EVNDrivebase#
Building upon the functionality provided by EVNMotor, EVNDrivebase provides functions useful for controlling differential drive robots.
Note
EVNDrivebase consumes some of the RP2040’s spinlock peripherals. See this page for more info.
Note
EVNDrivebase uses the 2nd core to perform internal updates at a high rate. Between updates, user code can run on the 2nd core, but this configuration may cause timing-sensitive code to fail or lead to unexpected behaviour.
Constructor#
- EVNDrivebase(float wheel_dia, float axle_track, EVNMotor* motor_left, EVNMotor* motor_right);
- Parameters
wheel_dia – Diameter of each wheel (in mm)
axle_track – Distance between midpoint of both wheels (in mm)
motor_left – Pointer to
EVNMotorobject for left motormotor_right – Pointer to
EVNMotorobject for right motor
EVNMotor left_motor(1, EV3_MED); EVNMotor right_motor(2, EV3_MED, REVERSE); //wheel diameter - 62.4mm, axle track - 178mm EVNDrivebase db(62.4, 178, &left_motor, &right_motor);
Note
For those new to C++, pointers can be quite confusing! Think of & as a means for you to provide a link to an object.
Here, we pass a link to EVNMotor objects to our EVNDrivebase object, so that it can control the EVNMotor objects for us.
Functions#
- void begin();
Initializes drivebase object. Call this function after calling
begin()on the EVNMotor objects (which still need to be called!), but before calling any otherEVNDrivebasefunctions (including settings functions).EVNMotor left_motor(1, EV3_MED); EVNMotor right_motor(2, EV3_MED, REVERSE); EVNDrivebase db(62.4, 178, &left_motor, &right_motor); void setup1() { left_motor.begin(); right_motor.begin(); db.begin(); }
Note
EVNDrivebase should be initialized on the 2nd core by calling begin() in void setup1().
However, you can still call the other functions on both cores.
We recommend setting drivebase parameters on the 2nd core, while leaving movement to the main core.
Measurements#
- float getDistance()
- Returns
Distance travelled by drivebase (in mm)
float distance = db.getDistance();
- float getAngle()
- Returns
Angle turned by drivebase (in deg)
float angle = db.getAngle();
- float getHeading()
- Returns
Drivebase heading (ranging from 0-360 degrees)
float heading = db.getHeading();
- float getX()
- Returns
X coordinate of drivebase from origin (origin is the drivebase’s position on startup)
float x = db.getX();
- float getY()
- Returns
Y coordinate of drivebase from origin (origin is the drivebase’s position on startup)
float y = db.getY();
- void resetXY();
Sets drivebase’s current position to be the origin (0, 0).
db.resetXY(); //afterwards, getX() and getY() will return 0
- float getDistanceToPoint(float x, float y);
- Returns
Euclidean distance between drivebase’s XY position and target XY point
//if drivebase is at origin, the distance to point will be 4 float distance_to_point = db.getDistanceToPoint(3,2);
- float getMaxSpeed()
- Returns
Maximum speed of drivebase (in mm/s)
- float getMaxTurnRate()
- Returns
Maximum turning rate of drivebase (in deg/s)
Move Forever#
- void drive(float speed, float turn_rate, bool disable_accel_decel = false);
- void driveTurnRate(float speed, float turn_rate, bool disable_accel_decel = false);
Runs drivebase at the given speed and turn rate until a new command is called
- Parameters
speed – Velocity of drivebase (in mm/s)
turn_rate – Turning rate of drivebase (in deg/s)
disable_accel_decel – Disables acceleration and deceleration control. Defaults to false
//drive at a velocity of 50mm/s and turning rate of 5deg/s db.drive(50, 5);
- void driveRadius(float speed, float radius, bool disable_accel_decel = false);
Runs drivebase at the given speed and radius of turning until a new command is called
- Parameters
speed – Velocity of drivebase (in mm/s)
radius – Turning radius of drivebase (in mm)
disable_accel_decel – Disables acceleration and deceleration control. Defaults to false
//drive at a velocity of 50mm/s and move in an arc of radius 50mm db.driveRadius(50, 50);
- void drivePct(float speed_outer_pct, float turn_rate_pct, bool disable_accel_decel = true)
This function simulates a differential drive function where the outer wheel speed is given as a percentage, along with a “turning rate” percentage input to define the turning behaviour as described below:
0% “turning rate”: Both wheels run at speed_outer_pct, same direction 50% “turning rate”: One wheel stationary, other wheel runs at speed_outer_pct (one-wheel turn) 100% “turning rate”: Both wheels run at speed_outer_pct, but in opposite directions
Positive turning rate values turn anti-clockwise, negative values turn clockwise.
Since the inputs range from -100 to 100 (unlike driveRadius, where radius ranges to infinity), it can be easier to use this function for PID control.
- Parameters
speed_outer_pct – Speed for outer (faster) wheel in % (number from -100 to 100)
turn_rate_pct – Turning rate of drivebase in % (number from -100 to 100)
disable_accel_decel – Disables acceleration and deceleration control. Defaults to true
//drive forwards at 100% speed db.drivePct(100, 0); //drive forwards at 50% speed db.drivePct(50, 0); //drive backwards at 100% speed db.drivePct(-100, 0); //one-wheel clockwise turn at full speed db.drivePct(100, 50); //rotate clockwise on the spot at full speed db.drivePct(100, 100);
Move by a Fixed Amount#
- void straight(float speed, float distance, uint8_t stop_action = STOP_BRAKE, bool wait = true);
Runs drivebase in a straight line for the specified distance, then performs given stop action.
Drivebase speed direction is reversed when the
speedordistanceinputs are negative (e.g.straight(100, -100),straight(-100, 100), orstraight(-100, -100)will all move the drivebase backwards).- Parameters
speed – Velocity of drivebase (in mm/s)
distance – Distance to travel (in mm)
stop_action –
Behaviour of the motor upon completing its command. Defaults to
STOP_BRAKESTOP_BRAKE– Brake (Slow decay)STOP_COAST– Coast (Fast decay)STOP_HOLD– Hold positionSTOP_NONE– Continue running at current speed (and deceleration to a stop removed)
wait – Block function from returning until command is finished
//move in a straight line at a velocity of 50mm/s for a distance of 50mm db.straight(50, 50);
- void curve(float speed, float radius, float angle, uint8_t stop_action = STOP_BRAKE, bool wait = true);
- void curveRadius(float speed, float radius, float angle, uint8_t stop_action = STOP_BRAKE, bool wait = true);
Runs drivebase in a curve of specified radius until its heading has shifted by the given angle, then performs given stop action.
Drivebase turning direction is reversed when the
radiusorangleinputs are negative (e.g.curve(100, 100, -100),curve(100, -100, 100), orcurve(100, -100, -100)will all use a negative (clockwise) turning rate).- Parameters
speed – Velocity of drivebase (in mm/s)
radius – Turning radius of drivebase (in mm)
angle – Angle to travel by (in deg)
stop_action –
Behaviour of the motor upon completing its command. Defaults to
STOP_BRAKESTOP_BRAKE– Brake (Slow decay)STOP_COAST– Coast (Fast decay)STOP_HOLD– Hold positionSTOP_NONE– Continue running at current speed (and deceleration to a stop removed)
wait – Block function from returning until command is finished
//drive at a velocity of 50mm/s in an arc of radius 50mm until the drivebase has rotated by 90 degrees db.curve(50, 50, 90, STOP_BRAKE);
- void curveTurnRate(float speed, float turn_rate, float angle, uint8_t stop_action = STOP_BRAKE, bool wait = true);
Runs drivebase at given speed and turn rate until its heading has shifted by the given angle, then runs specified stop action
Drivebase turning direction is reversed when the
turn_rateorangleinputs are negative (e.g.curveTurnRate(100, 100, -100),curveTurnRate(100, -100, 100), orcurveTurnRate(100, -100, -100)will all use a negative (clockwise) turning rate).- Parameters
speed – Velocity of drivebase (in mm/s)
turn_rate – Turning rate of drivebase (in deg/s)
angle – Angle to travel by (in deg)
stop_action –
Behaviour of the motor upon completing its command. Defaults to
STOP_BRAKESTOP_BRAKE– Brake (Slow decay)STOP_COAST– Coast (Fast decay)STOP_HOLD– Hold positionSTOP_NONE– Continue running at current speed (and deceleration to a stop removed)
wait – Block function from returning until command is finished
//drive at a velocity of 50mm/s at a turning rate of 5deg/s until the drivebase has rotated by 90 degrees db.curveTurnRate(50, 5, 90, STOP_BRAKE);
- void turn(float turn_rate, float degrees, uint8_t stop_action = STOP_BRAKE, bool wait = true);
- void turnDegrees(float turn_rate, float degrees, uint8_t stop_action = STOP_BRAKE, bool wait = true);
Rotate drivebase on the spot by the given angle, then performs given stop action
- Parameters
turn_rate – Turning rate of drivebase (in deg/s)
angle – Angle to travel by (in deg)
stop_action –
Behaviour of the motor upon completing its command. Defaults to
STOP_BRAKESTOP_BRAKE– Brake (Slow decay)STOP_COAST– Coast (Fast decay)STOP_HOLD– Hold positionSTOP_NONE– Continue running at current speed (and deceleration to a stop removed)
wait – Block function from returning until command is finished
//rotate at a rate of 5deg/s until the drivebase has rotated by 90 degrees db.turn(5, 90, STOP_BRAKE);
- void turnHeading(float turn_rate, float heading, uint8_t stop_action = STOP_BRAKE, bool wait = true);
Rotate drivebase on the spot to the given heading, then performs given stop action
- Parameters
turn_rate – Turning rate of drivebase (in deg/s)
heading – Heading to travel to (in deg)
stop_action –
Behaviour of the motor upon completing its command. Defaults to
STOP_BRAKESTOP_BRAKE– Brake (Slow decay)STOP_COAST– Coast (Fast decay)STOP_HOLD– Hold positionSTOP_NONE– Continue running at current speed (and deceleration to a stop removed)
wait – Block function from returning until command is finished
//rotate at a rate of 5deg/s (or -5deg/s) until the drivebase has a heading of 90degrees db.turnHeading(5, 90, STOP_BRAKE);
- bool completed();
- Returns
Boolean indicating whether the drivebase’s command has reached completion
//wait until drivebase has completed its command while (!db.completed());
Move to Point#
- void driveToXY(float speed, float turn_rate, float x, float y, uint8_t stop_action = STOP_BRAKE, bool restore_initial_heading = true);
Rotates drivebase to face target XY position, drives forward to target, and rotates back to original heading
- Parameters
speed – Velocity of drivebase (in mm/s)
turn_rate – Turning rate of drivebase (in deg/s)
x – X coordinate of target
y – Y coordinate of target
stop_action –
Behaviour of the motor upon completing its command. Defaults to
STOP_BRAKESTOP_BRAKE– Brake (Slow decay)STOP_COAST– Coast (Fast decay)STOP_HOLD– Hold positionSTOP_NONE– Continue running at current speed (and deceleration to a stop removed)
wait – Block function from returning until command is finished
//drive to point (60, 60) at a velocity of 100mm/s and turning rate of 50deg/s db.driveToXY(100, 50, 60, 60, STOP_BRAKE);
Note
This feature is experimental! And also, it’s pretty much a party trick. Its behaviour may be changed in future versions.
Stopping#
- void stop()
Brakes both drivebase motors (slow decay).
db.stop();
- void coast()
Coasts both drivebase motors to a stop (fast decay). Compared to braking with stop(), the drivebase comes to a stop more slowly.
db.coast();
- void hold()
Hold drivebase motors in their current positions. Restricts the motor shafts from moving.
db.hold();
Control Settings#
To view the default accel/decel values, look at src\evn_motor_defs.h in the Github repository.
The PD values for the speed and turn rate controllers are obtained from the motor objects linked to drivebase.
If both motors are the same motor type, then the EVNMotor PD value for that motor type will be used by default. Otherwise, the CUSTOM_MOTOR PD values are used.
- void setSpeedKp(float kp);
Sets proportional gain values for the speed controller (controls average drivebase speed).
The error for the controller is the difference between the robot’s target distance travelled and the robot’s current distance travelled (in motor degrees).
- Parameters
kp – Proportional gain
db.setSpeedKp(20);
- void setSpeedKd(float kd);
Sets derivative gain values for the speed controller (controls average drivebase speed).
The error for the controller is the difference between the robot’s target distance travelled and the robot’s current distance travelled (in motor degrees).
- Parameters
kd – Derivative gain
db.setSpeedKd(0.2);
- void setTurnRateKp(float kp);
Sets proportional gain values for the turn rate controller (controls rate of turning of drivebase).
The error for the controller is the difference between the robot’s target angle and the robot’s current angle (in motor degrees).
This controller serves 2 purposes: to ensure the drivebase turns at the correct rate, and to stop either motor if the other is stalled, syncing their movement.
- Parameters
kp – Proportional gain
db.setTurnRateKp(20);
- void setTurnRateKd(float kd);
Sets derivative gain values for the turn rate controller (controls rate of turning of drivebase).
The error for the controller is the difference between the robot’s target angle and the robot’s current angle (in motor degrees).
This controller serves 2 purposes: to ensure the drivebase turns at the correct rate, and to stop either motor if the other is stalled, syncing their movement.
- Parameters
kd – Derivative gain
db.setTurnRateKd(0.2);
- void setSpeedAccel(float accel_mm_per_s_sq);
Sets speed acceleration value for drivebase (in mm/s^2).
- Parameters
accel_mm_per_s_sq – Acceleration in mm/s^2
db.setSpeedAccel(500);
- void setSpeedDecel(float decel_mm_per_s_sq);
Sets speed deceleration value for drivebase (in mm/s^2).
- Parameters
decel_mm_per_s_sq – Deceleration in mm/s^2
db.setSpeedDecel(500);
- void setTurnRateAccel(float accel_deg_per_s_sq);
Sets turn rate acceleration value for drivebase (in deg/s^2).
- Parameters
accel_deg_per_s_sq – Acceleration in deg/s^2
db.setTurnRateAccel(500);
- void setTurnRateDecel(float decel_deg_per_s_sq);
Sets turn rate deceleration value for drivebase (in deg/s^2).
- Parameters
decel_deg_per_s_sq – Deceleration in deg/s^2
db.setTurnRateDecel(500);
- void setDebug(uint8_t debug_type)
Used to toggle debug mode, where drivebase will print the error for either speed or turn rate PD control over
Serial. Can be used to observe or tune PD controller behaviour.- Parameters
debug_type –
Type of debug mode to run
DEBUG_OFFDEBUG_SPEEDDEBUG_TURN_RATE