20 #include "worldsimconfig.h"
21 #include "motorcontrollers.h"
26 #pragma GCC diagnostic ignored "-Wunused-parameter"
28 #include <yarp/os/Searchable.h>
30 #pragma GCC diagnostic warning "-Wunused-parameter"
33 #ifdef FARSA_USE_YARP_AND_ICUB
34 using namespace yarp::dev;
35 using namespace yarp::os;
60 double wPID::pidloop(
double PV ) {
68 this_target = next_target;
71 if ( accel_r > 0 && this_target != setpt) {
72 if ( this_target < setpt ) {
73 next_target += accel_r;
74 if ( next_target > setpt ) {
78 next_target -= accel_r;
79 if ( next_target < setpt ) {
89 accel = next_target - this_target;
92 this_error = this_target - PV;
95 deriv = this_error - last_error;
100 friction = ( PV == 0.0 && next_target != 0.0 );
102 integral += this_target - PV;
106 this_output = p_gain * this_error
110 + vel_ff * next_target
113 last_error = this_error;
116 if ( this_output - last_output > slew ) {
117 this_output = last_output + slew;
118 }
else if ( last_output - this_output > slew ) {
119 this_output = last_output - slew;
123 if ( this_output <
min ) {
125 }
else if ( this_output >
max ) {
130 return last_output = this_output;
142 MotorController::MotorController(
World* world ) {
147 MotorController::~MotorController() {
151 MultiMotorController::MultiMotorController( QVector<PhyDOF*> dofs,
World* world ) :
153 #ifdef FARSA_USE_YARP_AND_ICUB
160 controlModes.fill( 1, motorsv.size() );
161 refsacc.fill( 1.0, motorsv.size() );
163 refs.fill( 0.0, motorsv.size() );
164 refsvel.fill( 1.0, motorsv.size() );
165 xfx0.fill( 0.0, motorsv.size() );
166 x0.fill( 0.0, motorsv.size() );
167 dx0.fill( 0.0, motorsv.size() );
168 t.fill( 0.0, motorsv.size() );
169 T.fill( 0.0, motorsv.size() );
170 stops.fill(
true, motorsv.size() );
171 lastErrors.fill( 0.0, motorsv.size() );
172 lastIs.fill( 0.0, motorsv.size() );
173 lastTorques.fill( 0.0, motorsv.size() );
175 pos_pids.resize( motorsv.size() );
176 for(
int i=0; i<motorsv.size(); i++ ) {
177 pos_pids[i] =
new wPID();
178 pos_pids[i]->p_gain = 0.8;
179 pos_pids[i]->i_gain = 0.05;
180 pos_pids[i]->d_gain = 0.0;
181 pos_pids[i]->accel_r = 0;
182 pos_pids[i]->min = -PI_GRECO/2.0;
183 pos_pids[i]->max = +PI_GRECO/2.0;
186 desiredVel.fill( 0.0, motorsv.size() );
188 vel_pids.resize( motorsv.size() );
189 for(
int i=0; i<motorsv.size(); i++ ) {
190 vel_pids[i] =
new wPID();
191 vel_pids[i]->p_gain = 0.8;
192 vel_pids[i]->i_gain = 0.1;
193 vel_pids[i]->d_gain = 0.0;
196 vel_pids[i]->min = -
toRad( 120 );
197 vel_pids[i]->max = +
toRad( 120 );
200 loLimits.resize( motorsv.size() );
201 hiLimits.resize( motorsv.size() );
202 for(
int i=0; i<motorsv.size(); i++ ) {
204 motorsv[i]->limits( fmin, fmax );
211 for(
int i=0; i<motorsv.size(); i++ ) {
212 delete (vel_pids[i]);
213 delete (pos_pids[i]);
219 for(
int i=0; i<motorsv.size(); i++ ) {
220 switch( controlModes[i] ) {
223 real tFracT = t[i] / T[i];
224 real tFracT3= tFracT * tFracT * tFracT;
225 real tFracT4= tFracT * tFracT3;
226 real tFracT5= tFracT * tFracT4;
231 accum = dx0[i] * tFracT;
232 accum = accum + tFracT3 * (10.0*xfx0[i] - 6.0*dx0[i]);
233 accum = accum - tFracT4 * (15.0*xfx0[i] - 8.0*dx0[i]);
234 accum = accum + tFracT5 * (6.0*xfx0[i] - 3.0*dx0[i]);
241 pos_pids[i]->setpt = accum;
243 motorsv[i]->setDesiredPosition( toRawPosition(accum, i) );
247 stops[i] = ( t[i] / T[i] > 1.0 );
251 vel_pids[i]->setpt = desiredVel[i];
252 wishvel = vel_pids[i]->pidloop( motorsv[i]->velocity() );
253 motorsv[i]->setDesiredVelocity( wishvel );
263 #ifdef FARSA_USE_YARP_AND_ICUB
280 *ax = motorsv.size();
290 if ( j < 0 && j >= motorsv.size() ) {
293 if ( motorsv[j]->translate() ) {
296 refs[j] =
toRad( ref );
298 if ( motorsv[j]->isLimited() ) {
302 real offset = (fabs(hiLimits[j])-fabs(loLimits[j]))*0.005;
303 refs[j] =
ramp( loLimits[j]+offset, hiLimits[j]-offset, refs[j] );
306 x0[j] = fromRawPosition(j);
307 xfx0[j] = refs[j] - x0[j];
308 dx0[j] = motorsv[j]->velocity();
309 T[j] = fabs( xfx0[j] ) / refsvel[j];
313 stops[j] = ( T[j] < 0.010 );
319 for(
int i=0; i<refs.size(); i++ ) {
320 if ( motorsv[i]->translate() ) {
321 refs[i] = newrefs[i];
323 refs[i] =
toRad( newrefs[i] );
325 if ( motorsv[i]->isLimited() ) {
329 real offset = (fabs(hiLimits[i])-fabs(loLimits[i]))*0.005;
330 refs[i] =
ramp( loLimits[i]+offset, hiLimits[i]-offset, refs[i] );
333 x0[i] = fromRawPosition( i );
334 xfx0[i] = refs[i] - x0[i];
335 dx0[i] = motorsv[i]->velocity();
336 T[i] = fabs( xfx0[i] ) / refsvel[i];
340 stops[i] = ( T[i] < 0.010 );
347 if ( j < 0 && j >= motorsv.size() ) {
350 if ( motorsv[j]->translate() ) {
353 refs[j] +=
toRad( delta );
355 if ( motorsv[j]->isLimited() ) {
359 real offset = (fabs(hiLimits[j])-fabs(loLimits[j]))*0.005;
360 refs[j] =
ramp( loLimits[j]+offset, hiLimits[j]-offset, refs[j] );
363 x0[j] = fromRawPosition(j);
364 xfx0[j] = refs[j] - x0[j];
365 dx0[j] = motorsv[j]->velocity();
366 T[j] = fabs( xfx0[j] ) / refsvel[j];
375 for(
int i=0; i<refs.size(); i++ ) {
376 if ( motorsv[i]->translate() ) {
377 refs[i] += deltas[i];
379 refs[i] +=
toRad( deltas[i] );
381 if ( motorsv[i]->isLimited() ) {
385 real offset = (fabs(hiLimits[i])-fabs(loLimits[i]))*0.005;
386 refs[i] =
ramp( loLimits[i]+offset, hiLimits[i]-offset, refs[i] );
389 x0[i] = fromRawPosition( i );
390 xfx0[i] = refs[i] - x0[i];
391 dx0[i] = motorsv[i]->velocity();
392 T[i] = fabs( xfx0[i] ) / refsvel[i];
402 if ( j < 0 && j >= motorsv.size() ) {
406 *flag = ( fabs(fromRawPosition(j) - refs[j]) < 0.01745329 );
413 for(
int i=0; i<refs.size(); i++ ) {
415 ends &= ( fabs(fromRawPosition(i) - refs[i]) < 0.01745329 );
424 if ( j < 0 && j >= motorsv.size() ) {
427 if ( motorsv[j]->translate() ) {
430 refsvel[j] =
toRad(sp);
432 motorsv[j]->setMaxVelocity( refsvel[j] );
437 for(
int i=0; i<refs.size(); i++ ) {
438 if ( motorsv[i]->translate() ) {
439 refsvel[i] = spds[i];
441 refsvel[i] =
toRad(spds[i]);
443 motorsv[i]->setMaxVelocity( refsvel[i] );
449 if ( j < 0 && j >= motorsv.size() ) {
452 if ( motorsv[j]->translate() ) {
455 refsacc[j] =
toRad(acc);
461 for(
int i=0; i<refs.size(); i++ ) {
462 if ( motorsv[i]->translate() ) {
463 refsacc[i] = accs[i];
465 refsacc[i] =
toRad(accs[i]);
472 if ( j < 0 && j >= motorsv.size() ) {
475 if ( motorsv[j]->translate() ) {
484 for(
int i=0; i<refsvel.size(); i++ ) {
485 if ( motorsv[i]->translate() ) {
486 spds[i] = refsvel[i];
495 if ( j < 0 && j >= motorsv.size() ) {
498 if ( motorsv[j]->translate() ) {
507 for(
int i=0; i<refsvel.size(); i++ ) {
508 if ( motorsv[i]->translate() ) {
509 accs[i] = refsacc[i];
518 if ( j < 0 && j >= motorsv.size() ) {
521 refs[j] = fromRawPosition(j);
524 motorsv[j]->setVelocity(0.0);
526 vel_pids[j]->reset();
531 for(
int i=0; i<motorsv.size(); i++ ) {
532 refs[i] = fromRawPosition(i);
535 motorsv[i]->setVelocity(0.0);
537 vel_pids[i]->reset();
548 if ( j < 0 && j >= motorsv.size() ) {
552 desiredVel[j] =
toRad(sp);
557 for(
int i=0; i<desiredVel.size(); i++ ) {
558 desiredVel[i] =
toRad(sp[i]);
565 if ( j < 0 && j >= motorsv.size() ) {
569 refs[j] = fromRawPosition(j);
576 if ( j < 0 && j >= motorsv.size() ) {
587 if ( j < 0 && j >= motorsv.size() ) {
595 if ( j < 0 && j >= motorsv.size() ) {
598 *mode = controlModes[j];
603 for(
int i=0; i<motorsv.size(); i++ ) {
604 modes[i] = controlModes[i];
630 if ( j < 0 && j >= motorsv.size() ) {
633 if ( motorsv[j]->translate() ) {
634 (*v) = fromRawPosition(j);
636 (*v) =
toDegree( fromRawPosition(j) );
642 for(
int i=0; i<motorsv.size(); i++ ) {
643 if ( motorsv[i]->translate() ) {
644 encs[i] = fromRawPosition(i);
646 encs[i] =
toDegree( fromRawPosition(i) );
653 if ( j < 0 && j >= motorsv.size() ) {
656 if ( motorsv[j]->translate() ) {
657 (*sp) = motorsv[j]->velocity();
659 (*sp) =
toDegree(motorsv[j]->velocity());
665 for(
int i=0; i<motorsv.size(); i++ ) {
666 if ( motorsv[i]->translate() ) {
667 spds[i] = motorsv[i]->velocity();
669 spds[i] =
toDegree(motorsv[i]->velocity());
684 if ( axis < 0 && axis >= motorsv.size() ) {
687 if ( motorsv[axis]->translate() ) {
688 loLimits[axis] =
min;
689 hiLimits[axis] =
max;
691 loLimits[axis] =
toRad( min );
692 hiLimits[axis] =
toRad( max );
698 if ( axis < 0 && axis >= motorsv.size() ) {
701 if ( motorsv[axis]->translate() ) {
702 *min = loLimits[axis];
703 *max = hiLimits[axis];
712 if ( axis < 0 && axis >= motorsv.size() ) {
715 if ( motorsv[axis]->translate() ) {
716 motorsv[axis]->setLimits( min, max );
718 motorsv[axis]->setLimits(
toRad(min),
toRad(max) );
724 if ( axis < 0 && axis >= motorsv.size() ) {
728 motorsv[axis]->limits( fmin, fmax );
729 if ( motorsv[axis]->translate() ) {
740 if ( axis < 0 && axis >= motorsv.size() ) {
744 motorsv[axis]->enableLimits();
746 motorsv[axis]->disableLimits();
751 real MultiMotorController::fromRawPosition(
int i ) {
753 motorsv[i]->limits( rmin, rmax );
754 return linearMap( motorsv[i]->position(), rmin, rmax, loLimits[i], hiLimits[i] );
757 real MultiMotorController::toRawPosition( real norawpos,
int i ) {
759 motorsv[i]->limits( rmin, rmax );
760 return linearMap( norawpos, loLimits[i], hiLimits[i], rmin, rmax );
766 desiredVel.fill( 0.0, motorsv.size() );
767 minVel.fill( -1.0, motorsv.size() );
768 maxVel.fill( 1.0, motorsv.size() );
776 for(
int i=0; i<motorsv.size(); i++ ) {
777 motorsv[i]->setDesiredVelocity( desiredVel[i] );
782 for(
int i=0; i<qMin(speeds.size(), desiredVel.size()); i++ ) {
783 if ( speeds[i] < minVel[i] ) {
784 desiredVel[i] = minVel[i];
785 }
else if ( speeds[i] > maxVel[i] ) {
786 desiredVel[i] = maxVel[i];
788 desiredVel[i] = speeds[i];
794 if ( sp1 < minVel[0] ) {
795 desiredVel[0] = minVel[0];
796 }
else if ( sp1 > maxVel[0] ) {
797 desiredVel[0] = maxVel[0];
802 if ( sp2 < minVel[1] ) {
803 desiredVel[1] = minVel[1];
804 }
else if ( sp2 > maxVel[1] ) {
805 desiredVel[1] = maxVel[1];
813 for(
int i=0; i<motorsv.size(); i++ ) {
814 speeds.append(motorsv[i]->velocity());
819 sp1 = motorsv[0]->velocity();
820 sp2 = motorsv[1]->velocity();
829 minVel[0] = minSpeed1;
830 minVel[1] = minSpeed2;
831 maxVel[0] = maxSpeed1;
832 maxVel[1] = maxSpeed2;
841 minSpeed1 = minVel[0];
842 minSpeed2 = minVel[1];
843 maxSpeed1 = maxVel[0];
844 maxSpeed2 = maxVel[1];