Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] DriveBase.distance() changes after resetting wheel motors' angles #1449

Open
donmerendolo opened this issue Feb 16, 2024 · 6 comments
Open
Labels
documentation Improvements or additions to documentation software: pybricks-micropython Issues with Pybricks MicroPython firmware (or EV3 runtime) topic: motors Issues involving motors

Comments

@donmerendolo
Copy link

Describe the bug
What is the problem?
Hi, I am coaching an FLL team and was testing the robot today using relative distances (passing target_distance - robot.distance() to DriveBase.straight()). I noticed that the robot sometimes moved a lot and other times it moved very little. Later today I was able to isolate the issue and found out that resetting the wheel motors' angles changed the measured distance value. I don't know if it's relevant but we use the SPIKE Prime.

To reproduce
I made this program that shows that DriveBase distance changes without moving the motors:

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import Motor
from pybricks.parameters import Button, Color, Direction, Port, Side, Stop, Axis, Icon
from pybricks.robotics import DriveBase
from pybricks.tools import wait, StopWatch, Matrix

hub = PrimeHub()

left_wheel = Motor(Port.B, Direction.COUNTERCLOCKWISE)
right_wheel = Motor(Port.A, Direction.CLOCKWISE)

robot = DriveBase(left_wheel, right_wheel, 62.4, 110)

print("Before reset:")
print("robot distance:", robot.distance())
print("left_wheel angle:", left_wheel.angle())
print("right_wheel angle:", right_wheel.angle())
print()

left_wheel.reset_angle(0)
print("After left_wheel reset:")
print("robot distance:", robot.distance())
print("left_wheel angle:", left_wheel.angle())
print("right_wheel angle:", right_wheel.angle())
print()

right_wheel.reset_angle(0)
print("After right_wheel reset:")
print("robot distance:", robot.distance())
print("left_wheel angle:", left_wheel.angle())
print("right_wheel angle:", right_wheel.angle())
print()

Which outputs this:

Before reset:
robot distance: 0
left_wheel angle: 97
right_wheel angle: 158

After left_wheel reset:
robot distance: -27
left_wheel angle: 0
right_wheel angle: 158

After right_wheel reset:
robot distance: -70
left_wheel angle: 0
right_wheel angle: 0

As you can see, the robot's measured distance is changed without even moving the motors.

Expected behavior
I think the measured distance should stay the same after resetting the drivebase's motors.

Resetting distance after resetting the motors solves this issue but I spent some time figuring this out.

@donmerendolo donmerendolo added the triage Issues that have not been triaged yet label Feb 16, 2024
@laurensvalk
Copy link
Member

Thank you! I can see that this could be confusing.

Another way to resolve this would be to reset the motors before creating the drive base:

left_wheel = Motor(Port.B, Direction.COUNTERCLOCKWISE)
left_wheel.reset_angle(0)
right_wheel = Motor(Port.A, Direction.CLOCKWISE)
right_wheel.reset_angle(0)

robot = DriveBase(left_wheel, right_wheel, 62.4, 110)

Resetting distance after resetting the motors solves this issue but I spent some time figuring this out.

Maybe we should do this automatically, and add a note about it in the docs.

Related to this, maybe we should also reset the angle when switching to/from using the gyro.

@laurensvalk laurensvalk added software: pybricks-micropython Issues with Pybricks MicroPython firmware (or EV3 runtime) bug Something isn't working topic: motors Issues involving motors and removed triage Issues that have not been triaged yet labels Feb 17, 2024
@donmerendolo
Copy link
Author

Thanks ☺️

Another way to resolve this would be to reset the motors before creating the drive base:

left_wheel = Motor(Port.B, Direction.COUNTERCLOCKWISE)
left_wheel.reset_angle(0)
right_wheel = Motor(Port.A, Direction.CLOCKWISE)
right_wheel.reset_angle(0)

robot = DriveBase(left_wheel, right_wheel, 62.4, 110)

Even then, if the robot references itself with a wall (for example), resets distance, then resets motors, the measured distance will change too, right? This year, in my team's robot we sometimes want to turn with a single wheel, so we reset motors in the wall too (although I don't think it makes much sense to use relative angle here instead of gyro or absolute angle).

@laurensvalk
Copy link
Member

Thank you. I think we haven't given the individual motor resets combined with drive base resets enough thought.

I agree that some changes would be helpful, and we can certainly do so. We just have to figure out what's "right", and then find a way to implement it as well.

Possible approach: (feel free to suggest others!)

  • when reset_angle is used on a single motor, change the firmware so that drive_base.distance() and angle() are not affected.
  • drivebase.reset() does not affect the individual motor, since it isn't clear what they should be reset to.

Would this solve your use case?

@donmerendolo
Copy link
Author

That approach is exactly what I had in mind!! 😄

For solving our use case we have made a function similar to this to make sure we always reset distance after motors:

def reset_motors():
    left_wheel.reset_angle(0)
    right_wheel.reset_angle(0)
    drivebase.reset()

@laurensvalk
Copy link
Member

We have recently added the ability to pass a desired distance and angle to DriveBase.reset(distance, angle) which should give some more flexibility to solve this issue.

After giving this more thought in the context of the original question here, I'm not sure that changing the existing behavior would be the best solution. The sources for the drivebase distance are the motor angles. So if you change the motor angles, this will change the distance too. This also applies when moving a single motor.

Would it be OK if we added a note to the reset_angle documentation to say that this also affects the distance value?

@donmerendolo
Copy link
Author

Yeah, that sounds like the best solution 👍.

@laurensvalk laurensvalk added documentation Improvements or additions to documentation and removed bug Something isn't working labels Oct 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation software: pybricks-micropython Issues with Pybricks MicroPython firmware (or EV3 runtime) topic: motors Issues involving motors
Projects
None yet
Development

No branches or pull requests

2 participants