201 Bottle &bJoint=bGroup.findGroup(joint.str());
203 pid.
Kp=bJoint.check(
"Kp",Value(0.0)).asFloat64();
204 pid.
Ki=bJoint.check(
"Ki",Value(0.0)).asFloat64();
205 pid.
Kd=bJoint.check(
"Kd",Value(0.0)).asFloat64();
206 pid.
scale=bJoint.check(
"scale",Value(0.0)).asFloat64();
207 pid.
st_up=bJoint.check(
"st_up",Value(0.0)).asFloat64();
208 pid.
st_down=bJoint.check(
"st_down",Value(0.0)).asFloat64();
209 pid.
encs_ratio=bJoint.check(
"encs_ratio",Value(1.0)).asFloat64();
211 if (bJoint.check(
"idling"))
213 if (Bottle *bIdlingJoints=bJoint.find(
"idling").asList())
216 for (
int j=0; j<bIdlingJoints->size(); j++)
218 int k=bIdlingJoints->get(j).asInt32();
221 for (l=0; l<
rJoints.size(); l++)
223 if (
rJoints.get(l).asInt32()==k)
231 yError(
"unrecognized joint %d to put in idle",k);
257 pGeneral.put(
"joint",i);
258 string sGeneral=
"(general ";
259 sGeneral+=pGeneral.toString();
262 Bottle bGeneral,bPlantEstimation,bStictionEstimation;
263 bGeneral.fromString(sGeneral);
264 bPlantEstimation.fromString(
"(plant_estimation (Ts 0.01) (Q 1.0) (R 1.0) (P0 100000.0) (tau 1.0) (K 1.0) (max_pwm 800.0))");
265 bStictionEstimation.fromString(
"(stiction_estimation (Ts 0.01) (T 2.0) (vel_thres 5.0) (e_thres 1.0) (gamma (10.0 10.0)) (stiction (0.0 0.0)))");
267 Bottle bConf=bGeneral;
268 bConf.append(bPlantEstimation);
269 bConf.append(bStictionEstimation);
271 Property pOptions(bConf.toString().c_str());
275 yError(
"designer configuration failed!");
281 Property pPlantEstimation;
282 pPlantEstimation.put(
"max_time",20.0);
283 pPlantEstimation.put(
"switch_timeout",2.0);
286 yInfo(
"Estimating plant for joint %d: max duration = %g seconds",
287 i,pPlantEstimation.find(
"max_time").asFloat64());
289 double t0=Time::now();
290 while (!designer.
isDone())
292 yInfo(
"elapsed %d [s]",(
int)(Time::now()-t0));
303 double tau=pResults.find(
"tau_mean").asFloat64();
304 double K=pResults.find(
"K_mean").asFloat64();
305 yInfo(
"plant = %g/s * 1/(1+s*%g)",K,tau);
307 Property pControllerRequirements,pController;
308 pControllerRequirements.put(
"tau",tau);
309 pControllerRequirements.put(
"K",K);
310 pControllerRequirements.put(
"f_c",0.75);
314 pControllerRequirements.put(
"T_dr",1.0);
315 pControllerRequirements.put(
"type",
"PI");
318 pControllerRequirements.put(
"type",
"P");
321 yInfo(
"tuning results: %s",pController.toString().c_str());
322 double Kp=pController.find(
"Kp").asFloat64();
323 double Ki=pController.find(
"Ki").asFloat64();
325 int scale=(int)pid.
scale;
int shift=1<<scale;
327 double fwKi=floor(Ki*pid.
encs_ratio*shift/1000.0);
328 pid.
Kp=yarp::math::sign(pid.
Kp*fwKp)>0.0?fwKp:-fwKp;
329 pid.
Ki=yarp::math::sign(pid.
Ki*fwKi)>0.0?fwKi:-fwKi;
331 yInfo(
"Kp (FW) = %g; Ki (FW) = %g; Kd (FW) = %g; shift factor = %d",pid.
Kp,pid.
Ki,pid.
Kd,scale);
333 Property pStictionEstimation;
334 pStictionEstimation.put(
"max_time",60.0);
335 pStictionEstimation.put(
"Kp",Kp);
336 pStictionEstimation.put(
"Ki",0.0);
337 pStictionEstimation.put(
"Kd",0.0);
340 yInfo(
"Estimating stiction for joint %d: max duration = %g seconds",
341 i,pStictionEstimation.find(
"max_time").asFloat64());
344 while (!designer.
isDone())
346 yInfo(
"elapsed %d [s]",(
int)(Time::now()-t0));
356 pid.
st_up=floor(pResults.find(
"stiction").asList()->get(0).asFloat64());
357 pid.
st_down=floor(pResults.find(
"stiction").asList()->get(1).asFloat64());
358 yInfo(
"Stiction values: up = %g; down = %g",pid.
st_up,pid.
st_down);
361 IPositionControl *ipos;
366 imod->setControlMode(i,VOCAB_CM_POSITION);
367 ipos->setRefSpeed(i,50.0);
368 ipos->positionMove(i,0.0);
369 yInfo(
"Driving the joint back to rest... ");
371 while (Time::now()-t0<5.0)
374 ienc->getEncoder(i,&enc);
403 Bottle &bGeneral=rf.findGroup(
"general");
404 if (bGeneral.isNull())
406 yError(
"group [general] is missing!");
410 Bottle &bPart=rf.findGroup(
part);
413 yError(
"group [%s] is missing!",
part.c_str());
417 if (!bPart.check(
"device"))
419 yError(
"\"device\" option is missing!");
423 name=bGeneral.check(
"name",Value(
"fingersTuner")).asString();
424 robot=bGeneral.check(
"robot",Value(
"icub")).asString();
425 double ping_robot_tmo=bGeneral.check(
"ping_robot_tmo",Value(0.0)).asFloat64();
426 device=bPart.find(
"device").asString();
428 if (Bottle *rj=bGeneral.find(
"relevantJoints").asList())
432 yError(
"\"relevantJoints\" option is missing!");
436 int numAlias=bGeneral.check(
"numAlias",Value(0)).asInt32();
437 for (
int i=0; i<numAlias; i++)
441 Bottle &bAlias=bGeneral.findGroup(item.str());
442 if (Bottle *joints=bAlias.find(
"joints").asList())
443 alias[bAlias.find(
"tag").asString()]=*joints;
449 for (
int i=0; i<
rJoints.size(); i++)
451 int j=
rJoints.get(i).asInt32();
455 ostringstream portsSuffix;
458 Property option(
"(device remote_controlboard)");
460 option.put(
"local",
"/"+
name+
"/"+portsSuffix.str());
462 if (ping_robot_tmo>0.0)
465 driver=
new PolyDriver(option);
469 yError(
"%s device driver not available!",
device.c_str());
481 joints.addInt32(sel.asInt32());
482 else if (sel.isString())
484 map<string,Bottle>::iterator it=
alias.find(sel.asString());
493 for (
int i=0; i<joints.size(); i++)
495 int j=
rJoints.get(i).asInt32();
496 map<int,PidData>::iterator it=
pids.find(j);
503 ipid->getPid(VOCAB_PIDTYPE_POSITION,j,&_pid);
511 ipid->setPid(VOCAB_PIDTYPE_POSITION,j,_pid);
525 joints.addInt32(sel.asInt32());
526 else if (sel.isString())
528 map<string,Bottle>::iterator it=
alias.find(sel.asString());
537 for (
int i=0; i<joints.size(); i++)
539 int j=joints.get(i).asInt32();
540 map<int,PidData>::iterator it=
pids.find(j);
549 ipid->getPid(VOCAB_PIDTYPE_POSITION,j,&_pid);
553 ipid->setPid(VOCAB_PIDTYPE_POSITION,j,_pid);