Cheetah Software  1.0
LegController.cpp
Go to the documentation of this file.
1 
11 #include <eigen3/Eigen/Dense>
12 
14 
18 template <typename T>
20  tauFeedForward = Vec3<T>::Zero();
21  forceFeedForward = Vec3<T>::Zero();
22  qDes = Vec3<T>::Zero();
23  qdDes = Vec3<T>::Zero();
24  pDes = Vec3<T>::Zero();
25  vDes = Vec3<T>::Zero();
26  kpCartesian = Mat3<T>::Zero();
27  kdCartesian = Mat3<T>::Zero();
28  kpJoint = Mat3<T>::Zero();
29  kdJoint = Mat3<T>::Zero();
30 }
31 
32 template <typename T>
34  q = Vec3<T>::Zero();
35  qd = Vec3<T>::Zero();
36  p = Vec3<T>::Zero();
37  v = Vec3<T>::Zero();
38  J = Mat3<T>::Zero();
39  tauEstimate = Vec3<T>::Zero();
40 }
41 
47 template <typename T>
49  for (auto& cmd : commands) {
50  cmd.zero();
51  }
52  _legsEnabled = false;
53 }
54 
61 template <typename T>
63  zeroCommand();
64  if (robot == RobotType::CHEETAH_3) {
65  for (int leg = 0; leg < 4; leg++) {
66  for (int axis = 0; axis < 3; axis++) {
67  commands[leg].kdCartesian(axis, axis) = gain;
68  }
69  }
70  } else { // mini-cheetah
71  for (int leg = 0; leg < 4; leg++) {
72  for (int axis = 0; axis < 3; axis++) {
73  commands[leg].kdJoint(axis, axis) = gain;
74  }
75  }
76  }
77 }
78 
82 template <typename T>
83 void LegController<T>::updateData(const SpiData* spiData) {
84  for (int leg = 0; leg < 4; leg++) {
85  // q:
86  datas[leg].q(0) = spiData->q_abad[leg];
87  datas[leg].q(1) = spiData->q_hip[leg];
88  datas[leg].q(2) = spiData->q_knee[leg];
89 
90  // qd
91  datas[leg].qd(0) = spiData->qd_abad[leg];
92  datas[leg].qd(1) = spiData->qd_hip[leg];
93  datas[leg].qd(2) = spiData->qd_knee[leg];
94 
95  // J and p
96  computeLegJacobianAndPosition<T>(_quadruped, datas[leg].q, &(datas[leg].J),
97  &(datas[leg].p), leg);
98 
99  // v
100  datas[leg].v = datas[leg].J * datas[leg].qd;
101  }
102 }
103 
107 template <typename T>
108 void LegController<T>::updateData(const TiBoardData* tiBoardData) {
109  for (int leg = 0; leg < 4; leg++) {
110  for (int joint = 0; joint < 3; joint++) {
111  datas[leg].q(joint) = tiBoardData[leg].q[joint];
112  datas[leg].qd(joint) = tiBoardData[leg].dq[joint];
113  datas[leg].p(joint) = tiBoardData[leg].position[joint];
114  datas[leg].v(joint) = tiBoardData[leg].velocity[joint];
115  computeLegJacobianAndPosition<T>(_quadruped, datas[leg].q, &datas[leg].J,
116  nullptr, leg);
117  datas[leg].tauEstimate[joint] = tiBoardData[leg].tau[joint];
118  }
119  }
120 }
121 
125 template <typename T>
127  for (int leg = 0; leg < 4; leg++) {
128  // tauFF
129  Vec3<T> legTorque = commands[leg].tauFeedForward;
130 
131  // forceFF
132  Vec3<T> footForce = commands[leg].forceFeedForward;
133 
134  // cartesian PD
135  footForce +=
136  commands[leg].kpCartesian * (commands[leg].pDes - datas[leg].p);
137  footForce +=
138  commands[leg].kdCartesian * (commands[leg].vDes - datas[leg].v);
139 
140  // Torque
141  legTorque += datas[leg].J.transpose() * footForce;
142 
143  // set command:
144  spiCommand->tau_abad_ff[leg] = legTorque(0);
145  spiCommand->tau_hip_ff[leg] = legTorque(1);
146  spiCommand->tau_knee_ff[leg] = legTorque(2);
147 
148  // joint space pd
149  // joint space PD
150  spiCommand->kd_abad[leg] = commands[leg].kdJoint(0, 0);
151  spiCommand->kd_hip[leg] = commands[leg].kdJoint(1, 1);
152  spiCommand->kd_knee[leg] = commands[leg].kdJoint(2, 2);
153 
154  spiCommand->kp_abad[leg] = commands[leg].kpJoint(0, 0);
155  spiCommand->kp_hip[leg] = commands[leg].kpJoint(1, 1);
156  spiCommand->kp_knee[leg] = commands[leg].kpJoint(2, 2);
157 
158  spiCommand->q_des_abad[leg] = commands[leg].qDes(0);
159  spiCommand->q_des_hip[leg] = commands[leg].qDes(1);
160  spiCommand->q_des_knee[leg] = commands[leg].qDes(2);
161 
162  spiCommand->qd_des_abad[leg] = commands[leg].qdDes(0);
163  spiCommand->qd_des_hip[leg] = commands[leg].qdDes(1);
164  spiCommand->qd_des_knee[leg] = commands[leg].qdDes(2);
165 
166  // estimate torque
167  datas[leg].tauEstimate =
168  legTorque +
169  commands[leg].kpJoint * (commands[leg].qDes - datas[leg].q) +
170  commands[leg].kdJoint * (commands[leg].qdDes - datas[leg].qd);
171 
172  spiCommand->flags[leg] = _legsEnabled ? 1 : 0;
173  }
174 }
175 
179 template <typename T>
181  for (int leg = 0; leg < 4; leg++) {
182  Vec3<T> tauFF = commands[leg].tauFeedForward.template cast<T>();
183  tauFF += commands[leg].kpJoint * (commands[leg].qDes - datas[leg].q) +
184  commands[leg].kdJoint * (commands[leg].qdDes - datas[leg].qd);
185 
186  for (int joint = 0; joint < 3; joint++) {
187  tiBoardCommand[leg].kp[joint] = commands[leg].kpCartesian(joint, joint);
188  tiBoardCommand[leg].kd[joint] = commands[leg].kdCartesian(joint, joint);
189  tiBoardCommand[leg].tau_ff[joint] = tauFF[joint];
190  tiBoardCommand[leg].position_des[joint] = commands[leg].pDes[joint];
191  tiBoardCommand[leg].velocity_des[joint] = commands[leg].vDes[joint];
192  tiBoardCommand[leg].force_ff[joint] =
193  commands[leg].forceFeedForward[joint];
194  }
195 
196  tiBoardCommand[leg].enable = _legsEnabled ? 1 : 0;
197  tiBoardCommand[leg].max_torque = _maxTorque;
198  }
199 }
200 
201 template<typename T>
202 void LegController<T>::setLcm(leg_control_data_lcmt *lcmData, leg_control_command_lcmt *lcmCommand) {
203  for(int leg = 0; leg < 4; leg++) {
204  for(int axis = 0; axis < 3; axis++) {
205  int idx = leg*3 + axis;
206  lcmData->q[idx] = datas[leg].q[axis];
207  lcmData->qd[idx] = datas[leg].qd[axis];
208  lcmData->p[idx] = datas[leg].p[axis];
209  lcmData->v[idx] = datas[leg].v[axis];
210  lcmData->tau_est[idx] = datas[leg].tauEstimate[axis];
211 
212  lcmCommand->tau_ff[idx] = commands[leg].tauFeedForward[axis];
213  lcmCommand->f_ff[idx] = commands[leg].forceFeedForward[axis];
214  lcmCommand->q_des[idx] = commands[leg].qDes[axis];
215  lcmCommand->qd_des[idx] = commands[leg].qdDes[axis];
216  lcmCommand->p_des[idx] = commands[leg].pDes[axis];
217  lcmCommand->v_des[idx] = commands[leg].vDes[axis];
218  lcmCommand->kp_cartesian[idx] = commands[leg].kpCartesian(axis, axis);
219  lcmCommand->kd_cartesian[idx] = commands[leg].kdCartesian(axis, axis);
220  lcmCommand->kp_joint[idx] = commands[leg].kpJoint(axis, axis);
221  lcmCommand->kd_joint[idx] = commands[leg].kdJoint(axis, axis);
222  }
223  }
224 }
225 
226 template struct LegControllerCommand<double>;
227 template struct LegControllerCommand<float>;
228 
229 template struct LegControllerData<double>;
230 template struct LegControllerData<float>;
231 
232 template class LegController<double>;
233 template class LegController<float>;
234 
239 template <typename T>
241  Vec3<T>* p, int leg) {
242  T l1 = quad._abadLinkLength;
243  T l2 = quad._hipLinkLength;
244  T l3 = quad._kneeLinkLength;
245  T sideSign = quad.getSideSign(leg);
246 
247  T s1 = std::sin(q(0));
248  T s2 = std::sin(q(1));
249  T s3 = std::sin(q(2));
250 
251  T c1 = std::cos(q(0));
252  T c2 = std::cos(q(1));
253  T c3 = std::cos(q(2));
254 
255  T c23 = c2 * c3 - s2 * s3;
256  T s23 = s2 * c3 + c2 * s3;
257 
258  if (J) {
259  J->operator()(0, 0) = 0;
260  J->operator()(0, 1) = l3 * c23 + l2 * c2;
261  J->operator()(0, 2) = l3 * c23;
262  J->operator()(1, 0) = l3 * c1 * c23 + l2 * c1 * c2 - l1 * sideSign * s1;
263  J->operator()(1, 1) = -l3 * s1 * s23 - l2 * s1 * s2;
264  J->operator()(1, 2) = -l3 * s1 * s23;
265  J->operator()(2, 0) = l3 * s1 * c23 + l2 * c2 * s1 + l1 * sideSign * c1;
266  J->operator()(2, 1) = l3 * c1 * s23 + l2 * c1 * s2;
267  J->operator()(2, 2) = l3 * c1 * s23;
268  }
269 
270  if (p) {
271  p->operator()(0) = l3 * s23 + l2 * s2;
272  p->operator()(1) = l1 * sideSign * c1 + l3 * (s1 * c23) + l2 * c2 * s1;
273  p->operator()(2) = l1 * sideSign * s1 - l3 * (c1 * c23) - l2 * c1 * c2;
274  }
275 }
276 
278  Vec3<double>& q,
279  Mat3<double>* J,
280  Vec3<double>* p, int leg);
282  Vec3<float>& q,
283  Mat3<float>* J,
284  Vec3<float>* p, int leg);
float q_knee[4]
Definition: SpineBoard.h:37
T _hipLinkLength
Definition: Quadruped.h:62
float qd_des_knee[4]
Definition: SpineBoard.h:17
typename Eigen::Matrix< T, 3, 3 > Mat3
Definition: cppTypes.h:54
void setLcm(leg_control_data_lcmt *data, leg_control_command_lcmt *command)
typename Eigen::Matrix< T, 3, 1 > Vec3
Definition: cppTypes.h:26
float tau_abad_ff[4]
Definition: SpineBoard.h:27
float kd_hip[4]
Definition: SpineBoard.h:24
T _kneeLinkLength
Definition: Quadruped.h:62
float kd_knee[4]
Definition: SpineBoard.h:25
float q_hip[4]
Definition: SpineBoard.h:36
float q_des_knee[4]
Definition: SpineBoard.h:13
float kd_abad[4]
Definition: SpineBoard.h:23
float tau_knee_ff[4]
Definition: SpineBoard.h:29
float q_des_abad[4]
Definition: SpineBoard.h:11
float kp_knee[4]
Definition: SpineBoard.h:21
float q_des_hip[4]
Definition: SpineBoard.h:12
float qd_des_hip[4]
Definition: SpineBoard.h:16
void updateCommand(SpiCommand *spiCommand)
static T getSideSign(int leg)
Definition: Quadruped.h:74
int32_t flags[4]
Definition: SpineBoard.h:31
float tau[3]
float velocity_des[3]
float velocity[3]
template void computeLegJacobianAndPosition< float >(Quadruped< float > &quad, Vec3< float > &q, Mat3< float > *J, Vec3< float > *p, int leg)
void updateData(const SpiData *spiData)
float kp_abad[4]
Definition: SpineBoard.h:19
float kp_hip[4]
Definition: SpineBoard.h:20
float q_abad[4]
Definition: SpineBoard.h:35
template void computeLegJacobianAndPosition< double >(Quadruped< double > &quad, Vec3< double > &q, Mat3< double > *J, Vec3< double > *p, int leg)
Common Leg Control Interface and Leg Control Algorithms.
float qd_abad[4]
Definition: SpineBoard.h:38
float tau_hip_ff[4]
Definition: SpineBoard.h:28
float position[3]
T _abadLinkLength
Definition: Quadruped.h:62
RobotType
Definition: cppTypes.h:120
float qd_des_abad[4]
Definition: SpineBoard.h:15
void edampCommand(RobotType robot, T gain)
void computeLegJacobianAndPosition(Quadruped< T > &quad, Vec3< T > &q, Mat3< T > *J, Vec3< T > *p, int leg)
float qd_hip[4]
Definition: SpineBoard.h:39
float position_des[3]
float qd_knee[4]
Definition: SpineBoard.h:40