1
1
2
2
#include < Arduino.h>
3
+ #include < math.h>
3
4
#include " QuadrupedRobot.h"
4
5
5
6
/* *
@@ -117,48 +118,165 @@ void QuadrupedRobot::servo_move(float *angs_ptr)
117
118
{
118
119
timenow = millis ();
119
120
joint_angs_now[i] += joint_degs_speed[i] * (timenow - servo_time[i]);
121
+ servo_time[i] = timenow; // update servo time
120
122
}
121
- servo_write_angs (joint_angs_now);
123
+ servo_write_angs (joint_angs_now, false );
122
124
timenow = millis ();
123
125
}
124
126
// last run to assure that all servo has been desired position
125
127
for (size_t i = 0 ; i < DOF; i++)
126
128
{
127
- servo_write_angs (angs_ptr);
129
+ servo_write_angs (angs_ptr, false );
128
130
}
129
-
130
-
131
131
}
132
132
133
133
/* *
134
134
* Servo Write Current Angles
135
135
* Current Angles is in Callibrated Coordinate,
136
136
* which should be transfered to real angle degrees before using.
137
137
*/
138
- void QuadrupedRobot::servo_write_angs (float *angs_ptr)
138
+ void QuadrupedRobot::servo_write_angs (float *angs_ptr, bool is_in_degrees )
139
139
{
140
140
float real_ang{};
141
141
float pulsewidth{};
142
+ float ang_in_degree{};
142
143
for (size_t i = 0 ; i < DOF; i++)
143
144
{
144
- real_ang = init_servo_deg[i] + servo_dir[i] * angs_ptr[i];
145
+ if (is_in_degrees){
146
+ ang_in_degree = angs_ptr[i];
147
+ } else {
148
+ ang_in_degree = angs_ptr[i] * 180 / M_PI;
149
+ }
150
+ real_ang = init_servo_deg[i] + servo_dir[i] * ang_in_degree;
145
151
pulsewidth = 500 + real_ang / 90.0 * 1000 ;
146
152
if (!servos_ptr[i]->attached ())
147
153
{
148
154
servos_ptr[i]->attach (servo_pins[i], SERVOMIN, SERVOMAX);
149
155
}
150
156
servos_ptr[i]->writeMicroseconds (pulsewidth);
151
157
// update current angles buffer
152
- joint_angs_pre[i] = angs_ptr[i];
158
+ if (is_in_degrees) {
159
+ joint_angs_pre[i] = angs_ptr[i] * M_PI / 180 ;
160
+ } else {
161
+ joint_angs_pre[i] = angs_ptr[i];
162
+ }
163
+ }
164
+ }
165
+
166
+ /* *
167
+ * Moving body by moving the feet in opposite direction
168
+ * Body Frame xyz
169
+ */
170
+ void QuadrupedRobot::body_xyz (float x, float y, float z)
171
+ {
172
+ for (size_t i = 0 ; i < 4 ; i++)
173
+ {
174
+ foot_pos[3 * i] = -x;
175
+ foot_pos[3 * i + 1 ] = -y;
176
+ foot_pos[3 * i + 2 ] = -z;
153
177
}
178
+ inverse_kinematics ();
179
+ servo_move (joint_angs_new);
180
+ }
181
+
182
+ /* *
183
+ * Calculate the joint angles by foot positions
184
+ */
185
+ void QuadrupedRobot::inverse_kinematics ()
186
+ {
187
+ // FL 0, 1, 2
188
+ joint_angs_new[0 ] = gamma_left (foot_pos[1 ], foot_pos[2 ]); // HipX
189
+ vlegs_len[0 ] = vleg_left (foot_pos[0 ], foot_pos[1 ], joint_angs_new[0 ]);
190
+ joint_angs_new[2 ] = beta_front (vlegs_len[0 ]);
191
+ joint_angs_new[1 ] = alfa_front (foot_pos[0 ], joint_angs_new[2 ], vlegs_len[0 ]);
192
+ // FR 3, 4, 5
193
+ joint_angs_new[3 ] = gamma_right (foot_pos[4 ], foot_pos[5 ]);
194
+ vlegs_len[3 ] = vleg_right (foot_pos[3 ], foot_pos[4 ], joint_angs_new[3 ]);
195
+ joint_angs_new[5 ] = beta_front (vlegs_len[3 ]);
196
+ joint_angs_new[4 ] = alfa_front (foot_pos[3 ], joint_angs_new[5 ], vlegs_len[3 ]);
197
+ // RR 6, 7, 8
198
+ joint_angs_new[6 ] = gamma_right (foot_pos[7 ], foot_pos[8 ]);
199
+ vlegs_len[6 ] = vleg_right (foot_pos[6 ], foot_pos[7 ], joint_angs_new[6 ]);
200
+ joint_angs_new[8 ] = beta_rear (vlegs_len[6 ]);
201
+ joint_angs_new[7 ] = alfa_rear (foot_pos[6 ], joint_angs_new[8 ], vlegs_len[6 ]);
202
+ // RL 9, 10, 11
203
+ joint_angs_new[9 ] = gamma_left (foot_pos[10 ], foot_pos[11 ]);
204
+ vlegs_len[9 ] = vleg_left (foot_pos[9 ], foot_pos[10 ], joint_angs_new[9 ]);
205
+ joint_angs_new[11 ] = beta_rear (vlegs_len[9 ]);
206
+ joint_angs_new[10 ] = alfa_rear (foot_pos[9 ], joint_angs_new[11 ], vlegs_len[9 ]);
207
+ }
208
+
209
+ // Gamma: Hip Z angle
F438
code>
210
+ float QuadrupedRobot::gamma_left (float dy, float dz)
211
+ {
212
+ float res = atan ((toe_out0 - dz) / (height0 - dy)) - gamma0;
213
+ return res;
214
+ }
215
+
216
+ float QuadrupedRobot::gamma_right (float dy, float dz)
217
+ {
218
+ float res = gamma0 - atan ((toe_out0 + dz) / (height0 - dy));
219
+ return res;
220
+ }
221
+ // virtual leg length
222
+ float QuadrupedRobot::vleg_left (float dx, float dy, float gamma)
223
+ {
224
+ float res = sqrt (pow (vleg_len0 - (dy / cos (gamma0 + gamma)), 2 ) + pow (dx, 2 ));
225
+ if (res > thigh + calf)
226
+ res = thigh + calf;
227
+ return res;
228
+ }
229
+
230
+ float QuadrupedRobot::vleg_right (float dx, float dy, float gamma)
231
+ {
232
+ float res = sqrt (pow (vleg_len0 - (dy / cos (gamma0 - gamma)), 2 ) + pow (dx, 2 ));
233
+ if (res > thigh + calf)
234
+ res = thigh + calf;
235
+ return res;
236
+ }
237
+
238
+ float QuadrupedRobot::beta_front (float vleg_len)
239
+ {
240
+ float res = M_PI - acos (
241
+ (thigh * thigh + calf * calf - vleg_len * vleg_len) /
242
+ (2 * thigh * calf));
243
+ return res;
244
+ }
245
+
246
+ float QuadrupedRobot::beta_rear (float vleg_len)
247
+ {
248
+ float res = acos (
249
+ (thigh * thigh + calf * calf - vleg_len * vleg_len) /
250
+ (2 * thigh * calf)) - M_PI;
251
+ return res;
252
+ }
253
+
254
+ float QuadrupedRobot::alfa_front (float dx, float beta, float vleg_len)
255
+ {
256
+ float res = asin (dx / vleg_len);
257
+ res -= acos (
258
+ (thigh * thigh + vleg_len * vleg_len - calf * calf) /
259
+ (2 * thigh * vleg_len)
260
+ );
261
+ return res;
262
+ }
263
+
264
+ float QuadrupedRobot::alfa_rear (float dx, float beta, float vleg_len)
265
+ {
266
+ float res = asin (dx / vleg_len);
267
+ res += acos (
268
+ (thigh * thigh + vleg_len * vleg_len - calf * calf) /
269
+ (2 * thigh * vleg_len)
270
+ );
271
+ return res;
154
272
}
155
273
156
274
/* *
157
275
* Only used for adjusting legs
158
276
*/
159
277
void QuadrupedRobot::adjust ()
160
278
{
161
- servo_write_angs (adjust_angs);
279
+ servo_write_angs (adjust_angs, true );
162
280
clear_cmd ();
163
281
}
164
282
@@ -168,7 +286,7 @@ void QuadrupedRobot::adjust()
168
286
*/
169
287
void QuadrupedRobot::bot_stand ()
170
288
{
171
- servo_write_angs (stand_angs);
289
+ servo_write_angs (stand_angs, true );
172
290
clear_cmd ();
173
291
}
174
292
@@ -178,7 +296,7 @@ void QuadrupedRobot::bot_stand()
178
296
*/
179
297
void QuadrupedRobot::bot_rest ()
180
298
{
181
- servo_write_angs (rest_angs);
299
+ servo_write_angs (rest_angs, true );
182
300
clear_cmd ();
183
301
}
184
302
@@ -188,7 +306,9 @@ void QuadrupedRobot::bot_rest()
188
306
*/
189
307
void QuadrupedRobot::bot_walk ()
190
308
{
191
- Serial.print (" walk" );
309
+ Serial.println (" walk" );
310
+ body_xyz (0 , 0 , 0 );
311
+ clear_cmd ();
192
312
}
193
313
194
314
QuadrupedRobot::~QuadrupedRobot ()
0 commit comments