51 |
51 |
|
52 |
52 |
//! destructor
|
53 |
53 |
iCubJointInterface::~iCubJointInterface(){
|
|
54 |
//stop velocity controller on exit
|
|
55 |
yarp_ivel_->stop();
|
54 |
56 |
}
|
55 |
57 |
|
56 |
58 |
//! init the controller that allows to write target angles or velocities
|
... | ... | |
62 |
64 |
|
63 |
65 |
// set ref acceleration to a value for all axes:
|
64 |
66 |
yarp_commands_.resize(number_of_joints);
|
65 |
|
yarp_commands_=300.0;
|
|
67 |
yarp_commands_ = 1e6;
|
66 |
68 |
yarp_ivel_->setRefAccelerations(yarp_commands_.data());
|
67 |
69 |
yarp_ivel_->setVelocityMode();
|
68 |
70 |
}
|
... | ... | |
101 |
103 |
enum_id_bimap_t::const_iterator it;
|
102 |
104 |
for(it = enum_id_bimap.begin(); it != enum_id_bimap.end(); ++it) {
|
103 |
105 |
int id = it->left;
|
104 |
|
pv_mix_pid_p_[id] = 4.5;
|
|
106 |
pv_mix_pid_p_[id] = 15.5;
|
105 |
107 |
pv_mix_pid_d_[id] = 0.3;
|
106 |
108 |
pv_mix_last_error_[id] = 0.0;
|
107 |
109 |
}
|
... | ... | |
149 |
151 |
// calculate target velocities
|
150 |
152 |
// for now just use the same velocity for pan and vergence
|
151 |
153 |
float target_velocity_pan = (target_velocity_left + target_velocity_right) / 2.0;
|
152 |
|
float target_velocity_tilt = target_velocity_pan;
|
|
154 |
float target_velocity_vergence = target_velocity_left - target_velocity_right;
|
153 |
155 |
|
154 |
156 |
store_icub_joint_target(ICUB_ID_EYES_PAN,
|
155 |
157 |
target_position_pan, target_velocity_pan);
|
156 |
158 |
store_icub_joint_target(ICUB_ID_EYES_VERGENCE,
|
157 |
|
target_position_vergence, target_velocity_tilt);
|
|
159 |
target_position_vergence, target_velocity_vergence);
|
158 |
160 |
}else{
|
159 |
161 |
// convert to icub joint id
|
160 |
162 |
int icub_id = convert_humotion_jointid_to_icub(humotion_id);
|
... | ... | |
170 |
172 |
void iCubJointInterface::store_icub_joint_target(int icub_id, float position, float velocity) {
|
171 |
173 |
cout << "store_icub_joint_target(" << icub_id << ", " << position << ", ..)\n";
|
172 |
174 |
|
173 |
|
if (icub_id == ICUB_ID_NECK_PAN) {
|
|
175 |
if ((icub_id == ICUB_ID_NECK_PAN) || (icub_id == ICUB_ID_EYES_VERGENCE)){
|
174 |
176 |
// icub uses an inverted neck pan specification
|
175 |
177 |
position = -position;
|
176 |
178 |
velocity = -velocity;
|
... | ... | |
191 |
193 |
// fetch the target velocity
|
192 |
194 |
float target_velocity = target_velocity_[icub_id];
|
193 |
195 |
|
194 |
|
float vmax = 150.0;
|
|
196 |
float vmax = 350.0;
|
195 |
197 |
if (target_velocity > vmax) target_velocity = vmax;
|
196 |
198 |
if (target_velocity < -vmax) target_velocity = -vmax;
|
197 |
199 |
|
198 |
200 |
//execute:
|
199 |
201 |
//ivel->velocityMove(id, speed);
|
200 |
|
/*if ((icub_id != ICUB_ID_NECK_PAN) &&
|
201 |
|
(icub_id != ICUB_ID_EYES_BOTH_UD) &&
|
202 |
|
(icub_id != ICUB_ID_NECK_TILT) &&
|
203 |
|
(icub_id != ICUB_ID_EYES_BOTH_UD) &&
|
204 |
|
(icub_id != ICUB_ID_NECK_TILT)) {
|
|
202 |
if ((icub_id != ICUB_ID_NECK_PAN)
|
|
203 |
//&& (icub_id != ICUB_ID_EYES_BOTH_UD)
|
|
204 |
//&& (icub_id != ICUB_ID_NECK_TILT)
|
|
205 |
&& (icub_id != ICUB_ID_EYES_PAN)
|
|
206 |
&& (icub_id != ICUB_ID_EYES_VERGENCE)
|
|
207 |
//&& (icub_id != ICUB_ID_NECK_TILT)
|
|
208 |
){
|
205 |
209 |
// limit to some joints for debugging...
|
206 |
210 |
return;
|
207 |
|
}*/
|
|
211 |
}
|
208 |
212 |
|
209 |
213 |
// we now add a pd control loop for velocity moves in order to handle position errors
|
210 |
214 |
// TODO: add position interpolation into future. this requires to enable the velocity
|
... | ... | |
214 |
218 |
// first: fetch the timstamp of the last known position
|
215 |
219 |
humotion::Timestamp data_ts = get_ts_position(humotion_id).get_last_timestamp();
|
216 |
220 |
|
|
221 |
// fetch current position & velocity
|
|
222 |
float current_position = get_ts_position(humotion_id).get_interpolated_value(data_ts);
|
|
223 |
float current_velocity = get_ts_speed(humotion_id).get_interpolated_value(data_ts);
|
|
224 |
|
|
225 |
// the icub has a combined eye pan actuator, therefore
|
|
226 |
// we have to calculate pan angle and vergence based on the left and right target angles:
|
|
227 |
if (icub_id == ICUB_ID_EYES_PAN) {
|
|
228 |
// fetch timestamp
|
|
229 |
data_ts = get_ts_position(ID_EYES_LEFT_LR).get_last_timestamp();
|
|
230 |
|
|
231 |
// get the left and right positions
|
|
232 |
float pos_left = get_ts_position(ID_EYES_LEFT_LR).get_interpolated_value(data_ts);
|
|
233 |
float pos_right = get_ts_position(ID_EYES_RIGHT_LR).get_interpolated_value(data_ts);
|
|
234 |
current_position = (pos_left + pos_right) / 2.0;
|
|
235 |
|
|
236 |
// same for velocities:
|
|
237 |
float vel_left = get_ts_speed(ID_EYES_LEFT_LR).get_interpolated_value(data_ts);
|
|
238 |
float vel_right = get_ts_speed(ID_EYES_RIGHT_LR).get_interpolated_value(data_ts);
|
|
239 |
current_velocity = (vel_left + vel_right) / 2.0;
|
|
240 |
|
|
241 |
}else if (icub_id == ICUB_ID_EYES_VERGENCE) {
|
|
242 |
// fetch timestamp
|
|
243 |
data_ts = get_ts_position(ID_EYES_LEFT_LR).get_last_timestamp();
|
|
244 |
|
|
245 |
// get the left and right positions
|
|
246 |
float pos_left = get_ts_position(ID_EYES_LEFT_LR).get_interpolated_value(data_ts);
|
|
247 |
float pos_right = get_ts_position(ID_EYES_RIGHT_LR).get_interpolated_value(data_ts);
|
|
248 |
|
|
249 |
current_position = pos_left - pos_right;
|
|
250 |
|
|
251 |
// same for velocities:
|
|
252 |
float vel_left = get_ts_speed(ID_EYES_LEFT_LR).get_interpolated_value(data_ts);
|
|
253 |
float vel_right = get_ts_speed(ID_EYES_RIGHT_LR).get_interpolated_value(data_ts);
|
|
254 |
current_velocity = (vel_left - vel_right);
|
|
255 |
|
|
256 |
}
|
|
257 |
|
217 |
258 |
// calculate position error:
|
218 |
|
float position_error = target_angle_[icub_id] - get_ts_position(humotion_id).get_interpolated_value(data_ts);
|
|
259 |
float position_error = target_angle_[icub_id] - current_position;
|
219 |
260 |
|
220 |
261 |
// calculate d term
|
221 |
262 |
float error_d = (position_error - pv_mix_last_error_[icub_id]) / (framerate*1000.0);
|
... | ... | |
226 |
267 |
+ pv_mix_pid_p_[icub_id]*error_d
|
227 |
268 |
+ target_velocity;
|
228 |
269 |
|
|
270 |
|
|
271 |
//if (icub_id == ICUB_ID_EYES_VERGENCE) { target_velocity = 0.0; pv_mix_velocity = 0.0;}
|
|
272 |
|
229 |
273 |
cout << "\n"
|
230 |
|
<< get_ts_position(humotion_id).get_interpolated_value(data_ts) << " "
|
|
274 |
<< current_position << " "
|
231 |
275 |
<< target_angle_[icub_id] << " "
|
232 |
|
<< 123.4 << " "
|
|
276 |
<< current_velocity << " "
|
233 |
277 |
<< pv_mix_velocity << " "
|
234 |
278 |
<< target_velocity << " "
|
235 |
279 |
<< position_error << " "
|
236 |
|
<< icub_id << " PID\n";
|
|
280 |
<< " PID" << icub_id << "\n";
|
237 |
281 |
|
238 |
282 |
// execute velocity move
|
239 |
|
yarp_ivel_->velocityMove(icub_id, pv_mix_velocity);
|
|
283 |
bool success;
|
|
284 |
int count = 0;
|
|
285 |
do{
|
|
286 |
success = yarp_ivel_->velocityMove(icub_id, pv_mix_velocity);
|
|
287 |
if (count++ >= 10 ) {
|
|
288 |
cerr << "ERROR: failed to send velocity move command! gave up after 10 trials\n";
|
|
289 |
yarp_ivel_->stop();
|
|
290 |
exit(EXIT_FAILURE);
|
|
291 |
}
|
|
292 |
} while(!success);
|
240 |
293 |
}
|
241 |
294 |
|
242 |
295 |
//! actually execute the scheduled motion commands
|
... | ... | |
246 |
299 |
for(int i=ICUB_ID_NECK_TILT; i<=ICUB_ID_EYES_VERGENCE; i++){
|
247 |
300 |
set_target_in_velocitymode(i);
|
248 |
301 |
}
|
249 |
|
|
|
302 |
/*
|
250 |
303 |
// eyelids: unfortuantely the icub has only 1dof for eyelids
|
251 |
304 |
// therefore we can only use an opening value
|
252 |
305 |
float opening_left = target_angle_[ICUB_ID_EYES_LEFT_LID_UPPER]
|
... | ... | |
263 |
316 |
|
264 |
317 |
//mouth
|
265 |
318 |
face_interface_->set_mouth(target_angle_);
|
266 |
|
|
|
319 |
*/
|
267 |
320 |
|
268 |
321 |
//store joint values which we do not handle on icub here:
|
269 |
322 |
double timestamp = humotion::Timestamp::now().to_seconds();
|