根据记录的最高速度控制伺服的速度

问题描述 投票:0回答:0

我已将以下 Python 脚本作为要点上传到 GitHub 上。以下所有代码均来自此脚本。它连接到运行 StandardFirmata 的微控制器,并提供用于寻址伺服的 GUI。

https://gist.github.com/Lokno/649359ac881c130844de8e5e3705470d

脚本允许您参数化在给定持续时间内从一个位置到另一个位置的扫描。您还可以看到应用于扫描开始和结束的三次缓动的持续时间。

一切似乎都很好,但我认为我的数学仍然不准确。特别是,我不确定如何从数据表中包含已知的伺服速度。

代码首先确定伺服头在其速度根据扫描的分段函数变化时在给定时间内可以移动的最大位移或距离。这是扫描函数的积分:

def estimate_servo_displacement(self, total_duration, ease_in_duration, ease_out_duration):
    n = 10000 # fixed number of integration steps
    dt = total_duration / n
    displacement = 0

    for i in range(0,n):
        t = i*dt
        if t < ease_in_duration:
            speed = self.cubic_ease_out(t, 0, 1, ease_in_duration)
        elif t < (total_duration-ease_out_duration):
            speed = 1;
        else:
            speed = self.cubic_ease_in(t - total_duration + ease_out_duration, 1, -1, ease_out_duration)

        displacement += speed * dt

    return displacement

要获得以度为单位的实际行进距离,我们需要知道伺服的速度。大多数数据表似乎将速度定义为完成某个角度的速度。例如,假设舵机需要 0.15 秒才能移动 60 度。将其转换为每度毫秒数,我们得到:

top_speed = 0.15*1000/60 = 2.5 ms/degree

实际进行扫频的时候,我先按照上面的方法计算当前时间t的速度,这里称为经过时间。

def calculate_speed_at_time(self, elapsed_time, total_duration, ease_in_duration, ease_out_duration):
    speed = 0.0

    # Calculate speed at current time using cubic easing
    if elapsed_time < ease_in_duration:
        speed = self.cubic_ease_out(elapsed_time, 0, 1, ease_in_duration)
    elif elapsed_time < (total_duration-ease_out_duration):
        speed = 1
    else:
        speed = self.cubic_ease_in(elapsed_time - total_duration + ease_out_duration, 1, -1, ease_out_duration)

    return speed

实际的扫描迭代是在这个方法中用辅助方法constrain()计算的:

def constrain(self,x,xmin,xmax):
    return xmin if x < xmin else xmax if x > xmax else x

def iterate_sweep(self,elapsed_time,delta_time):
    direction = 1 if self.end > self.position else -1
    
    speed = self.calculate_speed_at_time(elapsed_time, self.duration, self.ease_in, self.ease_out)
    speed_factor = abs(self.end-self.start)/self.displacement

    self.position += direction*speed*speed_factor*delta_time
    self.position = self.constrain(self.position, 0, self.max_angle)

最初我试图在这段代码中包含 top_speed 常量,但最好的猜测是如何添加它会自行取消:

float speed_factor = abs(self.end-self.start)/(self.displacement/top_speed);
self.position += direction*(speed/top_speed)*speed_factor*delta_time;

将位移除以 top_speed 得出以度为单位的行进距离。这是因为 1/(ms/degrees) 是度每毫秒。将其除以绝对行进距离应得出伺服的整体比例因子,以便它只行进到我们想要的距离。

但类似地,在计算时间 t 的速度时,我正在做相同的计算,因此我假设结果也应该除以 top_speed in other 以获得最终方程的正确值。

但是现在这个词取消了自己,我不明白那怎么可能是正确的。感觉我的等式一开始可能是错误的,但我不确定是怎么回事。

提前感谢您的帮助。

注意:当需要速度控制时,步进电机是更好的选择。这段代码最初是为伺服系统设计的,但我也很乐意将它改编为步进电机。

python-3.x simulation microcontroller physics servo
© www.soinside.com 2019 - 2024. All rights reserved.