[ODE] Help with car simulation pls! :/

david@csworkbench.com david at csworkbench.com
Sat Apr 5 00:48:01 2003


Ok, let's explain exactly what the motors are doing.  They're turning the
wheels around their second axis.  So if you increase the velocity, the
wheels turn like wheels should if you press the gas on a car.  But without
a ground plane, and I'm assuming no gravity either (I haven't seen your
demo, I'm on Linux), there's nothing for those wheels to turn against.  It
sounds like your car is just suspended in midair.  So the torque that
motor exerts on the wheel is also exerted (oppositely) on the car body. 
That's why your car seems to flip end over end when you press the gas. 
When you turn the wheels to the left or right, the torque is exerted to
the left or right, so the car seems to turn on its side.  The way the
motor is supposed to work is, the motor turns the wheel, the contact joint
between the wheel and the ground keeps the bottom of the wheel stuck to
the same place on the ground, so the car body moves forward to satisfy the
constraint.  The motor doesn't directly push the car body forward (much
like what happens in real life).  Finally, to explain the jerking when you
turn the wheels, that is caused by the fact that you are turning the
wheels into a stop.  You are applying power (by setting fmax > 0 and
velocity != 0) in the direction of a stop, but the stop is reacting to
keep the wheels from turning that far, so the wheels sit there and
"bounce" against the stop.

So what can you do to fix it?  The first best thing is to add a ground
plane and gravity, and be sure to set up at least a little bit of friction
in your collision callback function.  That should get your car to start
moving in the direction you want it to.  But it won't handle the stop
problem.  The way you fix that is, down at the very bottom of the code you
copied in, where you set the FMax to 2.0, check dHinge2GetAngle1 to see if
it returns a number outside of -0.5 and 0.5.  If that's the case, set the
FMax to 0 to unpower the joint, otherwise set it to 2.0 as planned.  ODE
just doesn't handle powering into stops very gracefully at present.

Again, I haven't seen your simulation since I'm on linux and didn't find
any source code to recompile.  If I've totally missed it from what you've
said, let me know and I'll boot into Windows (ugh) at some point in the
not too distant future.

Hope that helps,
David

> Hi,
>
> I've been trying to get a car simulation to work much in the same way as
> buggydemo, test_buggy, silkworm, however for some reason mine just
> doesn't want to behave itself.. I must be doing something wrong in
> either way the way I'm creating the model/joints or my nieve attempts to
> get the bloody thing to move :p
>
> The symptons are like this.. when I just steer left or right the front
> wheels do rotate in the desired direction by the car "jerks" violently
> and actually rotates around its y-axis (even if I haven't applied any
> forward velocity, just moved the wheels..) if I keep steering left or
> right the car will rotate  faster and faster.. also when I go would go
> to accelerate forward or backwards the car rotates around its x-axis (at
> a stupidly fast speed.. but thats a value that needs tweaked
> probably?).. instead of what I would have thought (want to happen) move
> in the direction the wheels are pointing..
>
> I uploaded a test build at http://www.bl33t.co.uk/ode/Um.zip if my
> explaination is a bit crappy :( (cursor keys to control))
>
> I have two hunches on why, but I can't seem to fix them.
>
> One is that I don't have a ground plane so thats why the car is rotating
> around itself.. but then that doesn't explain why the actually chassis
> moves when I just steer left or right... and I'm trying to push it
> forward... not down :/
>
> I thought it might have something to do with the way I've created the
> Hinge2 joint between the chassis and the wheels, but it seems logically
> to me, steering is done on the y-axis (rotating wheels in the desired
> direction) and the moving is down on x-axis of the wheel :(
>
> // 0-1 = FRONT | 2-3 = BACK
> for(i = 0; i != 4; ++i)
> {
>
> // Create a Hinge 2 joint
> m_WheelJoints[i] = dJointCreateHinge2(GetWorldID(), 0);
>
> // Attach joint to the vehicle chassis
> dJointAttach(m_WheelJoints[i], m_BodyID, m_WheelBodies[i]);
>
> // What is the wheels position? (will create a 3-element array)
> const dReal* const vWheelPos = dBodyGetPosition(m_WheelBodies[i]);
>
> // Axis 1 - Steering-Axis (Y)
> // Axis 2 - Wheel Turning-Axis (X)
> dJointSetHinge2Anchor(m_WheelJoints[i], vWheelPos[0], vWheelPos[1],
> vWheelPos[2]);
> dJointSetHinge2Axis1(m_WheelJoints[i], 0, 1, 0);
> dJointSetHinge2Axis2(m_WheelJoints[i], 1, 0, 0);
>
> // Joint suspension
> dJointSetHinge2Param(m_WheelJoints[i], dParamSuspensionERP, 0.4);
> dJointSetHinge2Param(m_WheelJoints[i], dParamSuspensionCFM, 1.5);
>
> // Wheels aligned along steering axis
> dJointSetHinge2Param(m_WheelJoints[i], dParamLoStop, 0);
> dJointSetHinge2Param(m_WheelJoints[i], dParamHiStop, 0);
>
> }
>
> The way I attempt to move the car is pretty much taken from the silkworm
> source. From what I understand instead of applying a force to the
> chassis body via dApplyForce to get the car to move, the wheel
> joints/bodies have motors which will "move" the car.
>
> // Update speed/steering
> void CCar::Update()
> {
> if(m_VehicleMovement & ACCEL_FORWARD)
> {
> m_VehicleSpeed += 0.2;
> }
> if(m_VehicleMovement & ACCEL_BACKWARD)
> {
> m_VehicleSpeed -= 0.2;
> }
> if(m_VehicleMovement & STEER_LEFT)
> {
> m_VehicleSteer = -1.0;
> }
> if(m_VehicleMovement & STEER_RIGHT)
> {
> m_VehicleSteer = 1.0;
> }
> MoveVehicle();
> m_VehicleMovement = NULL;
> }
>
> // "Move" the vehicle
> void CVehicle::MoveVehicle()
> {
> int w;
> for (w = 0; w < 4; w++)
> {
> dJointSetHinge2Param (m_WheelJoints[w], dParamVel2, m_VehicleSpeed);
> dJointSetHinge2Param (m_WheelJoints[w], dParamFMax2, 0.4);
> }
>
> // steering
> bool steer_pressed = false;
> if (m_VehicleMovement & STEER_LEFT) { steer_pressed = true; }
> if (m_VehicleMovement & STEER_RIGHT) { steer_pressed = true; }
> for (w = 0; w < 4; w++)
> {
> if (w < 2)
> {
> dJointSetHinge2Param (m_WheelJoints[w],dParamVel, m_VehicleSteer); }
> /* else
> {
> dJointSetHinge2Param (m_WheelJoints[w],dParamVel, -m_VehicleSteer); }
> */
> if (!steer_pressed)
> {
> dJointSetHinge2Param (m_WheelJoints[w],dParamLoStop,-0.00);
> dJointSetHinge2Param (m_WheelJoints[w],dParamHiStop, 0.00);
> }
> else
> {
> dJointSetHinge2Param (m_WheelJoints[w],dParamLoStop,-0.50);
> dJointSetHinge2Param (m_WheelJoints[w],dParamHiStop, 0.50);
> }
> dJointSetHinge2Param (m_WheelJoints[w],dParamFMax, 2.0);
> dJointSetHinge2Param (m_WheelJoints[w],dParamFudgeFactor, 0.1);
> }
> }
>
> Any help, tips, hints anything to help me solve this would be greatly
> appericated! I know im so close.. but so far :(
>
> Regards
>
> Craig
>
>
> _______________________________________________
> ODE mailing list
> ODE@q12.org
> http://q12.org/mailman/listinfo/ode