11 #include <eigen3/Eigen/Dense> 49 for (
auto& cmd : commands) {
65 for (
int leg = 0; leg < 4; leg++) {
66 for (
int axis = 0; axis < 3; axis++) {
67 commands[leg].kdCartesian(axis, axis) = gain;
71 for (
int leg = 0; leg < 4; leg++) {
72 for (
int axis = 0; axis < 3; axis++) {
73 commands[leg].kdJoint(axis, axis) = gain;
84 for (
int leg = 0; leg < 4; leg++) {
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];
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];
96 computeLegJacobianAndPosition<T>(_quadruped, datas[leg].q, &(datas[leg].J),
97 &(datas[leg].p), leg);
100 datas[leg].v = datas[leg].J * datas[leg].qd;
107 template <
typename T>
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,
117 datas[leg].tauEstimate[joint] = tiBoardData[leg].
tau[joint];
125 template <
typename T>
127 for (
int leg = 0; leg < 4; leg++) {
129 Vec3<T> legTorque = commands[leg].tauFeedForward;
132 Vec3<T> footForce = commands[leg].forceFeedForward;
136 commands[leg].kpCartesian * (commands[leg].pDes - datas[leg].p);
138 commands[leg].kdCartesian * (commands[leg].vDes - datas[leg].v);
141 legTorque += datas[leg].J.transpose() * footForce;
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);
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);
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);
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);
167 datas[leg].tauEstimate =
169 commands[leg].kpJoint * (commands[leg].qDes - datas[leg].q) +
170 commands[leg].kdJoint * (commands[leg].qdDes - datas[leg].qd);
172 spiCommand->
flags[leg] = _legsEnabled ? 1 : 0;
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);
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];
196 tiBoardCommand[leg].
enable = _legsEnabled ? 1 : 0;
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];
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);
239 template <
typename T>
247 T s1 = std::sin(q(0));
248 T s2 = std::sin(q(1));
249 T s3 = std::sin(q(2));
251 T c1 = std::cos(q(0));
252 T c2 = std::cos(q(1));
253 T c3 = std::cos(q(2));
255 T c23 = c2 * c3 - s2 * s3;
256 T s23 = s2 * c3 + c2 * s3;
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;
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;
typename Eigen::Matrix< T, 3, 3 > Mat3
void setLcm(leg_control_data_lcmt *data, leg_control_command_lcmt *command)
typename Eigen::Matrix< T, 3, 1 > Vec3
void updateCommand(SpiCommand *spiCommand)
static T getSideSign(int leg)
template void computeLegJacobianAndPosition< float >(Quadruped< float > &quad, Vec3< float > &q, Mat3< float > *J, Vec3< float > *p, int leg)
void updateData(const SpiData *spiData)
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.
void edampCommand(RobotType robot, T gain)
void computeLegJacobianAndPosition(Quadruped< T > &quad, Vec3< T > &q, Mat3< T > *J, Vec3< T > *p, int leg)