0
votes

I am modeling a simple differential drive robot (such as the e-Puck, Khepera, etc.) with pyBox2D. This class of robots is usually controlled by indicating speeds for the right and left wheel in rad/sec.
However, Box2D can only control a (kinematic) body through two parameters: linear velocity (in meters/sec, as a 2D vector) and angular velocity (in rad/sec). I need to convert my wheel speeds to linear + angular velocities.

Linear velocity is actually straightforward. Given a wheel radius r in meters, and current robot orientation theta in radians, the forward speed is simply the average of the two wheel speeds in meters/sec and reduced to a vector according to current orientation:

(1) forwardSpeed = ((rightSpeed * r) + (leftSpeed * r)) / 2

(2) linearVelocity = (forwardSpeed * cos(theta), forwardSpeed * sin(theta))

I cannot quite figure out the correct formula for angular velocity, though. Intuitively, it should be the difference between the two speeds modulo the distance between the wheels:

(3) angularVelocity = (rightSpeed - leftSpeed) / wheelSeparation

in the limit cases: when right = left, the robot spins in place, and when either rightSpeed = 0 or leftSpeed = 0, the robot spins (pivots) around the stationary wheel, i.e. in a circle with radius = to the separation between the wheels.

I do not get the expected behavior with formula (3), though. As a test, I set the left wheel speed to 0 and progressively increased the value of the right wheel 's speed. The expected behavior is that the robot's should spin around the left wheel with increased velocity. Instead, the robot spins in circles of increasing radius, i.e it spirals outward, which suggests that the angular velocity is insufficient.

Notice that I am using a Box2D kinematic body for the robot, so friction does not play a role in my results.

1

1 Answers

0
votes

Keep in mind that angular velocities in Box2D work around the origin (0,0) in local body coordinates, which makes it very awkward to accurately reproduce this type of movement. Presumably the origin of the robot is in the center of the body, in which case you can never get it to rotate around one wheel (that would need both a rotate and translate). It might actually be easier to model the robot as a dynamic body and apply forces where the wheels are. If you don't want to deal with friction losses etc, you could use a kinematic body for each wheel and connect them to the main (dynamic) body with revolute joints.