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

Drive Base with gyro is slow to recover perturbed heading angle when driving at high speed #1032

Closed
laurensvalk opened this issue Apr 15, 2023 · 7 comments
Labels
bug Something isn't working topic: control Issues involving control system algorithms topic: imu Issues related to IMU/gyro/accelerometer topic: motors Issues involving motors

Comments

@laurensvalk
Copy link
Member

I tried [use the] straight() command and it works but whenever I change the straight speed in drivebase.settings, instead of instantly adjusting itself, it does a big curve just to get to the initial angle.

Originally posted by @Xylar52 in #989 (comment)

@laurensvalk
Copy link
Member Author

Can you share a code sample and a video that reproduces that behavior? You can just attach the video here.

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

hub = PrimeHub()
motorl = Motor(Port.A, Direction.COUNTERCLOCKWISE)
motorr = Motor(Port.B)
motorl.control.limits(acceleration=[2000, 400])
motorr.control.limits(acceleration=[2000, 400])
drive_base = DriveBase(
    left_motor=motorl, 
    right_motor=motorr, 
    wheel_diameter=55, 
    axle_track=143,
    positive_direction=Direction.COUNTERCLOCKWISE,
    use_gyro=True)

drive_base.settings(
    straight_speed=500,
    straight_acceleration=1000,
    turn_acceleration=2000,
    turn_rate=500
    )

while True:
    drive_base.straight(1000, then=Stop.NONE)

This code concludes in this :

20230405_133825.mp4

However, if you delete the straight speed in settings :

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

hub = PrimeHub()
motorl = Motor(Port.A, Direction.COUNTERCLOCKWISE)
motorr = Motor(Port.B)
motorl.control.limits(acceleration=[2000, 400])
motorr.control.limits(acceleration=[2000, 400])
drive_base = DriveBase(
    left_motor=motorl, 
    right_motor=motorr, 
    wheel_diameter=55, 
    axle_track=143,
    positive_direction=Direction.COUNTERCLOCKWISE,
    use_gyro=True)

drive_base.settings(
    straight_acceleration=1000,
    turn_acceleration=2000,
    turn_rate=500
    )

while True:
    drive_base.straight(1000, then=Stop.NONE)`

It concludes in the normal behaviour :

20230405_133902.mp4

Originally posted by @Xylar52 in #989 (comment)

@laurensvalk laurensvalk added bug Something isn't working topic: motors Issues involving motors topic: control Issues involving control system algorithms topic: imu Issues related to IMU/gyro/accelerometer labels Apr 15, 2023
@laurensvalk
Copy link
Member Author

Hypothesis: with the gyro as the heading input, it is much easier to perturb the heading controller by a large amount. By contrast, when the motor angles are used for heading, the motors would stall long before you could spin the drivebase by a huge amount.

So, something is probably oversaturated in one of the control variables. I'd need to do some datalogging to see what it is.

Workaround for now
Don't push the robot around too much, or use a lower speed.

@laurensvalk
Copy link
Member Author

Reproduce on the large drive base

from pybricks.pupdevices import Motor
from pybricks.parameters import Port, Direction, Stop
from pybricks.robotics import DriveBase
from pybricks.tools import wait

left_motor = Motor(Port.A, Direction.COUNTERCLOCKWISE)
right_motor = Motor(Port.B)

drive_base = DriveBase(
    left_motor,
    right_motor,
    wheel_diameter=88,
    axle_track=18*8+1,
    positive_direction=Direction.COUNTERCLOCKWISE,
    use_gyro=True)

drive_base.settings(
    straight_speed=800,  # This is very fast, 0.8 m/s
    straight_acceleration=1152,
    turn_rate=202,
    turn_acceleration=910
)

# Drive forward for 300 mm.
drive_base.straight(30000)

@laurensvalk
Copy link
Member Author

This piece of code is not working as intended:

https://github.com/pybricks/pybricks-micropython/blob/2beddbcd724714944e9fd36db3f99fb9d7a9e77f/lib/pbio/src/drivebase.c#L433-L444

One controller can pause another as intended, but it unpauses itself immediately in the next iteration.

laurensvalk added a commit to pybricks/pybricks-micropython that referenced this issue Apr 20, 2023
Now, the paused controller cannot unpause itself until all controllers are unpaused.

This is simpler, and also generalizes to N motors when we go beyond drivebases.

Partially fixes pybricks/support#1032
laurensvalk added a commit to pybricks/pybricks-micropython that referenced this issue Apr 20, 2023
@laurensvalk
Copy link
Member Author

This was happening partially due to a bug in the way the heading and distance controllers were synchronized.

That is now fixed, but that doesn't fix OP's issue completely. This remaining issue still stands:


When driving at high speed, the motors are almost saturated with just the feed forward component.

Large perturbations are now fixed, so the robot turns back quickly if you spin it far. But small errors are not corrected very well at high speeds.

@laurensvalk
Copy link
Member Author

I should add that this is the expected result technically, but it is probably more intuitive to slow the robot down explicitly in this scenario using some sort of supervisory controller.

@laurensvalk
Copy link
Member Author

laurensvalk commented Apr 20, 2023

The simpler solution is probably to reduce the maximum settable speed to something that still allows the robot to over-correct as needed.

In fact, we could just add this to the docs. With the default settings, this issue does not occur.

laurensvalk added a commit to pybricks/pybricks-micropython that referenced this issue Apr 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working topic: control Issues involving control system algorithms topic: imu Issues related to IMU/gyro/accelerometer topic: motors Issues involving motors
Projects
None yet
Development

No branches or pull requests

1 participant