20 #include "worldsimconfig.h"
21 #include "motorcontrollers.h"
25 #ifdef FARSA_USE_YARP_AND_ICUB
28 #pragma GCC diagnostic ignored "-Wunused-parameter"
30 #include <yarp/os/Searchable.h>
32 #pragma GCC diagnostic warning "-Wunused-parameter"
35 using namespace yarp::dev;
36 using namespace yarp::os;
61 double wPID::pidloop(
double PV ) {
69 this_target = next_target;
72 if ( accel_r > 0 && this_target != setpt) {
73 if ( this_target < setpt ) {
74 next_target += accel_r;
75 if ( next_target > setpt ) {
79 next_target -= accel_r;
80 if ( next_target < setpt ) {
90 accel = next_target - this_target;
93 this_error = this_target - PV;
96 deriv = this_error - last_error;
101 friction = ( PV == 0.0 && next_target != 0.0 );
103 integral += this_target - PV;
107 this_output = p_gain * this_error
111 + vel_ff * next_target
114 last_error = this_error;
117 if ( this_output - last_output > slew ) {
118 this_output = last_output + slew;
119 }
else if ( last_output - this_output > slew ) {
120 this_output = last_output - slew;
124 if ( this_output <
min ) {
126 }
else if ( this_output >
max ) {
131 return last_output = this_output;
143 MotorController::MotorController(
World* world ) {
148 MotorController::~MotorController() {
152 MultiMotorController::MultiMotorController( QVector<PhyDOF*> dofs,
World* world ) :
154 #ifdef FARSA_USE_YARP_AND_ICUB
161 controlModes.fill( 1, motorsv.size() );
162 refsacc.fill( 1.0, motorsv.size() );
164 refs.fill( 0.0, motorsv.size() );
165 refsvel.fill( 1.0, motorsv.size() );
166 xfx0.fill( 0.0, motorsv.size() );
167 x0.fill( 0.0, motorsv.size() );
168 dx0.fill( 0.0, motorsv.size() );
169 t.fill( 0.0, motorsv.size() );
170 T.fill( 0.0, motorsv.size() );
171 stops.fill(
true, motorsv.size() );
172 lastErrors.fill( 0.0, motorsv.size() );
173 lastIs.fill( 0.0, motorsv.size() );
174 lastTorques.fill( 0.0, motorsv.size() );
176 pos_pids.resize( motorsv.size() );
177 for(
int i=0; i<motorsv.size(); i++ ) {
178 pos_pids[i] =
new wPID();
179 pos_pids[i]->p_gain = 0.8;
180 pos_pids[i]->i_gain = 0.05;
181 pos_pids[i]->d_gain = 0.0;
182 pos_pids[i]->accel_r = 0;
183 pos_pids[i]->min = -PI_GRECO/2.0;
184 pos_pids[i]->max = +PI_GRECO/2.0;
187 desiredVel.fill( 0.0, motorsv.size() );
189 vel_pids.resize( motorsv.size() );
190 for(
int i=0; i<motorsv.size(); i++ ) {
191 vel_pids[i] =
new wPID();
192 vel_pids[i]->p_gain = 0.8;
193 vel_pids[i]->i_gain = 0.1;
194 vel_pids[i]->d_gain = 0.0;
197 vel_pids[i]->min = -
toRad( 120 );
198 vel_pids[i]->max = +
toRad( 120 );
201 loLimits.resize( motorsv.size() );
202 hiLimits.resize( motorsv.size() );
203 for(
int i=0; i<motorsv.size(); i++ ) {
205 motorsv[i]->limits( fmin, fmax );
212 for(
int i=0; i<motorsv.size(); i++ ) {
213 delete (vel_pids[i]);
214 delete (pos_pids[i]);
220 for(
int i=0; i<motorsv.size(); i++ ) {
221 switch( controlModes[i] ) {
224 real tFracT = t[i] / T[i];
225 real tFracT3= tFracT * tFracT * tFracT;
226 real tFracT4= tFracT * tFracT3;
227 real tFracT5= tFracT * tFracT4;
232 accum = dx0[i] * tFracT;
233 accum = accum + tFracT3 * (10.0*xfx0[i] - 6.0*dx0[i]);
234 accum = accum - tFracT4 * (15.0*xfx0[i] - 8.0*dx0[i]);
235 accum = accum + tFracT5 * (6.0*xfx0[i] - 3.0*dx0[i]);
242 pos_pids[i]->setpt = accum;
244 motorsv[i]->setDesiredPosition( toRawPosition(accum, i) );
248 stops[i] = ( t[i] / T[i] > 1.0 );
252 vel_pids[i]->setpt = desiredVel[i];
253 wishvel = vel_pids[i]->pidloop( motorsv[i]->velocity() );
254 motorsv[i]->setDesiredVelocity( wishvel );
264 #ifdef FARSA_USE_YARP_AND_ICUB
281 *ax = motorsv.size();
291 if ( j < 0 && j >= motorsv.size() ) {
294 if ( motorsv[j]->translate() ) {
297 refs[j] =
toRad( ref );
299 if ( motorsv[j]->isLimited() ) {
303 real offset = (fabs(hiLimits[j])-fabs(loLimits[j]))*0.005;
304 refs[j] =
ramp( loLimits[j]+offset, hiLimits[j]-offset, refs[j] );
307 x0[j] = fromRawPosition(j);
308 xfx0[j] = refs[j] - x0[j];
309 dx0[j] = motorsv[j]->velocity();
310 T[j] = fabs( xfx0[j] ) / refsvel[j];
314 stops[j] = ( T[j] < 0.010 );
320 for(
int i=0; i<refs.size(); i++ ) {
321 if ( motorsv[i]->translate() ) {
322 refs[i] = newrefs[i];
324 refs[i] =
toRad( newrefs[i] );
326 if ( motorsv[i]->isLimited() ) {
330 real offset = (fabs(hiLimits[i])-fabs(loLimits[i]))*0.005;
331 refs[i] =
ramp( loLimits[i]+offset, hiLimits[i]-offset, refs[i] );
334 x0[i] = fromRawPosition( i );
335 xfx0[i] = refs[i] - x0[i];
336 dx0[i] = motorsv[i]->velocity();
337 T[i] = fabs( xfx0[i] ) / refsvel[i];
341 stops[i] = ( T[i] < 0.010 );
348 if ( j < 0 && j >= motorsv.size() ) {
351 if ( motorsv[j]->translate() ) {
354 refs[j] +=
toRad( delta );
356 if ( motorsv[j]->isLimited() ) {
360 real offset = (fabs(hiLimits[j])-fabs(loLimits[j]))*0.005;
361 refs[j] =
ramp( loLimits[j]+offset, hiLimits[j]-offset, refs[j] );
364 x0[j] = fromRawPosition(j);
365 xfx0[j] = refs[j] - x0[j];
366 dx0[j] = motorsv[j]->velocity();
367 T[j] = fabs( xfx0[j] ) / refsvel[j];
376 for(
int i=0; i<refs.size(); i++ ) {
377 if ( motorsv[i]->translate() ) {
378 refs[i] += deltas[i];
380 refs[i] +=
toRad( deltas[i] );
382 if ( motorsv[i]->isLimited() ) {
386 real offset = (fabs(hiLimits[i])-fabs(loLimits[i]))*0.005;
387 refs[i] =
ramp( loLimits[i]+offset, hiLimits[i]-offset, refs[i] );
390 x0[i] = fromRawPosition( i );
391 xfx0[i] = refs[i] - x0[i];
392 dx0[i] = motorsv[i]->velocity();
393 T[i] = fabs( xfx0[i] ) / refsvel[i];
403 if ( j < 0 && j >= motorsv.size() ) {
407 *flag = ( fabs(fromRawPosition(j) - refs[j]) < 0.01745329 );
414 for(
int i=0; i<refs.size(); i++ ) {
416 ends &= ( fabs(fromRawPosition(i) - refs[i]) < 0.01745329 );
425 if ( j < 0 && j >= motorsv.size() ) {
428 if ( motorsv[j]->translate() ) {
431 refsvel[j] =
toRad(sp);
433 motorsv[j]->setMaxVelocity( refsvel[j] );
438 for(
int i=0; i<refs.size(); i++ ) {
439 if ( motorsv[i]->translate() ) {
440 refsvel[i] = spds[i];
442 refsvel[i] =
toRad(spds[i]);
444 motorsv[i]->setMaxVelocity( refsvel[i] );
450 if ( j < 0 && j >= motorsv.size() ) {
453 if ( motorsv[j]->translate() ) {
456 refsacc[j] =
toRad(acc);
462 for(
int i=0; i<refs.size(); i++ ) {
463 if ( motorsv[i]->translate() ) {
464 refsacc[i] = accs[i];
466 refsacc[i] =
toRad(accs[i]);
473 if ( j < 0 && j >= motorsv.size() ) {
476 if ( motorsv[j]->translate() ) {
485 for(
int i=0; i<refsvel.size(); i++ ) {
486 if ( motorsv[i]->translate() ) {
487 spds[i] = refsvel[i];
496 if ( j < 0 && j >= motorsv.size() ) {
499 if ( motorsv[j]->translate() ) {
508 for(
int i=0; i<refsvel.size(); i++ ) {
509 if ( motorsv[i]->translate() ) {
510 accs[i] = refsacc[i];
519 if ( j < 0 && j >= motorsv.size() ) {
522 refs[j] = fromRawPosition(j);
525 motorsv[j]->setVelocity(0.0);
527 vel_pids[j]->reset();
532 for(
int i=0; i<motorsv.size(); i++ ) {
533 refs[i] = fromRawPosition(i);
536 motorsv[i]->setVelocity(0.0);
538 vel_pids[i]->reset();
549 if ( j < 0 && j >= motorsv.size() ) {
553 desiredVel[j] =
toRad(sp);
558 for(
int i=0; i<desiredVel.size(); i++ ) {
559 desiredVel[i] =
toRad(sp[i]);
566 if ( j < 0 && j >= motorsv.size() ) {
570 refs[j] = fromRawPosition(j);
577 if ( j < 0 && j >= motorsv.size() ) {
588 if ( j < 0 && j >= motorsv.size() ) {
596 if ( j < 0 && j >= motorsv.size() ) {
599 *mode = controlModes[j];
604 for(
int i=0; i<motorsv.size(); i++ ) {
605 modes[i] = controlModes[i];
631 if ( j < 0 && j >= motorsv.size() ) {
634 if ( motorsv[j]->translate() ) {
635 (*v) = fromRawPosition(j);
637 (*v) =
toDegree( fromRawPosition(j) );
643 for(
int i=0; i<motorsv.size(); i++ ) {
644 if ( motorsv[i]->translate() ) {
645 encs[i] = fromRawPosition(i);
647 encs[i] =
toDegree( fromRawPosition(i) );
654 if ( j < 0 && j >= motorsv.size() ) {
657 if ( motorsv[j]->translate() ) {
658 (*sp) = motorsv[j]->velocity();
660 (*sp) =
toDegree(motorsv[j]->velocity());
666 for(
int i=0; i<motorsv.size(); i++ ) {
667 if ( motorsv[i]->translate() ) {
668 spds[i] = motorsv[i]->velocity();
670 spds[i] =
toDegree(motorsv[i]->velocity());
685 if ( axis < 0 && axis >= motorsv.size() ) {
688 if ( motorsv[axis]->translate() ) {
689 loLimits[axis] =
min;
690 hiLimits[axis] =
max;
692 loLimits[axis] =
toRad( min );
693 hiLimits[axis] =
toRad( max );
699 if ( axis < 0 && axis >= motorsv.size() ) {
702 if ( motorsv[axis]->translate() ) {
703 *min = loLimits[axis];
704 *max = hiLimits[axis];
713 if ( axis < 0 && axis >= motorsv.size() ) {
716 if ( motorsv[axis]->translate() ) {
717 motorsv[axis]->setLimits( min, max );
719 motorsv[axis]->setLimits(
toRad(min),
toRad(max) );
725 if ( axis < 0 && axis >= motorsv.size() ) {
729 motorsv[axis]->limits( fmin, fmax );
730 if ( motorsv[axis]->translate() ) {
741 if ( axis < 0 && axis >= motorsv.size() ) {
745 motorsv[axis]->enableLimits();
747 motorsv[axis]->disableLimits();
752 real MultiMotorController::fromRawPosition(
int i ) {
754 motorsv[i]->limits( rmin, rmax );
755 return linearMap( motorsv[i]->position(), rmin, rmax, loLimits[i], hiLimits[i] );
758 real MultiMotorController::toRawPosition( real norawpos,
int i ) {
760 motorsv[i]->limits( rmin, rmax );
761 return linearMap( norawpos, loLimits[i], hiLimits[i], rmin, rmax );
764 void wheeledRobotsComputeKinematicMovement(wMatrix &mtr, real leftWheelVelocity, real rightWheelVelocity, real wheelr, real axletrack, real timestep)
766 const wMatrix origMtr = mtr;
775 const real leftSpeed = leftWheelVelocity * wheelr;
776 const real rightSpeed = rightWheelVelocity * wheelr;
780 if (fabs(leftSpeed - rightSpeed) < 0.00001f) {
782 mtr.w_pos += -mtr.y_ax.scale(rightSpeed * timestep);
829 const wVector L(0.0, -leftSpeed, 0.0);
830 const wVector A(axletrack, -(rightSpeed - leftSpeed), 0.0);
831 const real a = -(L.y / A.y);
832 const wVector C = L + A.
scale(a);
839 const real distLeftWheel = -C.x;
840 const real distRightWheel = -(C.x - A.x);
841 const real angularVelocity = (fabs(distLeftWheel) > fabs(distRightWheel)) ? (-leftSpeed / distLeftWheel) : (-rightSpeed / distRightWheel);
847 const real angularDisplacement = angularVelocity * timestep;
848 const wVector centerOfRotation = origMtr.transformVector(C - wVector(axletrack / 2.0, 0.0, 0.0));
849 const wVector axisOfRotation = origMtr.z_ax;
852 mtr = mtr.
rotateAround(axisOfRotation, centerOfRotation, angularDisplacement);
859 desiredVel.fill( 0.0, motorsv.size() );
860 minVel.fill( -1.0, motorsv.size() );
861 maxVel.fill( 1.0, motorsv.size() );
869 for(
int i=0; i<motorsv.size(); i++ ) {
870 motorsv[i]->setDesiredVelocity( desiredVel[i] );
875 for(
int i=0; i<qMin(speeds.size(), desiredVel.size()); i++ ) {
876 if ( speeds[i] < minVel[i] ) {
877 desiredVel[i] = minVel[i];
878 }
else if ( speeds[i] > maxVel[i] ) {
879 desiredVel[i] = maxVel[i];
881 desiredVel[i] = speeds[i];
887 if ( sp1 < minVel[0] ) {
888 desiredVel[0] = minVel[0];
889 }
else if ( sp1 > maxVel[0] ) {
890 desiredVel[0] = maxVel[0];
895 if ( sp2 < minVel[1] ) {
896 desiredVel[1] = minVel[1];
897 }
else if ( sp2 > maxVel[1] ) {
898 desiredVel[1] = maxVel[1];
906 for(
int i=0; i<motorsv.size(); i++ ) {
907 speeds.append(motorsv[i]->velocity());
912 sp1 = motorsv[0]->velocity();
913 sp2 = motorsv[1]->velocity();
922 minVel[0] = minSpeed1;
923 minVel[1] = minSpeed2;
924 maxVel[0] = maxSpeed1;
925 maxVel[1] = maxSpeed2;
934 minSpeed1 = minVel[0];
935 minSpeed2 = minVel[1];
936 maxSpeed1 = maxVel[0];
937 maxSpeed2 = maxVel[1];