Hi, I've done a sort of "quaternion spring" by using dQMultiple2().
It works great!
i.e., (assuming target_q contains the desired rotation)
memcpy(current_q, dBodyGetQuaternion(body), sizeof(dReal)*4);
dQMultiply2(q_delta, current_q, target_q);
// Torque is embedded in the delta quaternion
angvel = dBodyGetAngularVel(body);
torque[0] = q_delta[1] * t_stiffness - angvel[0] * t_damping;
torque[1] = q_delta[2] * t_stiffness - angvel[1] * t_damping;
torque[2] = q_delta[3] * t_stiffness - angvel[2] * t_damping;
dBodyAddTorque(body, torque[0], torque[1], torque[2]);
In your case you'll have to calculate target_q according to the velocity vector.
Should also mention, it's useful to make sure the quaternion doesn't
"flip" by taking the dot product:
double dot = current_q[0]*target_q[0] + current_q[1]*target_q[1]
+ current_q[2]*target_q[2] + current_q[3]*target_q[3];
// ensure delta follows the shortest path
if (dot > 0) {
target_q[0] *= -1;
target_q[1] *= -1;
target_q[2] *= -1;
target_q[3] *= -1;
}
I'm using this code to make the object follow a haptic device's end
effector position, ODE does haptics!
Steve