如何设置 pymunk SimpleMotor 的旋转速率以达到特定角度?
How to set the rotation rate of a pymunk SimpleMotor to reach a specific angle?
我正在尝试创建一个函数(用于深度学习),在该函数中我可以通过发送具有角度差的特定列表来控制机器人的角度值,然后电机应该旋转直到达到该角度.当我使用键盘控件时,设置 SimpleMotor.rate 在 while 循环内工作,但当我试图在 while 循环外的函数中使用它时它不起作用。有人可以建议吗?这是代码:
def change_angle(angles):
chassis_angle = self.chassis_b.angle*180/np.pi
cur_angles = [self.leftLeg_1b_body.angle*180/np.pi- chassis_angle,self.leftLeg_1a_body.angle*180/np.pi-chassis_angle,self.rightLeg_1a_body.angle*180/np.pi-chassis_angle,self.rightLeg_1b_body.angle*180/np.pi-chassis_angle]
target_angles = [cur_angles[0]+angles[0],cur_angles[1]+angles[1],cur_angles[2]+angles[2],cur_angles[3]+angles[3]]
#time = angle/omega
if target_angles[0]-cur_angles[0]>0:
self.motor_ba1Left.rate = -2
print("1")
else:
self.motor_ba1Left.rate = 2
print("2")
if target_angles[1]-cur_angles[1]>0:
self.motor_ac1Left.rate = -2
print("3")
else:
self.motor_ac1Left.rate = 2
print("4")
if target_angles[2]-cur_angles[2]>0:
self.motor_ac1Right.rate = 2
print("5")
else:
self.motor_ac1Right.rate = -2
print("6")
if target_angles[3]-cur_angles[3]>0:
self.motor_ba1Right.rate = 2
print("7")
else:
self.motor_ba1Right.rate = -2
print("8")
while (target_angles[0]!=cur_angles[0]) or (target_angles[1]!=cur_angles[1]) or (target_angles[2]!=cur_angles[2]) or (target_angles[3]!=cur_angles[3]):
if target_angles[0]-cur_angles[0]==0:
self.motor_ba1Left.rate = 0
if target_angles[1]-cur_angles[1]==0:
self.motor_ac1Left.rate = 0
if target_angles[2]-cur_angles[2]==0:
self.motor_ac1Right.rate = 0
if target_angles[3]-cur_angles[3]==0:
self.motor_ba1Right.rate = 0
cur_angles = [self.leftLeg_1b_body.angle*180/np.pi- chassis_angle,self.leftLeg_1a_body.angle*180/np.pi-chassis_angle,self.rightLeg_1a_body.angle*180/np.pi-chassis_angle,self.rightLeg_1b_body.angle*180/np.pi-chassis_angle]
self.motor_ba1Left.rate = 0
self.motor_ac1Right.rate = 0
self.motor_ac1Left.rate = 0
self.motor_ba1Right.rate = 0
simulate = True
rotationRate = 1
while running:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key in (K_q, K_ESCAPE)):
sys.exit(0)
elif event.type == KEYDOWN and event.key == K_z:
# Start/stop simulation.
simulate = not simulate
elif event.type == KEYDOWN and event.key == K_r:
# Reset.
self.reset_bodies()
elif event.type == KEYDOWN and event.key == K_h:
self.chassis_b.angular_velocity = -2
elif event.type == KEYDOWN and event.key == K_u:
self.chassis_b.apply_force_at_local_point([0,-1500000])
elif event.type == KEYDOWN and event.key == K_j:
self.chassis_b.apply_force_at_local_point([0,1500000])
elif event.type == KEYDOWN and event.key == K_k:
self.chassis_b.angular_velocity = 2
elif event.type == KEYDOWN and event.key == K_w:
self.motor_ba1Left.rate = -rotationRate
elif event.type == KEYDOWN and event.key == K_s:
self.motor_ba1Left.rate = rotationRate
elif event.type == KEYDOWN and event.key == K_a:
self.motor_ac1Left.rate = -rotationRate
elif event.type == KEYDOWN and event.key == K_d:
self.motor_ac1Left.rate = rotationRate
elif event.type == KEYDOWN and event.key ==K_UP:
self.motor_ba1Right.rate = rotationRate
elif event.type == KEYDOWN and event.key ==K_DOWN:
self.motor_ba1Right.rate = -rotationRate
elif event.type == KEYDOWN and event.key ==K_LEFT:
self.motor_ac1Right.rate = -rotationRate
elif event.type == KEYDOWN and event.key ==K_RIGHT:
self.motor_ac1Right.rate = rotationRate
elif event.type == KEYUP:
print("keyup")
self.motor_ba1Left.rate = 0
self.motor_ac1Left.rate = 0
self.motor_ba1Right.rate = 0
self.motor_ac1Right.rate = 0
self.chassis_b.angular_velocity = 0
#self.chassis_b.velocity = 0d
self.draw()
change_angle([30,40,-30,-40])
### Update physics
fps = 50
iterations = 25
dt = 1.0/float(fps)/float(iterations)
if simulate:
for x in range(iterations): # 10 iterations to get a more stable simulation
self.space.step(dt)
#self.rotation()
self.check_collide()
#self.arm_collide_check()
#self.printinfo()
pygame.display.flip()
clock.tick(fps)
if __name__ == '__main__':
sim = Simulator()
sim.main()
我认为 change_angle 中的 while 循环没有按预期工作。
您从 while running:
循环中调用 change_angle 的每一帧。在该函数中,您首先使用 if 语句确定电机的速率。到目前为止,一切都很好。在此之后,速率将设置为某个值,但电机还没有旋转任何东西,因为这发生在步进函数中:self.space.step(dt)
这是实际向前移动模拟的部分,运行电机、应用重力、解决碰撞等
在这部分之后有一个 while 循环,我认为这个想法是为了弄清楚角度是否已更新为目标角度。然而,这永远不会发生,因为模拟只发生在我上面描述的阶跃函数中。
我认为你可以尝试删除那个 while 循环,而是在 change_angle 的开头放置一个大的 if 语句来检查是否达到目标角度,如果是则将电机的速率重置为 0 和return。 (否则继续现有的 if 语句)。
最后一个提示:角度是浮点数,例如42.234567.... 尝试比较这些数字是否完全相等几乎不是一个好主意,因为它们可能永远不会因为舍入误差而变得相等。相反,最好检查差异是否小于某个增量,例如target_angles[0]!=cur_angles[0]
变为 abs(target_angles[0]-cur_angles[0]) < delta
其中 delta 是一个小数字(例如 delta=0.01
)
我正在尝试创建一个函数(用于深度学习),在该函数中我可以通过发送具有角度差的特定列表来控制机器人的角度值,然后电机应该旋转直到达到该角度.当我使用键盘控件时,设置 SimpleMotor.rate 在 while 循环内工作,但当我试图在 while 循环外的函数中使用它时它不起作用。有人可以建议吗?这是代码:
def change_angle(angles):
chassis_angle = self.chassis_b.angle*180/np.pi
cur_angles = [self.leftLeg_1b_body.angle*180/np.pi- chassis_angle,self.leftLeg_1a_body.angle*180/np.pi-chassis_angle,self.rightLeg_1a_body.angle*180/np.pi-chassis_angle,self.rightLeg_1b_body.angle*180/np.pi-chassis_angle]
target_angles = [cur_angles[0]+angles[0],cur_angles[1]+angles[1],cur_angles[2]+angles[2],cur_angles[3]+angles[3]]
#time = angle/omega
if target_angles[0]-cur_angles[0]>0:
self.motor_ba1Left.rate = -2
print("1")
else:
self.motor_ba1Left.rate = 2
print("2")
if target_angles[1]-cur_angles[1]>0:
self.motor_ac1Left.rate = -2
print("3")
else:
self.motor_ac1Left.rate = 2
print("4")
if target_angles[2]-cur_angles[2]>0:
self.motor_ac1Right.rate = 2
print("5")
else:
self.motor_ac1Right.rate = -2
print("6")
if target_angles[3]-cur_angles[3]>0:
self.motor_ba1Right.rate = 2
print("7")
else:
self.motor_ba1Right.rate = -2
print("8")
while (target_angles[0]!=cur_angles[0]) or (target_angles[1]!=cur_angles[1]) or (target_angles[2]!=cur_angles[2]) or (target_angles[3]!=cur_angles[3]):
if target_angles[0]-cur_angles[0]==0:
self.motor_ba1Left.rate = 0
if target_angles[1]-cur_angles[1]==0:
self.motor_ac1Left.rate = 0
if target_angles[2]-cur_angles[2]==0:
self.motor_ac1Right.rate = 0
if target_angles[3]-cur_angles[3]==0:
self.motor_ba1Right.rate = 0
cur_angles = [self.leftLeg_1b_body.angle*180/np.pi- chassis_angle,self.leftLeg_1a_body.angle*180/np.pi-chassis_angle,self.rightLeg_1a_body.angle*180/np.pi-chassis_angle,self.rightLeg_1b_body.angle*180/np.pi-chassis_angle]
self.motor_ba1Left.rate = 0
self.motor_ac1Right.rate = 0
self.motor_ac1Left.rate = 0
self.motor_ba1Right.rate = 0
simulate = True
rotationRate = 1
while running:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key in (K_q, K_ESCAPE)):
sys.exit(0)
elif event.type == KEYDOWN and event.key == K_z:
# Start/stop simulation.
simulate = not simulate
elif event.type == KEYDOWN and event.key == K_r:
# Reset.
self.reset_bodies()
elif event.type == KEYDOWN and event.key == K_h:
self.chassis_b.angular_velocity = -2
elif event.type == KEYDOWN and event.key == K_u:
self.chassis_b.apply_force_at_local_point([0,-1500000])
elif event.type == KEYDOWN and event.key == K_j:
self.chassis_b.apply_force_at_local_point([0,1500000])
elif event.type == KEYDOWN and event.key == K_k:
self.chassis_b.angular_velocity = 2
elif event.type == KEYDOWN and event.key == K_w:
self.motor_ba1Left.rate = -rotationRate
elif event.type == KEYDOWN and event.key == K_s:
self.motor_ba1Left.rate = rotationRate
elif event.type == KEYDOWN and event.key == K_a:
self.motor_ac1Left.rate = -rotationRate
elif event.type == KEYDOWN and event.key == K_d:
self.motor_ac1Left.rate = rotationRate
elif event.type == KEYDOWN and event.key ==K_UP:
self.motor_ba1Right.rate = rotationRate
elif event.type == KEYDOWN and event.key ==K_DOWN:
self.motor_ba1Right.rate = -rotationRate
elif event.type == KEYDOWN and event.key ==K_LEFT:
self.motor_ac1Right.rate = -rotationRate
elif event.type == KEYDOWN and event.key ==K_RIGHT:
self.motor_ac1Right.rate = rotationRate
elif event.type == KEYUP:
print("keyup")
self.motor_ba1Left.rate = 0
self.motor_ac1Left.rate = 0
self.motor_ba1Right.rate = 0
self.motor_ac1Right.rate = 0
self.chassis_b.angular_velocity = 0
#self.chassis_b.velocity = 0d
self.draw()
change_angle([30,40,-30,-40])
### Update physics
fps = 50
iterations = 25
dt = 1.0/float(fps)/float(iterations)
if simulate:
for x in range(iterations): # 10 iterations to get a more stable simulation
self.space.step(dt)
#self.rotation()
self.check_collide()
#self.arm_collide_check()
#self.printinfo()
pygame.display.flip()
clock.tick(fps)
if __name__ == '__main__':
sim = Simulator()
sim.main()
我认为 change_angle 中的 while 循环没有按预期工作。
您从 while running:
循环中调用 change_angle 的每一帧。在该函数中,您首先使用 if 语句确定电机的速率。到目前为止,一切都很好。在此之后,速率将设置为某个值,但电机还没有旋转任何东西,因为这发生在步进函数中:self.space.step(dt)
这是实际向前移动模拟的部分,运行电机、应用重力、解决碰撞等
在这部分之后有一个 while 循环,我认为这个想法是为了弄清楚角度是否已更新为目标角度。然而,这永远不会发生,因为模拟只发生在我上面描述的阶跃函数中。
我认为你可以尝试删除那个 while 循环,而是在 change_angle 的开头放置一个大的 if 语句来检查是否达到目标角度,如果是则将电机的速率重置为 0 和return。 (否则继续现有的 if 语句)。
最后一个提示:角度是浮点数,例如42.234567.... 尝试比较这些数字是否完全相等几乎不是一个好主意,因为它们可能永远不会因为舍入误差而变得相等。相反,最好检查差异是否小于某个增量,例如target_angles[0]!=cur_angles[0]
变为 abs(target_angles[0]-cur_angles[0]) < delta
其中 delta 是一个小数字(例如 delta=0.01
)