4 wheel vehicle motorTorque crash

aspilicious

22-02-2011 19:54:45

I made the folowwing function:

void Car::moveForward()
{
backWheelLeft->setMotorTorque(100);
backWheelRight->setMotorTorque(100);
}

And it crashes in the setMotorTorque function.
Any ideas?

EDIT:
The wheels are initialized like this:

frontWheelLeft = static_cast<NxOgre::Wheel*>(car->getShape(FrontWheelLeft));
frontWheelRight = static_cast<NxOgre::Wheel*>(car->getShape(FrontWheelRight));
backWheelLeft = static_cast<NxOgre::Wheel*>(car->getShape(BackWheelLeft));
backWheelRight = static_cast<NxOgre::Wheel*>(car->getShape(BackWheelRight));

aspilicious

22-02-2011 20:12:32

My code if you need it :)

Critter::BodyDescription bodyDescription;
bodyDescription.mMass = 80.0f;

// A body with a wheel can't sleep. So we'll make the sleep counter to ~3 years!
bodyDescription.mWakeUpCounter = 1E8;

NxOgre::ShapeDescriptions shapes;

// A wheel can't just be attached to a Actor/Body by itself, it needs a chassis for collisions.
NxOgre::BoxDescription box_desc;
box_desc.mSize.set(0.5,0.5,1.5);
box_desc.mId = Chassis;

// Create 4 wheels two at the front (the steering) and two at the back (the driving)
NxOgre::WheelDescription front_wheel_left_desc;
front_wheel_left_desc.mRadius = 0.5f;
front_wheel_left_desc.mLocalPose = NxOgre::Vec3(-1.0,0,-2.0);
front_wheel_left_desc.mId = FrontWheelLeft;

NxOgre::WheelDescription front_wheel_right_desc;
front_wheel_right_desc.mRadius = 0.5f;
front_wheel_right_desc.mLocalPose = NxOgre::Vec3(1.0,0,-2.0);
front_wheel_right_desc.mId = FrontWheelRight;

NxOgre::WheelDescription back_wheel_left_desc;
back_wheel_left_desc.mRadius = 0.5f;
back_wheel_left_desc.mLocalPose = NxOgre::Vec3(-1.0,0,2.0);
back_wheel_left_desc.mId = BackWheelLeft;

NxOgre::WheelDescription back_wheel_right_desc;
back_wheel_right_desc.mRadius = 0.5f;
back_wheel_right_desc.mLocalPose = NxOgre::Vec3(1.0,0,2.0);
back_wheel_right_desc.mId = BackWheelRight;

shapes.push_back(&box_desc);
shapes.push_back(&front_wheel_left_desc);
shapes.push_back(&front_wheel_right_desc);
shapes.push_back(&back_wheel_left_desc);
shapes.push_back(&back_wheel_right_desc);

car = renderSystem->createBody(shapes, NxOgre::Vec3(0,3,0), "cube.1m.mesh", bodyDescription);
car->getSceneNode()->setScale(Ogre::Vector3(3.0,0.5,6.0));

frontWheelLeft = static_cast<NxOgre::Wheel*>(car->getShape(FrontWheelLeft));
frontWheelRight = static_cast<NxOgre::Wheel*>(car->getShape(FrontWheelRight));
backWheelLeft = static_cast<NxOgre::Wheel*>(car->getShape(BackWheelLeft));
backWheelRight = static_cast<NxOgre::Wheel*>(car->getShape(BackWheelRight));

betajaen

22-02-2011 20:54:40

Are those pointers actual pointers? Not NULL or 0xCCCCCCCC?

aspilicious

22-02-2011 22:29:19

WHAT o_O
After some trial and error and debug info I had to do this:

frontWheelLeft = static_cast<NxOgre::Wheel*>(car->getShape(3));
frontWheelRight = static_cast<NxOgre::Wheel*>(car->getShape(2));
backWheelLeft = static_cast<NxOgre::Wheel*>(car->getShape(1));
backWheelRight = static_cast<NxOgre::Wheel*>(car->getShape(0));

I dont know how the shape array get filled but this is weird o_O

proof

23-02-2011 05:47:58

When adding the wheel like in the example aspilicious posted, the WheelDescription.mId is the Id you need to pass to car->getShape(Id) so it would return the right wheel.

betajaen

23-02-2011 08:07:41

Actually your both wrong.

getShape(index) returns a shape, where index is the position of the shape in the array. 0 = Returns the Chassis, 1 = Front Left Wheel, 2 = Front Right Wheel, and so on. This order is determined when you push_back a shape description into a ShapeDescriptions when giving it to the create method.

A new BuggySwires function "getShapeByID(index)" returns a shape, where index is the Shape::getID() of that shape. Chassis = Returns the Chassis, FrontWheelLeft = Front Left Wheel, FrontWheelRight = Front Right Wheel, and so on.

In short, your mixing up BuggySwires code with Detritus code.

aspilicious

23-02-2011 08:25:01

I don't think I'm wrong this time
I also thought the Id was the order it was pushed into the array.

But I get the following results:


shapes.push_back(&box_desc);
shapes.push_back(&front_wheel_left_desc);
shapes.push_back(&front_wheel_right_desc);
shapes.push_back(&back_wheel_left_desc);
shapes.push_back(&back_wheel_right_desc);

frontWheelLeft = static_cast<NxOgre::Wheel*>(car->getShape(1));
frontWheelRight = static_cast<NxOgre::Wheel*>(car->getShape(2));
backWheelLeft = static_cast<NxOgre::Wheel*>(car->getShape(3));
backWheelRight = static_cast<NxOgre::Wheel*>(car->getShape(4));


Result
--------
frontWheelLeft => mId = 4 => mWheelShape
frontWheelRight => mId = 3 => mWheelShape
backWheelLeft => mId = 2 => mWheelShape
backWheelRight => mId = 1 => boxShape

Expected results
--------------------
frontWheelLeft => mId = 2 => mWheelShape
frontWheelRight => mId = 3 => mWheelShape
backWheelLeft => mId = 4 => mWheelShape
backWheelRight => mId = 5 => mWheelShape

betajaen

23-02-2011 09:07:15

Are you using BuggySwires? or Detritus?


It's getShapeByID to get a shape by an ID. Your getting it by the position it was inserted into the vector.

Shape* RigidBody::getShape(unsigned int index)
{
if (index > mShapes.size() - 1)
return 0;
return mShapes.at(index);
}

Shape* RigidBody::getShapeById(unsigned int id)
{
for (unsigned int i=0;i < mShapes.size();i++)
if (mShapes[i]->getId() == id)
return mShapes[i];
return 0;
}

aspilicious

23-02-2011 09:57:53

*please* look at my code carefully. I know how it works, but somehow something is still unlogical.
I use detrius.

shapes.push_back(&box_desc);
shapes.push_back(&front_wheel_left_desc);
shapes.push_back(&front_wheel_right_desc);
shapes.push_back(&back_wheel_left_desc);
shapes.push_back(&back_wheel_right_desc);

==> This means the shapes array should be in this order:

0) *box_desc
1) *front_wheel_left_desc
2) *front_wheel_right_desc
3) *back_wheel_left_desc
4) *back_wheel_right_desc

==> That is correct (I checked it in my debugger)
==> Now I'm adding the shapes array to my car
car = renderSystem->createBody(shapes, NxOgre::Vec3(0,3,0), "cube.1m.mesh", bodyDescription);

==> If I check the shapes array now with car->getShapes(). I get an iterator.
==> And this iterator has a different order for my shapes. So I can't rely on the order I added them in the shapes array. Something in the createBody function changes the order.
==> This is a bug or it is by design

The solution I use (in my 3th reply) is correct for my code (I can confirm that because my car is driving and the wheel pointers are connected with the right wheel).
If i need this more I should probably write my own getShapeById