/* author: Louis Hugues - created on 27 janv. 2005 */
package simbad.sim;
import java.text.DecimalFormat;
import javax.media.j3d.Transform3D;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
/**
* This class models the differential drive kinematic common.
* The two control parameters are left and right velocity.
*/
public class DifferentialKinematic extends KinematicModel {
private Transform3D t3d;
private double leftWheelVelocity;
private double rightWheelVelocity;
private double wheelsDistance;
private Point3d tempPoint;
public DifferentialKinematic(double wheelsDistance){
this.wheelsDistance = wheelsDistance;
tempPoint = new Point3d();
t3d = new Transform3D();
reset();
}
/** Compute instant translation and rotation vectors .
*
* @param elapsedSecond time elapsed
* @param rotation current rotation
* @param instantTranslation to store translation
* @param instantRotation to store rotation
*/
protected void update(double elapsedSecond,Transform3D rotation,Vector3d instantTranslation,Vector3d instantRotation)
{
// perform translation - according to current position and orientation
//For details see :
//Computational Principles of Mobile Robotic - Dudek & Jenkins -
// Cambridge University Press - Differential drive chapter.
double epsilon = 0.001;
double vl = leftWheelVelocity;
double vr = rightWheelVelocity;
// distance between the two wheels.
double l = wheelsDistance;
double r, omega;
double dtheta;
// forward kinematic : find position knowing the velocity of the two
// wheels.
if (Math.abs(vl - vr) < epsilon) {
dtheta = 0;
instantTranslation.set(vl * elapsedSecond, 0, 0);
rotation.transform(instantTranslation);
} else {
// compute position (r,omega) of instantaneous center of curvature (ICC)
r = l * (vl + vr) / (2 * (vr - vl));
omega = (vr - vl) / l;
double omegadt = omega * elapsedSecond;
// move in XZ plane
// rotate position around the ICC of omega x dt radians
instantTranslation.set(0, 0, r);
t3d.setIdentity();
t3d.rotY(omegadt);
t3d.transform(instantTranslation);
// back to origin
tempPoint.set(0, 0, r);
instantTranslation.sub(tempPoint);
// take into account current robot orientation
rotation.transform(instantTranslation);
dtheta = omegadt;
}
// perform rotation -
instantRotation.set(0,dtheta,0);
}
/** Resets all control parameters to their initial values. */
protected void reset() {
leftWheelVelocity = 0;
rightWheelVelocity = 0;
}
/** Resets all control parameters to their initial values. */
protected String toString(DecimalFormat format) {
return "kinematic \t= DifferentialKinematic\n" + "left velocity \t= "
+ format.format(leftWheelVelocity) + " m/s\n"
+ "right velocity \t= " + format.format(rightWheelVelocity)
+ " m/s\n";
}
/** Sets the velocity of the left wheel in meter/s. */
public void setLeftVelocity(double vel) {
leftWheelVelocity = vel;
}
/** Sets the velocity of the right wheel in meter/s. */
public void setRightVelocity(double vel) {
rightWheelVelocity = vel;
}
/** Sets the velocity of both wheels in meter/s. */
public void setWheelsVelocity(double vl, double vr) {
leftWheelVelocity = vl;
rightWheelVelocity = vr;
}
/** Gets the velocity of the left wheel in meter/s. */
public double getLeftVelocity() {
return leftWheelVelocity;
}
/** Gets the velocity of the right wheel in meter/s. */
public double getRightVelocity() {
return rightWheelVelocity;
}
}