AIWheeledVehicle steering aid
by Tim Hutcheson · 10/23/2005 (4:37 pm) · 9 comments
Download Code File
To get this running, add this to vehicle.h around line 100:
In AIWheeledVehicle::getSteeringAngle, add the follwing right after
front = wFront + center;
Then place this into your AIWheeledVehicle.cc file:
If you want to turn this feature on and off, bind mDataBlock->gShowSteeringConstructs to a key toggle routine. But used only as a diagnostic, I just edit the renderImage routine to do this.
As a footnote to this, I found occasions where #NAND was generated an cleaned p the whole trangle code a bit, to make it more textbook Cosine law like and added code to check for numerical inconsistencies. I replaced the code from
apx Line 113:
down to apx line 132
with:
That's about it, impress your friends with how smart your bots are.
To get this running, add this to vehicle.h around line 100:
Point3F front, center, desired; bool gShowSteeringConstructs;
In AIWheeledVehicle::getSteeringAngle, add the follwing right after
front = wFront + center;
mDataBlock->center = center; mDataBlock->front = front; mDataBlock->desired = desired;
Then place this into your AIWheeledVehicle.cc file:
void AIWheeledVehicle::renderImage(SceneState *state, SceneRenderImage *image)
{
Parent::renderImage(state, image);
mDataBlock->gShowSteeringConstructs = true;
if (mDataBlock->gShowSteeringConstructs) {
glDisable(GL_LIGHTING);
glPushMatrix();
dglMultMatrix(&getRenderTransform());
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
Point3F center = mDataBlock->center;
Point3F front = mDataBlock->front;
Point3F desired = mDataBlock->desired;
// desired.z = center.z; // Use this if you want your drawn triangle flat in the plane of the vehicle
MatrixF wt = this->getWorldTransform();
wt.mulP(center);
wt.mulP(desired);
wt.mulP(front);
glBegin(GL_LINES);
glColor3f(1, 0, 0);
glVertex3f(front.x, front.y, front.z);
glVertex3f(desired.x, desired.y, desired.z);
glEnd();
wireCube(Point3F(0.05,0.05,0.05),front);
glBegin(GL_LINES);
glColor3f(0, 1, 0);
glVertex3f(desired.x, desired.y, desired.z);
glVertex3f(center.x, center.y, center.z);
glEnd();
wireCube(Point3F(0.05,0.05,0.05),desired);
glBegin(GL_LINES);
glColor3f(0, 0, 1);
glVertex3f(center.x, center.y, center.z);
glVertex3f(front.x, front.y, front.z);
glEnd();
wireCube(Point3F(0.05,0.05,0.05),center);
glPopMatrix();
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
}
}If you want to turn this feature on and off, bind mDataBlock->gShowSteeringConstructs to a key toggle routine. But used only as a diagnostic, I just edit the renderImage routine to do this.
As a footnote to this, I found occasions where #NAND was generated an cleaned p the whole trangle code a bit, to make it more textbook Cosine law like and added code to check for numerical inconsistencies. I replaced the code from
apx Line 113:
Point3F ftoc;
down to apx line 132
Point3F location = getPosition();
with:
Point3F A = desired - center; // ltoc
Point3F B = front - center; // ftoc
Point3F C = front - desired; // ftol
F32 a2 = A.x*A.x + A.y*A.y;
F32 b2 = B.x*B.x + B.y*B.y;
F32 c2 = C.x*C.x + C.y*C.y;
F32 a = mSqrt(a2);
F32 b = mSqrt(b2);
F32 c = mSqrt(c2);
F32 acosarg = 0.0f;
F32 myAngle;
if( a*b == 0.0f ) {
if( a2 + b2 - c2 >= 0.0f )
myAngle = M_PI/2.0f;
else myAngle = -M_PI/2.0f;
}
else {
acosarg = (a2 + b2 - c2)/(2*a*b);
if(acosarg > .99999f) acosarg = 1.0f;
else if(acosarg < -.99999f) acosarg = -1.0f;
myAngle = acos(acosarg);
}That's about it, impress your friends with how smart your bots are.
About the author
#2
10/11/2005 (4:34 am)
#3
Since I posted the original resource I fixed another problem or two with the getSteerinAngle() routine. And I revised the renderImage method as well to move the worldTransform code out of that routine and back to the getSteeringAngle code where it belongs (otherwise it's out of synch). So here is the revised resource, from the top:
In vehicle.h, around line 107, add:
In AIWheeledVehicle.h after getSteeringAngle() , around line 40 add:
In aiWheeledVehicle.cc, replace the getSteeringAngle method with
[code]
void AIWheeledVehicle::renderImage(SceneState *state, SceneRenderImage *image)
{
Parent::renderImage(state, image);
// This tool provides a graphical diagnostic of the state of the
// steering algorithm for the AIWheeledVehicle. It consists of
// three colored cubes connected by the steering triangle.
// The red cube is placed at the front of the vehicle, the blue
// cube is at the "center" point (where the cosine is taken) and
// the red cube is at the vehicle destination. The "center" cube
// switches color when the steeringState changes: blue for left
// and green for right. Run the vehicle around a path, observe
// the behaior and tune the loop gain (K1) and the triangle (K2)
// for your bot.
mDataBlock->gShowSteeringConstructs = true;
if (mDataBlock->gShowSteeringConstructs)
{
glDisable(GL_LIGHTING);
glPushMatrix();
dglMultMatrix(&getRenderTransform());
Point3F center = mDataBlock->center;
Point3F front = mDataBlock->front;
Point3F desired = mDataBlock->desired;
F32 s = 0.05f;
glBegin(GL_LINES);
glColor3f(1, 0, 0);
glVertex3f(front.x, front.y, front.z);
glVertex3f(desired.x, desired.y, desired.z);
glEnd();
wireCube(Point3F(s,s,s),front);
glBegin(GL_LINES);
glColor3f(0, 1, 0);
glVertex3f(desired.x, desired.y, desired.z);
glVertex3f(center.x, center.y, center.z);
glEnd();
wireCube(Point3F(s,s,s),desired);
glBegin(GL_LINES);
glColor3f(0, 0, 1);
glVertex3f(center.x, center.y, center.z);
glVertex3f(front.x, front.y, front.z);
glEnd();
if( mDataBlock->steerState == 2)
glColor3f(0, 1, 0);
wireCube(Point3F(s,s,s),center);
glPopMatrix();
glEnable(GL_LIGHTING);
}
}
F32 AIWheeledVehicle::getSteeringAngle()
{
// K1 is the negative feedback or damping factor from the wheels.
// The magnitude should not be too large as it will introduce
// steady state errors or too small as it will make the closed loop
// unstable (wheel waggle). But it depends on the mass of the vehicle
// springs and steering geometry, so best results are had by tuning using
// the tools in the renderImage method.
F32 K1 = -0.2f;
// K2 determines the length of the line from center to front of the
// steering triangle and affects the steering of the vehicle somewhat
// in close corners, so it is adjustable.
F32 K2 = 0.75f;
desired = mMoveDestination;
Box3F box = getObjBox();
box.getCenter(
10/11/2005 (5:45 am)
Sorry for the missing definiton. Since I posted the original resource I fixed another problem or two with the getSteerinAngle() routine. And I revised the renderImage method as well to move the worldTransform code out of that routine and back to the getSteeringAngle code where it belongs (otherwise it's out of synch). So here is the revised resource, from the top:
In vehicle.h, around line 107, add:
Point3F front, center, desired; int steerState; bool gShowSteeringConstructs;
In AIWheeledVehicle.h after getSteeringAngle() , around line 40 add:
void AIWheeledVehicle::renderImage(SceneState *state, SceneRenderImage *image);
In aiWheeledVehicle.cc, replace the getSteeringAngle method with
[code]
void AIWheeledVehicle::renderImage(SceneState *state, SceneRenderImage *image)
{
Parent::renderImage(state, image);
// This tool provides a graphical diagnostic of the state of the
// steering algorithm for the AIWheeledVehicle. It consists of
// three colored cubes connected by the steering triangle.
// The red cube is placed at the front of the vehicle, the blue
// cube is at the "center" point (where the cosine is taken) and
// the red cube is at the vehicle destination. The "center" cube
// switches color when the steeringState changes: blue for left
// and green for right. Run the vehicle around a path, observe
// the behaior and tune the loop gain (K1) and the triangle (K2)
// for your bot.
mDataBlock->gShowSteeringConstructs = true;
if (mDataBlock->gShowSteeringConstructs)
{
glDisable(GL_LIGHTING);
glPushMatrix();
dglMultMatrix(&getRenderTransform());
Point3F center = mDataBlock->center;
Point3F front = mDataBlock->front;
Point3F desired = mDataBlock->desired;
F32 s = 0.05f;
glBegin(GL_LINES);
glColor3f(1, 0, 0);
glVertex3f(front.x, front.y, front.z);
glVertex3f(desired.x, desired.y, desired.z);
glEnd();
wireCube(Point3F(s,s,s),front);
glBegin(GL_LINES);
glColor3f(0, 1, 0);
glVertex3f(desired.x, desired.y, desired.z);
glVertex3f(center.x, center.y, center.z);
glEnd();
wireCube(Point3F(s,s,s),desired);
glBegin(GL_LINES);
glColor3f(0, 0, 1);
glVertex3f(center.x, center.y, center.z);
glVertex3f(front.x, front.y, front.z);
glEnd();
if( mDataBlock->steerState == 2)
glColor3f(0, 1, 0);
wireCube(Point3F(s,s,s),center);
glPopMatrix();
glEnable(GL_LIGHTING);
}
}
F32 AIWheeledVehicle::getSteeringAngle()
{
// K1 is the negative feedback or damping factor from the wheels.
// The magnitude should not be too large as it will introduce
// steady state errors or too small as it will make the closed loop
// unstable (wheel waggle). But it depends on the mass of the vehicle
// springs and steering geometry, so best results are had by tuning using
// the tools in the renderImage method.
F32 K1 = -0.2f;
// K2 determines the length of the line from center to front of the
// steering triangle and affects the steering of the vehicle somewhat
// in close corners, so it is adjustable.
F32 K2 = 0.75f;
desired = mMoveDestination;
Box3F box = getObjBox();
box.getCenter(
#4
10/11/2005 (5:56 am)
deleted post, fixed the above...
#5
10/11/2005 (6:02 am)
Gosh I hope that fixes everything. I think I should best redo this resource on top of a clean copy of the 1.4RC2 version of the AIWheeledVehicle code just to be sure I'm not overlooking anything else. Sorry, my bad.
#6
10/12/2005 (7:56 am)
Fixed up the resource a little and uploaded the body of code with a snapshot of what you would see in first person view. The snapshot was taking just after the bot recieved a new target position and the wheels had moved full left toward the target. Once the target is in line with the vehicle, small deviations in the sterring commands would show up in the off-vertical deflection of the green line. The larger cube turns colors based on even the smallest right and left steering changes.
#7
10/13/2005 (2:22 am)
#8
10/13/2005 (3:06 am)
#9
10/13/2005 (5:10 am)
Juan, the yellow arrows are part of the building skin (image) and not part of the resource. 
Torque Owner Corin