Cheetah Software  1.0
LegController< T > Class Template Reference

#include <LegController.h>

+ Inheritance diagram for LegController< T >:
+ Collaboration diagram for LegController< T >:

Public Member Functions

 LegController (Quadruped< T > &quad)
 
void zeroCommand ()
 
void edampCommand (RobotType robot, T gain)
 
void updateData (const SpiData *spiData)
 
void updateData (const TiBoardData *tiBoardData)
 
void updateCommand (SpiCommand *spiCommand)
 
void updateCommand (TiBoardCommand *tiBoardCommand)
 
void setEnabled (bool enabled)
 
void setLcm (leg_control_data_lcmt *data, leg_control_command_lcmt *command)
 
void setMaxTorqueCheetah3 (T tau)
 

Public Attributes

LegControllerCommand< T > commands [4]
 
LegControllerData< T > datas [4]
 
Quadruped< T > & _quadruped
 
bool _legsEnabled = false
 
_maxTorque = 0
 

Detailed Description

template<typename T>
class LegController< T >

Definition at line 49 of file LegController.h.

Constructor & Destructor Documentation

template<typename T>
LegController< T >::LegController ( Quadruped< T > &  quad)
inline

Definition at line 51 of file LegController.h.

51  : _quadruped(quad) {
52  for (auto& data : datas) data.setQuadruped(_quadruped);
53  }
LegControllerData< T > datas[4]
Definition: LegController.h:70
Quadruped< T > & _quadruped
Definition: LegController.h:71

Member Function Documentation

template<typename T>
void LegController< T >::edampCommand ( RobotType  robot,
gain 
)

Set the leg to edamp. This overwrites all command data and generates an emergency damp command using the given gain. For the mini-cheetah, the edamp gain is Nm/(rad/s), and for the Cheetah 3 it is N/m. You still must call updateCommand for this command to end up in the low-level command data!

Definition at line 62 of file LegController.cpp.

References CHEETAH_3.

62  {
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 }
LegControllerCommand< T > commands[4]
Definition: LegController.h:69
template<typename T>
void LegController< T >::setEnabled ( bool  enabled)
inline

Definition at line 61 of file LegController.h.

61 { _legsEnabled = enabled; };

+ Here is the caller graph for this function:

template<typename T >
void LegController< T >::setLcm ( leg_control_data_lcmt *  data,
leg_control_command_lcmt *  command 
)

Definition at line 202 of file LegController.cpp.

202  {
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 }
LegControllerData< T > datas[4]
Definition: LegController.h:70
LegControllerCommand< T > commands[4]
Definition: LegController.h:69

+ Here is the caller graph for this function:

template<typename T>
void LegController< T >::setMaxTorqueCheetah3 ( tau)
inline

Set the maximum torque. This only works on cheetah 3!

Definition at line 67 of file LegController.h.

67 { _maxTorque = tau; }

+ Here is the caller graph for this function:

template<typename T >
void LegController< T >::updateCommand ( SpiCommand spiCommand)

Update the "leg command" for the SPIne board message

Definition at line 126 of file LegController.cpp.

References SpiCommand::flags, SpiCommand::kd_abad, SpiCommand::kd_hip, SpiCommand::kd_knee, SpiCommand::kp_abad, SpiCommand::kp_hip, SpiCommand::kp_knee, SpiCommand::q_des_abad, SpiCommand::q_des_hip, SpiCommand::q_des_knee, SpiCommand::qd_des_abad, SpiCommand::qd_des_hip, SpiCommand::qd_des_knee, SpiCommand::tau_abad_ff, SpiCommand::tau_hip_ff, and SpiCommand::tau_knee_ff.

126  {
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 }
float qd_des_knee[4]
Definition: SpineBoard.h:17
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
float kd_knee[4]
Definition: SpineBoard.h:25
float q_des_knee[4]
Definition: SpineBoard.h:13
float kd_abad[4]
Definition: SpineBoard.h:23
LegControllerData< T > datas[4]
Definition: LegController.h:70
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
int32_t flags[4]
Definition: SpineBoard.h:31
float kp_abad[4]
Definition: SpineBoard.h:19
float kp_hip[4]
Definition: SpineBoard.h:20
float tau_hip_ff[4]
Definition: SpineBoard.h:28
float qd_des_abad[4]
Definition: SpineBoard.h:15
LegControllerCommand< T > commands[4]
Definition: LegController.h:69

+ Here is the caller graph for this function:

template<typename T >
void LegController< T >::updateCommand ( TiBoardCommand tiBoardCommand)

Update the "leg command" for the TI Board

Definition at line 180 of file LegController.cpp.

References TiBoardCommand::enable, TiBoardCommand::force_ff, TiBoardCommand::kd, TiBoardCommand::kp, TiBoardCommand::max_torque, TiBoardCommand::position_des, TiBoardCommand::tau_ff, and TiBoardCommand::velocity_des.

180  {
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 }
typename Eigen::Matrix< T, 3, 1 > Vec3
Definition: cppTypes.h:26
LegControllerData< T > datas[4]
Definition: LegController.h:70
float velocity_des[3]
float position_des[3]
LegControllerCommand< T > commands[4]
Definition: LegController.h:69
template<typename T >
void LegController< T >::updateData ( const SpiData spiData)

Update the "leg data" from a SPIne board message

Definition at line 83 of file LegController.cpp.

References SpiData::q_abad, SpiData::q_hip, SpiData::q_knee, SpiData::qd_abad, SpiData::qd_hip, and SpiData::qd_knee.

83  {
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 }
float q_knee[4]
Definition: SpineBoard.h:37
float q_hip[4]
Definition: SpineBoard.h:36
LegControllerData< T > datas[4]
Definition: LegController.h:70
Quadruped< T > & _quadruped
Definition: LegController.h:71
float q_abad[4]
Definition: SpineBoard.h:35
float qd_abad[4]
Definition: SpineBoard.h:38
float qd_hip[4]
Definition: SpineBoard.h:39
float qd_knee[4]
Definition: SpineBoard.h:40

+ Here is the caller graph for this function:

template<typename T >
void LegController< T >::updateData ( const TiBoardData tiBoardData)

Update the "leg data" from a TI Board message

Definition at line 108 of file LegController.cpp.

References TiBoardData::dq, TiBoardData::position, TiBoardData::q, TiBoardData::tau, and TiBoardData::velocity.

108  {
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 }
LegControllerData< T > datas[4]
Definition: LegController.h:70
float tau[3]
Quadruped< T > & _quadruped
Definition: LegController.h:71
float velocity[3]
float position[3]
template<typename T >
void LegController< T >::zeroCommand ( )

Zero all leg commands. This should be run before any control code, so if the control code is confused and doesn't change the leg command, the legs won't remember the last command.

Definition at line 48 of file LegController.cpp.

48  {
49  for (auto& cmd : commands) {
50  cmd.zero();
51  }
52  _legsEnabled = false;
53 }
LegControllerCommand< T > commands[4]
Definition: LegController.h:69

+ Here is the caller graph for this function:

Member Data Documentation

template<typename T>
bool LegController< T >::_legsEnabled = false

Definition at line 72 of file LegController.h.

template<typename T>
T LegController< T >::_maxTorque = 0

Definition at line 73 of file LegController.h.

template<typename T>
Quadruped<T>& LegController< T >::_quadruped

Definition at line 71 of file LegController.h.

template<typename T>
LegControllerCommand<T> LegController< T >::commands[4]

Definition at line 69 of file LegController.h.

template<typename T>
LegControllerData<T> LegController< T >::datas[4]

Definition at line 70 of file LegController.h.


The documentation for this class was generated from the following files: