forked from arpg/CarPlanner
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApplyVelocitiesFunctor.cpp
More file actions
165 lines (130 loc) · 7.57 KB
/
ApplyVelocitiesFunctor.cpp
File metadata and controls
165 lines (130 loc) · 7.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "ApplyVelocitiesFunctor.h"
#include "LocalPlanner.h"
#include "Eigen/StdVector"
static bool& g_bSkidCompensationActive(CVarUtils::CreateCVar("debug.SkidCompensationActive", false, ""));
////////////////////////////////////////////////////////////////
ApplyVelocitesFunctor5d::ApplyVelocitesFunctor5d(BulletCarModel *pCarModel, Eigen::Vector3d dInitTorques, CommandList *pPreviousCommands /* = NULL */) :
m_pCarModel(pCarModel),
m_dInitTorques(dInitTorques),
m_bNoDelay(false)
{
if(pPreviousCommands != NULL) {
m_lPreviousCommands = *pPreviousCommands;
}
}
////////////////////////////////////////////////////////////////
double ApplyVelocitesFunctor5d::GetGravityCompensation(int nIndex)
{
double aExtra = -(m_pCarModel->GetTotalGravityForce(m_pCarModel->GetWorldInstance(nIndex))/m_pCarModel->GetWorldInstance(nIndex)->m_Parameters[CarParameters::Mass])*1.1/*CAR_GRAVITY_COMPENSATION_COEFFICIENT*/;
return aExtra;
}
////////////////////////////////////////////////////////////////
double ApplyVelocitesFunctor5d::GetFrictionCompensation(int nIndex, double dt)
{
double aExtra = -m_pCarModel->GetTotalWheelFriction(nIndex,dt)/m_pCarModel->GetWorldInstance(nIndex)->m_Parameters[CarParameters::Mass];
return aExtra;
}
////////////////////////////////////////////////////////////////
//double ApplyVelocitesFunctor5d::GetSteeringCompensation(VehicleState& state, double phi, double curvature, int nIndex)
//{
// //get the corrected steering parameters
// phi = m_pCarModel->GetCorrectedSteering(curvature,nIndex);
// double vf = state.m_dV.norm();
// double aExtra = fabs(vf*vf*curvature*tan(phi))*CAR_STEERING_COMPENSATION_COEFFICIENT;
// return aExtra;
//}
////////////////////////////////////////////////////////////////
void ApplyVelocitesFunctor5d::ApplyVelocities(const VehicleState& startingState,
std::vector<ControlCommand>& vCommands,
std::vector<VehicleState>& vStatesOut,
const int nStartIndex,
const int nEndIndex,
const int nIndex,
const bool bNoCompensation /*= false*/,
const CommandList *pPreviousCommands /*= NULL*/) {
Eigen::Vector3d torques;
Eigen::Vector4dAlignedVec vCoefs;
BulletWorldInstance* pWorld = m_pCarModel->GetWorldInstance(nIndex);
vStatesOut.clear();
double dTime = 0;
VehicleState currentState;
m_pCarModel->SetState(nIndex,startingState);
m_pCarModel->GetVehicleState(nIndex,currentState);
VehicleState* pCurrentState = ¤tState; //this is necessary as we need to get a pointer to the current state for compensations
//clear all the previous commands but chose between the member list or the one passed to the function
m_pCarModel->SetCommandHistory(nIndex, pPreviousCommands == NULL ? m_lPreviousCommands : *pPreviousCommands);
//m_pCarModel->ResetCommandHistory(nIndex);
vStatesOut.resize(nEndIndex-nStartIndex);
ControlCommand command;
for (int ii = nStartIndex; ii < nEndIndex; ii++) {
//update the vehicle state
//approximation for this dt
command = vCommands[ii];
if(bNoCompensation == false ){
//HACK: SampleAcceleration actually returns this as acceleration and
//not force, so we have to change that here
double totalAccel = command.m_dForce;
//compensate for gravity/slope
double aExtra = 0;
double dCorrectedCurvature;
command.m_dPhi = m_pCarModel->GetSteeringAngle(command.m_dCurvature,
dCorrectedCurvature,nIndex,1.0);
//if(dRatio < 1.0){
if(g_bSkidCompensationActive){
//get the steering compensation
std::pair<double,double> leftWheel = m_pCarModel->GetSteeringRequiredAndMaxForce(nIndex,0,command.m_dPhi,command.m_dT);
std::pair<double,double> rightWheel = m_pCarModel->GetSteeringRequiredAndMaxForce(nIndex,1,command.m_dPhi,command.m_dT);
double dRatio = std::max(fabs(leftWheel.second/leftWheel.first),fabs(rightWheel.second/rightWheel.first));
for(int ii = 0 ; ii < 5 && dRatio < 1.0 ; ii++){
command.m_dCurvature *=1.5;///= (dRatio);
command.m_dPhi = m_pCarModel->GetSteeringAngle(command.m_dCurvature,
dCorrectedCurvature,nIndex,1.0);
std::pair<double,double> newLeftWheel = m_pCarModel->GetSteeringRequiredAndMaxForce(nIndex,0,command.m_dPhi,command.m_dT);
std::pair<double,double> newRightWheel = m_pCarModel->GetSteeringRequiredAndMaxForce(nIndex,1,command.m_dPhi,command.m_dT);
dRatio = std::max(fabs(newLeftWheel.second/leftWheel.first),fabs(newRightWheel.second/rightWheel.first));
}
}
aExtra += GetGravityCompensation(nIndex);
//aExtra += GetSteeringCompensation(*pCurrentState,command.m_dPhi,command.m_dCurvature,nIndex);
aExtra += GetFrictionCompensation(nIndex,command.m_dT);
totalAccel += aExtra;
// if(dRatio < 1.0){
// totalAccel = 0;//(dRatio*dRatio*dRatio);
// }
//actually convert the accel (up to this point) to a force to be applied to the car
command.m_dForce = totalAccel*m_pCarModel->GetWorldInstance(nIndex)->m_Parameters[CarParameters::Mass];
//here Pwm = (torque+slope*V)/Ts
command.m_dForce = sgn(command.m_dForce)* (fabs(command.m_dForce) + pWorld->m_Parameters[CarParameters::TorqueSpeedSlope]*pWorld->m_state.m_dV.norm())/pWorld->m_Parameters[CarParameters::StallTorqueCoef];
command.m_dForce += pWorld->m_Parameters[CarParameters::AccelOffset]*SERVO_RANGE;
//offset and coef are in 0-1 range, so multiplying by SERVO_RANGE is necessary
command.m_dPhi = SERVO_RANGE*(command.m_dPhi*pWorld->m_Parameters[CarParameters::SteeringCoef] +
pWorld->m_Parameters[CarParameters::SteeringOffset]);
//save the command changes to the command array -- this is so we can apply
//the commands to the vehicle WITH compensation
vCommands[ii] = command;
}
//set the timestamp for this command
vCommands[ii].m_dTime = dTime;
dTime += command.m_dT;
m_pCarModel->UpdateState(nIndex,command,command.m_dT,m_bNoDelay);
m_pCarModel->GetVehicleState(nIndex,vStatesOut[ii-nStartIndex]);
vStatesOut[ii-nStartIndex].m_dCurvature = command.m_dCurvature;
pCurrentState = &vStatesOut[ii-nStartIndex];
pCurrentState->m_dTime = dTime;
}
}
////////////////////////////////////////////////////////////////
VehicleState ApplyVelocitesFunctor5d::ApplyVelocities(const VehicleState& startState,
MotionSample& sample,
int nIndex /*= 0*/,
bool noCompensation /*= false*/) {
ApplyVelocities(startState,
sample.m_vCommands,
sample.m_vStates,
0,
sample.m_vCommands.size(),
nIndex,
noCompensation,
NULL);
return sample.m_vStates.back();
}