Одним из способов решения этой проблемы является реализация конечного автомата .То есть вместо того, чтобы определять проблему с помощью команд, таких как move_left()
и move_right()
, вместо этого вы можете иметь некоторые переменные, которые представляют конечную позицию, в которой вы хотите, чтобы каждая рука заканчивалась, и второй набор переменных, которые представляют текущуюположение руки.Затем на каждом временном шаге вы просто слегка перемещаете руки в направлении их цели-цели.
Вот очень простая игрушка, демонстрирующая эту идею.Обратите внимание, что он перемещает каждую «руку» не более чем на 0,1 единицы каждые 100 мс (с шагом времени (вы, конечно, можете использовать любые значения временного шага и максимального движения):
import time
class Robot:
def __init__(self):
self._leftArmCurrentPos = 0.0
self._leftArmTargetPos = 0.0
self._rightArmCurrentPos = 0.0
self._rightArmTargetPos = 0.0
def setLeftArmTargetPos(self, newPos):
self._leftArmTargetPos = newPos
def setRightArmTargetPos(self, newPos):
self._rightArmTargetPos = newPos
# Returns the closest value to (deltaVal) in the range [-0.1, +0.1]
def clamp(self, deltaVal):
aLittleBit = 0.1 # or however much you want
if (deltaVal > aLittleBit):
return aLittleBit
elif (deltaVal < -aLittleBit):
return -aLittleBit
else:
return deltaVal
def moveArmsTowardsTargetPositions(self):
leftArmDelta = self.clamp(self._leftArmTargetPos - self._leftArmCurrentPos)
if (leftArmDelta != 0.0):
self._leftArmCurrentPos += leftArmDelta
print("Moved left arm by %f towards %f, new left arm pos is %f" % (leftArmDelta, self._leftArmTargetPos, self._leftArmCurrentPos))
rightArmDelta = self.clamp(self._rightArmTargetPos - self._rightArmCurrentPos)
if (rightArmDelta != 0.0):
self._rightArmCurrentPos += rightArmDelta
print("Moved right arm by %f towards %f, new right arm pos is %f" % (rightArmDelta, self._rightArmTargetPos, self._rightArmCurrentPos))
if __name__ == "__main__":
r = Robot()
r.setLeftArmTargetPos(10.0)
r.setRightArmTargetPos(-3.0)
while True:
r.moveArmsTowardsTargetPositions()
time.sleep(0.1)
ПриятноПобочным эффектом этого подхода является то, что если вы в любой момент передумаете о том, где вы хотите, чтобы руки были, вы можете просто позвонить setLeftArmTargetPos()
или setRightArmTargetPos()
, чтобы дать оружию новые / другие значения назначения, и они сразу женачать движение от (где бы они ни находились в настоящее время) к новым целевым позициям - нет необходимости ждать, пока они прибудут в старые пункты назначения первыми.