void CAIRobot::FollowPath(const D3DXVECTOR3 *m_vPos,const D3DXVECTOR3 *m_vHeading,const D3DXVECTOR3* m_vVelocity)
{
const D3DXVECTOR3 *m_vWayPt = g_Profile.aGameStyle->aAIPath.vNodePoint;
const D3DXVECTOR3 *m_vWayTan = g_Profile.aGameStyle->aAIPath.vNodeTangent;
const float *m_fWaySpeed = g_Profile.aGameStyle->aAIPath.fWayPtSpeed;
const int *nNumWayPt = &g_Profile.aGameStyle->aAIPath.nWayPtCount
D3DXVECTOR3 vCurPos = *m_vPos;
//Find Out the Next Way Point
if(m_dPrevPt == m_dCurPt)
m_dPrevPt -= 1;
if(m_dPrevPt<0)
m_dPrevPt = *nNumWayPt-1;
int nNextPt = m_dCurPt;
if(nNextPt>=*nNumWayPt)
nNextPt = 0;
fStep = 0.2f+D3DXVec3Length(&(m_vWayPt[m_dPrevPt] - vCurPos))/D3DXVec3Length(&(m_vWayPt[m_dCurPt] - m_vWayPt[m_dPrevPt]));
if(fStep>1)fStep = 1;
if( fStep==1)
{
m_dPrevPt = m_dCurPt;
m_dCurPt = nNextPt+1;
}
int nPt0 = m_dPrevPt-1;
if(nPt0<0)
nPt0 = *nNumWayPt-1;
int nPt1 = m_dCurPt+1;
if(nPt1>=*nNumWayPt)
nPt1 = 0;
D3DXVECTOR3 vTarPt = CalculateSplinePt(m_vWayPt[nPt0],m_vWayPt[m_dPrevPt],m_vWayPt[m_dCurPt],m_vWayPt[nPt1],fStep);
vTargetCross = vTarPt;
//Find Out the Steering angle
D3DXVECTOR3 m_vTarget = vTarPt - vCurPos;
D3DXVECTOR3 m_vSteer;
D3DXVec3Normalize(&m_vTarget,&m_vTarget);
D3DXVec3Cross(&m_vSteer,m_vHeading,&m_vTarget);
D3DXVec3Normalize(&m_vSteer, &m_vSteer);
// Left or right?
if(m_vSteer.z<-0.1f)//+ve Left -ve Right
m_fUserInput[INPUT_LEFT]=1;
else if((m_vSteer.z>0.1f))
m_fUserInput[INPUT_RIGHT]=1;
}
Car Spline Path Follow
I got a serious problem in making my car to follow the spline path...
Vehicle is moving along the path but in zig zag way...Tel me where am i doing wrong...
If you have any Article links for Path following...That wil be really great to me...
Here is my code...
Well it is difficult to tell from the code, but perhaps the problem is that you're using discrete input rather than analogue? Meaning that you will steer harshly left until your over the line, then harshly right etc. etc. meaning you're forever over-compensating with your steering. Is it possible to use analogue input, using less input the closer to the line the car is, or if this isn't possible, then stop steering when u get close to the line.
makar's assertion is correct; you are performing what is known as a 'bang-bang' control strategy. That is, control is either on or off (or in your case, left or right). There are a variety of alternative methods you could implement. Here are some options for you:
1) Implement a 'dead band'. That is, if the car is within a finite distance of the spline curve, don't apply any steering control. If the spline is curved, eventually the car will diverge from the spline and your controller will then steer it back to the curve. There is obviously a clear relationship between the width of the dead band and the quality of control (i.e., how close the the path you can guarantee being).
2) Implement a 'look-ahead' (also called 'model predictive') controller. Compute the position of the car at some small time interval in the future and make a steering decision based on whether this point is on the left or right of the path. You can enhance this method by including a dead band as well.
3) Implement a vehicle with more than two steering values. This will allow you to choose shallower steering when close to the path and sharper steering when further away from it.
4) Combine all of the above. Implement multiple steering angles for your vehicle (or even a smooth steering function that permits the car to turn at any angular rate up to some maximum) and add a PD (proportional derivative) controller. A PD controller computes the steering angle based on both the error (distance between car and spline) and the first derivative of this error (easily approximated using de(t) = (e(t)-e(t-dt))/dt (e: error; de: derivative; t: time; dt: timestep) ). Add in a small deadband to reduce the control load when very close to the path... and make it predictive by choosing the steering angle based on what the spline path is doing ahead of the vehicle (curving to left, curving to right or staying straight).
If you're not sure how to do any of this, just holler. There are plenty of people herein (myself included) that would be happy to point you in the right direction.
Cheers,
Timkin
1) Implement a 'dead band'. That is, if the car is within a finite distance of the spline curve, don't apply any steering control. If the spline is curved, eventually the car will diverge from the spline and your controller will then steer it back to the curve. There is obviously a clear relationship between the width of the dead band and the quality of control (i.e., how close the the path you can guarantee being).
2) Implement a 'look-ahead' (also called 'model predictive') controller. Compute the position of the car at some small time interval in the future and make a steering decision based on whether this point is on the left or right of the path. You can enhance this method by including a dead band as well.
3) Implement a vehicle with more than two steering values. This will allow you to choose shallower steering when close to the path and sharper steering when further away from it.
4) Combine all of the above. Implement multiple steering angles for your vehicle (or even a smooth steering function that permits the car to turn at any angular rate up to some maximum) and add a PD (proportional derivative) controller. A PD controller computes the steering angle based on both the error (distance between car and spline) and the first derivative of this error (easily approximated using de(t) = (e(t)-e(t-dt))/dt (e: error; de: derivative; t: time; dt: timestep) ). Add in a small deadband to reduce the control load when very close to the path... and make it predictive by choosing the steering angle based on what the spline path is doing ahead of the vehicle (curving to left, curving to right or staying straight).
If you're not sure how to do any of this, just holler. There are plenty of people herein (myself included) that would be happy to point you in the right direction.
Cheers,
Timkin
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement