Robot stops even though motor.hold() is not in the code. #1756
-
I wrote the following code, but even though I didn't write motor.hold(), the robot stops between await tank.drive_deg(70, -18, 460, False) and await tank.drive_deg(70, 15, 450). class Tank:
def __init__(self, left_port: Port, right_port: Port, wheel_diameter: float, axle_track: float) -> None:
self.left_motor = Motor(left_port, Direction.COUNTERCLOCKWISE)
self.right_motor = Motor(right_port)
self.wheel_diameter = wheel_diameter
self.axle_track = axle_track
def reset(self) -> None:
"""Resets the estimated driven distance to 0."""
self.left_motor.reset_angle(0)
self.right_motor.reset_angle(0)
def deg(self) -> float:
"""Gets the estimated driven distance."""
return (self.left_motor.angle() + self.right_motor.angle()) / 2
def _stov(self, speed: float) -> float:
return speed / 100 * 1110
def _ctod(self, cm: float) -> float:
return cm / (self.wheel_diameter * umath.pi / 10) * 360
def drive(self, speed: float, steering : float) -> None:
if steering > 0:
self.tank(speed, speed * (1 - abs(steering) / 50))
else:
self.tank(speed * (1 - abs(steering) / 50), speed)
def tank(self, left_speed: float, right_speed: float) -> None:
if (abs(left_speed) > 100) or (abs(right_speed) > 100):
raise ValueError("-100 <= speed <= 100")
self.left_motor.run(self._stov(left_speed))
self.right_motor.run(self._stov(right_speed))
def tank_dc(self, left_power: float, right_power: float) -> None:
self.left_motor.dc(left_power)
self.right_motor.dc(right_power)
async def drive_deg(self, speed: float, steering: float, deg: float, stop: bool = True) -> None:
self.reset()
if steering >= 0:
while abs(self.left_motor.angle()) <= abs(deg):
self.drive(speed, steering)
else:
while abs(self.right_motor.angle()) <= abs(deg):
self.drive(speed, steering)
if stop:
self.hold()
async def drive_cm(self, speed: float, steering: float, cm: float, stop: bool = True) -> None:
await self.drive_deg(speed, steering, self._ctod(cm), stop)
async def shift_drive(self, speed_before: float, speed_after: float, steering: float, shift_time: float) -> None:
if (abs(speed_before) > 100) or (abs(speed_after) > 100):
raise ValueError("-100 <= speed <= 100")
timer.reset()
while timer.time() <= shift_time:
self.drive(speed_before + timer.time() * (speed_after - speed_before) / shift_time, steering)
async def tank_deg(self, left_speed: float, right_speed: float, deg: float, stop: bool = True) -> None:
self.reset()
if left_speed >= right_speed:
while abs(self.left_motor.angle()) <= abs(deg):
self.tank(left_speed, right_speed)
else:
while abs(self.right_motor.angle()) <= abs(deg):
self.tank(left_speed, right_speed)
if stop:
self.hold()
async def tank_cm(self, left_speed: float, right_speed: float, cm: float, stop: bool = True) -> None:
await self.tank_deg(left_speed, right_speed, self._ctod(cm), stop)
def hold(self) -> None:
"""Stops the robot and actively holds it at its current angle."""
self.left_motor.hold()
self.right_motor.hold()
def speed(self) -> float:
"""Gets the speed (deg/s) of the robot."""
return (- self.left_motor.speed() + self.right_motor.speed()) / 2
tank = Tank(Port.D, Port.B, 62.4, 22 * 8)
async def main():
await tank.drive_deg(70, -18, 460, False)
await tank.drive_deg(70, 15, 450)
run_task(main()) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
At a glance, it looks like you have several while loops without any awaitable statements in them. Any loop that may take some time to complete (such as waiting on some condition to occur) needs at least one awaitable statement in it, which gives other parallel tasks a chance to run. For example, you could add: await wait(1) But since you aren't using multitasking yet, this is not the issue here. Are you intentionally resetting the motor angle on every move while it is still running? This causes the motor to stop as it needs the position sensors to know how fast it is going. Instead of resetting and then running to a given distance, you could instead measure the starting angle, and then let them run until (start value + distance). Then you shouldn't need any resets at all, and everthing should keep moving. |
Beta Was this translation helpful? Give feedback.
At a glance, it looks like you have several while loops without any awaitable statements in them.
Any loop that may take some time to complete (such as waiting on some condition to occur) needs at least one awaitable statement in it, which gives other parallel tasks a chance to run.
For example, you could add:
await wait(1)
But since you aren't using multitasking yet, this is not the issue here.
Are you intentionally resetting the motor angle on every move while it is still running? This causes the motor to stop as it needs the position sensors to know how fast it is going.
Instead of resetting and then running to a given distance, you could instead measure the starting angle, and then le…