iCub-main
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010 RobotCub Consortium, European Commission FP6 Project IST-004370
3 * Author: Marco Randazzo
4 * email: marco.randazzo@iit.it
5 * website: www.robotcub.org
6 * Permission is granted to copy, distribute, and/or modify this program
7 * under the terms of the GNU General Public License, version 2 or any
8 * later version published by the Free Software Foundation.
9 *
10 * A copy of the license can be found at
11 * http://www.robotcub.org/icub/license/gpl.txt
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 * Public License for more details
17*/
18
75#include <yarp/os/Network.h>
76#include <yarp/os/RFModule.h>
77#include <yarp/os/PeriodicThread.h>
78#include <yarp/os/Bottle.h>
79#include <yarp/os/BufferedPort.h>
80#include <yarp/os/Time.h>
81#include <yarp/os/Log.h>
82#include <yarp/os/LogStream.h>
83#include <yarp/sig/Vector.h>
84#include <yarp/math/Math.h>
85
86#include <yarp/dev/Drivers.h>
87#include <yarp/dev/CartesianControl.h>
88#include <yarp/dev/PolyDriver.h>
89
90//#include <gsl/gsl_math.h>
91
92#include <iostream>
93#include <iomanip>
94#include <string>
95#include <math.h>
96#include <SDL.h>
97
98using namespace std;
99using namespace yarp::os;
100using namespace yarp::dev;
101using namespace yarp::sig;
102using namespace yarp::math;
103
104#define PRINT_STATUS_PER 0.1
105#define MAX_AXES 32
106
108
109class CtrlThread: public PeriodicThread
110{
111 struct struct_jointProperties
112 {
113 int type;
114 int param[3];
115 string param_s;
116 };
117
118protected:
119 ResourceFinder &rf;
120 BufferedPort<Bottle> port_command;
121 BufferedPort<Bottle> port_axis_only;
122 BufferedPort<Bottle> port_buttons_only;
123 bool silent;
125
126 double defaultExecTime;
127 double t0;
133 SDL_Joystick* joy1;
134
135 //button actions;
136 string button_actions [20];
137
138 //hats actions;
139 string hat_actions [20];
140
141 //variables read from the joystick
146 double* rawAxes;
147 double* outAxes;
148
149 //variables read from the configuration file
152 double* inputMax;
153 double* inputMin;
154 double* outputMax;
155 double* outputMin;
158 struct_jointProperties* jointProperties;
159
160public:
161 CtrlThread(unsigned int _period, ResourceFinder &_rf) :
162 PeriodicThread((double)_period/1000.0), rf(_rf)
163 {
164 joy_id=0;
165 rawButtons=0;
167 rawAxes=0;
168 rawHats=0;
169 rawHatsOld=0;
170 outAxes=0;
171 joy1=0;
172 num_inputs=0;
173 num_outputs=0;
174 inputMax=0;
175 inputMin=0;
176 outputMax=0;
177 outputMin=0;
179 reverse=0;
181 silent = false;
182 force_cfg = false;
183 }
184
185 virtual bool threadInit()
186 {
187 // get params from the RF
188 if (rf.check("silent"))
189 {
190 yInfo ("Running in silent mode\n");
191 silent=true;
192 }
193
194 if (rf.check("force_configuration"))
195 {
196 yInfo ( "Force configuration option found\n");
197 force_cfg=true;
198 }
199
200 if (rf.findGroup("INPUTS").check("InputsNumber"))
201 {
202 num_inputs = rf.findGroup("INPUTS").find("InputsNumber").asInt32();
203 inputMax = new double [num_inputs];
204 inputMin = new double [num_inputs];
205 outputMax = new double [num_inputs];
206 outputMin = new double [num_inputs];
207 jointDeadband = new double [num_inputs];
208 reverse = new int [num_inputs];
209 yDebug ("Number of input axes in the configuration options: %d \n",num_inputs);
210 }
211 else
212 {
213 yError ("Unable to find number of input axes in the configuration options\n");
214 return false;
215 }
216
217 Bottle b;
218
219
220 b = rf.findGroup("INPUTS").findGroup("Reverse");
221 if (b.size()-1 == num_inputs)
222 {
223 for (int i = 1; i < b.size(); i++) reverse[i-1] = b.get(i).asInt32();
224 }
225 else {yError ( "Configuration error: invalid number of entries 'Reverse'\n"); return false;}
226 b = rf.findGroup("INPUTS").findGroup("InputMax");
227 if (b.size()-1 == num_inputs)
228 {
229 for (int i = 1; i < b.size(); i++) inputMax[i-1] = b.get(i).asFloat64();
230 }
231 else {yError ( "Configuration error: invalid number of entries 'InputMax'\n"); return false;}
232 b = rf.findGroup("INPUTS").findGroup("InputMin");
233 if (b.size()-1 == num_inputs)
234 {
235 for (int i = 1; i < b.size(); i++) inputMin[i-1] = b.get(i).asFloat64();
236 }
237 else {yError ( "Configuration error: invalid number of entries 'InputMin'\n"); return false;}
238 b = rf.findGroup("INPUTS").findGroup("OutputMax");
239 if (b.size()-1 == num_inputs)
240 {
241 for (int i = 1; i < b.size(); i++) outputMax[i-1] = b.get(i).asFloat64();
242 }
243 else {yError ( "Configuration error: invalid number of entries 'OutputMax'\n"); return false;}
244 b = rf.findGroup("INPUTS").findGroup("OutputMin");
245 if (b.size()-1 == num_inputs)
246 {
247 for (int i = 1; i < b.size(); i++) outputMin[i-1] = b.get(i).asFloat64();
248 }
249 else {yError ( "Configuration error: invalid number of entries 'OutputMin'\n"); return false;}
250
251 b = rf.findGroup("INPUTS").findGroup("Deadband");
252 if (b.size()-1 == num_inputs)
253 {
254 for (int i = 1; i < b.size(); i++) jointDeadband[i-1] = b.get(i).asFloat64();
255 }
256 else {yError ( "Configuration error: invalid number of entries 'Deadband'\n"); return false;}
257
258 if (rf.findGroup("OUTPUTS").check("OutputsNumber"))
259 {
260 num_outputs = rf.findGroup("OUTPUTS").find("OutputsNumber").asInt32();
261 jointProperties = new struct_jointProperties [num_outputs];
262 }
263 else
264 {
265 yError ( "Unable to find number of output axes in the configuration options\n");
266 return false;
267 }
268
269 for (int i=0; i<num_outputs; i++)
270 {
271 char tmp [20];
272 sprintf (tmp,"Ax%d",i);
273 if (!rf.findGroup("OUTPUTS").check(tmp))
274 {
275 yError ( "Error reading [OUTPUT] block, unable to find Ax%d identifier\n",i);
276 return false;
277 }
278 b = rf.findGroup("OUTPUTS").findGroup(tmp);
279 if (b.get(1).asString()=="polar_r_theta")
280 {
282 jointProperties[i].param[0]=b.get(2).asInt32();
283 jointProperties[i].param[1]=b.get(3).asInt32();
284 jointProperties[i].param[2]=b.get(4).asInt32();
285 }
286 else
287 if (b.get(1).asString()=="cartesian_xyz")
288 {
290 jointProperties[i].param[0]=b.get(2).asInt32();
291 jointProperties[i].param[1]=0;
292 jointProperties[i].param[2]=0;
293 }
294 else
295 if (b.get(1).asString()=="button_as_axis")
296 {
297 if (b.size() < 5)
298 {
299 yError("Configuration error: 'button_as_axis' for Ax%d requires 3 parameters (button_num, low_val, high_val)", i);
300 return false;
301 }
303 jointProperties[i].param[0]=b.get(2).asInt32(); //button num
304 jointProperties[i].param[1]=b.get(3).asInt32(); //low value
305 jointProperties[i].param[2]=b.get(4).asInt32(); //high value
306 }
307 else
308 if (b.get(1).asString()=="constant")
309 {
311 jointProperties[i].param[0]=b.get(2).asInt32();
312 jointProperties[i].param[1]=0;
313 jointProperties[i].param[2]=0;
314 }
315 else
316 if (b.get(1).asString()=="string")
317 {
319 jointProperties[i].param[0]=0;
320 jointProperties[i].param[1]=0;
321 jointProperties[i].param[2]=0;
322 jointProperties[i].param_s=b.get(2).asString();
323 }
324 else
325 {
326 yError() << "Unknown [OUTPUT] property";
327 return false;
328 }
329 }
330 //string s = b.toString(); //this causes compilation issues under linux
331
332 // open the output port
333 string output_port_name;
334 if (rf.findGroup("GENERAL").check("outputPortName"))
335 {
336 output_port_name = rf.findGroup("GENERAL").find("outputPortName").asString();
337 }
338 else
339 {
340 output_port_name = "/joystickCtrl:o";
341 yWarning ( "outputPortName not found, using %s \n", output_port_name.c_str());
342 }
343 bool ret=true;
344 ret &= port_command.open(output_port_name.c_str());
345 //@@@ TO BE COMPLETED: port name prefix to be set in the ini file
346 ret &= port_axis_only.open("/joystickCtrl/raw_axis:o");
347 ret &= port_buttons_only.open("/joystickCtrl/raw_buttons:o");
348 if (ret==false)
349 {
350 yError() << "Unable to open module ports";
351 return false;
352 }
353
354 //get the list of the commands to be executed with the buttons
355 Bottle& exec_comm_bottle = rf.findGroup("BUTTONS_EXECUTE");
356 if (!exec_comm_bottle.isNull())
357 {
358 yInfo ( "associating the following actions to the buttons: \n");
359 for (int iii = 0; iii < 20; iii++){
360 char tmp[80];
361 sprintf(tmp, "button%d", iii);
362 if (exec_comm_bottle.check(tmp))
363 {
364 button_actions[iii] = exec_comm_bottle.find(tmp).toString();
365 printf ("%s %s\n", tmp, button_actions[iii].c_str());
366 }
367 }
368 printf ("\n");
369 }
370
371 //get the list of the commands to be executed with the hats
372 Bottle& hats_exec_bottle = rf.findGroup("HATS_EXECUTE");
373 if (!hats_exec_bottle.isNull())
374 {
375 yInfo ( "associating the following actions to the hats: \n");
376 for (int iii = 0; iii < 20; iii++){
377 char tmp[80];
378 sprintf(tmp, "hat%d", iii);
379 if (hats_exec_bottle.check(tmp))
380 {
381 hat_actions[iii] = hats_exec_bottle.find(tmp).toString();
382 printf ("%s %s\n", tmp, hat_actions[iii].c_str());
383 }
384 }
385 printf ("\n");
386 }
387
388 // start SDL subsystem
389 //SDL_Init(SDL_INIT_VIDEO);
390 //SDL_SetVideoMode(640, 480, 16, SDL_DOUBLEBUF);
391 if ( SDL_InitSubSystem ( SDL_INIT_JOYSTICK ) < 0 )
392 {
393 yError ( "Unable to initialize Joystick: %s\n", SDL_GetError() );
394 return false;
395 }
396
397 // get the list of available joysticks
398 fprintf ( stderr, "\n");
399 int joy_id=0;
400 int joystick_num = SDL_NumJoysticks ();
401 if (joystick_num == 0)
402 {
403 yError ( "Error: No joysticks found\n"); return false;
404 }
405 else if (joystick_num == 1)
406 {
407 joy_id=0;
408 yInfo ( "One joystick found \n");
409#if (SDL_MAJOR_VERSION == 2)
410 yInfo ( "Using joystick: %s \n", SDL_JoystickNameForIndex(joy_id));
411#else
412 yInfo ( "Using joystick: %s \n", SDL_JoystickName(joy_id));
413#endif
414
415 }
416 else
417 {
418 yInfo ( "More than one joystick found:\n");
419 for (int i=0; i<joystick_num; i++)
420 {
421#if (SDL_MAJOR_VERSION == 2)
422 yInfo ( "%d: %s\n",i,SDL_JoystickNameForIndex(i));
423#else
424 yInfo ( "%d: %s\n",i,SDL_JoystickName(i));
425#endif
426 }
427 yInfo ( "\n");
428
429 // choose between multiple joysticks
430 if (rf.findGroup("GENERAL").check("DefaultJoystickNumber"))
431 {
432 joy_id = rf.findGroup("GENERAL").find("DefaultJoystickNumber").asInt32();
433 yInfo ( "Multiple joysticks found, using #%d, as specified in the configuration options\n", joy_id);
434 }
435 else
436 {
437 yWarning ( "No default joystick specified in the configuration options\n");
438 yWarning ( "Which joystick you want to use? (choose number) \n");
439 cin >> joy_id;
440 }
441 }
442
443 // Open the Joystick driver
444 joy1 = SDL_JoystickOpen ( joy_id );
445 if ( joy1 == NULL )
446 {
447 yError ( "Could not open joystick\n" );
448 return false;
449 }
450
451 // Obtaining Joystick capabilities
452 numAxes = SDL_JoystickNumAxes ( joy1 );
453 numBalls = SDL_JoystickNumBalls ( joy1 );
454 numHats = SDL_JoystickNumHats ( joy1 );
455 numButtons = SDL_JoystickNumButtons ( joy1 );
456 yInfo ( "Characteristics of joy %d: \n", joy_id);
457 yInfo ( "%i Axes\n", numAxes );
458 yInfo ( "%i Balls\n", numBalls );
459 yInfo ( "%i Hats\n", numHats );
460 yInfo ( "%i Buttons\n", numButtons );
461 yInfo ( "\n");
462
463 // check: selected joint MUST have at least one axis
464 if (numAxes<=0)
465 {
466 yError ( "Error: selected joystick has %d Axes?!\n",numAxes );
467 return false;
468 }
469
470 if (numAxes!=num_inputs)
471 {
472 if (force_cfg == false)
473 {
474 yWarning ( "Warning: # of joystick axes (%d) differs from # of configured input axes (%d)!\n",numAxes,num_inputs );
475 yWarning ( "This probably means that your .ini file does not containt a correct configuration.\n");
476 yWarning ( "Do you want to continue anyway (y/n)?\n");
477 char input[255];
478 cin >> input;
479 if (input[0]!='y' && input[0]!='Y')
480 {
481 yInfo ( "Quitting...\n");
482 return false;
483 }
484 else
485 {
486 yWarning ( "Overriding the number of axes specified in the configuration file. Using %d axes.\n",numAxes);
487 }
488 }
489 else
490 {
491 yWarning ( "Warning: # of joystick axes (%d) differs from # of configured input axes (%d)!\n",numAxes,num_inputs );
492 yWarning ( "This probably means that your .ini file does not containt a correct configuration.\n");
493 yWarning ( "However, --force_configuration option is enabled. This will override the number of axes specified in the configuration file.\n");
494 yWarning ( "Using %d axes.\n",numAxes);
495 }
496 }
497
498 rawAxes = new double [MAX_AXES];
499 rawHats = new int [MAX_AXES];
500 rawHatsOld = new int [MAX_AXES];
501 rawButtons = new int [MAX_AXES];
502 rawButtonsOld = new int [MAX_AXES];
503 outAxes = new double [MAX_AXES];
504
505 /*
506 // check: selected joint MUST have at least one button
507 if (numButtons>0)
508 rawButtons=new int [numButtons];
509 else
510 {
511 printf ( "Error reading numButtons\n" );
512 return false;
513 }*/
514 return true;
515 }
516
517 virtual void afterStart(bool s)
518 {
519 if (s)
520 yInfo ( "Thread started successfully\n");
521 else
522 yError ( "Thread did not start\n");
523
524 t0=Time::now();
525 }
526
527 virtual void run()
528 {
529 //check if driver is connected
530 /*
531 if (joy_id>SDL_NumJoysticks())
532 {
533 fprintf ( stderr, "Lost connection to driver!\n");
534 }
535 fprintf ( stderr, "%d\n",SDL_NumJoysticks());
536 */
537
538 // Updates the joystick status
539 SDL_JoystickUpdate ();
540
541 // Reading joystick data (axes/buttons...)
542 for ( int i=0; i < numButtons; ++i )
543 {
545 rawButtons[i] = SDL_JoystickGetButton ( joy1, i );
546 }
547
548 for ( int i=0; i < numHats; ++i )
549 {
550 rawHatsOld[i] = rawHats[i];
551 rawHats[i] = SDL_JoystickGetHat ( joy1, i );
552 }
553
554 for ( int i=0; i < numAxes; ++i )
555 {
556 rawAxes[i] = (double)SDL_JoystickGetAxis ( joy1, i );
557 }
558
559 // Formatting input data
560 for(int i=0;i<num_inputs;i++)
561 {
562 double v = rawAxes[i];
563 if (jointDeadband[i]>0)
564 {
565 if (fabs(v)<jointDeadband[i]) v=0;
566 }
567 if (reverse[i]==1)
568 v=-v;
569
570 if (inputMax[i]==inputMin[i])
571 {
572 v = 0;
573 }
574 else
575 {
576 v = (v<inputMax[i]) ? v : inputMax[i];
577 v = (v>inputMin[i]) ? v : inputMin[i];
578 v = v - ((inputMax[i]-inputMin[i])/2+inputMin[i]);
579 v = v / (inputMax[i]-inputMin[i]);
580 v = v * (outputMax[i]-outputMin[i]);
581 v = v + ((outputMax[i]-outputMin[i])/2+outputMin[i]);
582 }
583
584 /*
585 v = v+jointOffset[i];
586 v = v*jointGain[i];
587 v = (v<jointMax[i]) ? v : jointMax[i];
588 v = (v>jointMin[i]) ? v : jointMin[i];
589 */
590
591 rawAxes[i]=v;
592 }
593
594 // Sending data out on a Yarp port
595 Bottle data;
596 Bottle axis_data;
597 Bottle buttons_data;
598 for(int i=0;i<num_outputs;i++)
599 {
600 if (jointProperties[i].type == JTYPE_POLAR)
601 {
602 if (jointProperties[i].param[2] == 0)
603 {
604 outAxes[i]= atan2( (rawAxes[jointProperties[i].param[0]]),
605 (rawAxes[jointProperties[i].param[1]]) ) * 180.0 / 3.14159265;
606 }
607 else if (jointProperties[i].param[2] == 1)
608 {
609 outAxes[i]= sqrt ( pow((rawAxes[jointProperties[i].param[0]]),2)+
610 pow((rawAxes[jointProperties[i].param[1]]),2) );
611 }
612 else
613 {
614 outAxes[i]=0.0;
615 yWarning ( "Unknown parameter for JTYPE_POLAR, joint %d\n",i);
616 }
617 }
618 else if (jointProperties[i].type == JTYPE_CARTESIAN)
619 {
620 outAxes[i]=rawAxes[jointProperties[i].param[0]];
621 }
622 else if (jointProperties[i].type == JTYPE_CONSTANT)
623 {
624 outAxes[i]=(jointProperties[i].param[0]);
625 }
626 else if (jointProperties[i].type == JTYPE_BUTTON)
627 {
628 const int button_idx = jointProperties[i].param[0];
629 if (button_idx>=0 && button_idx<numButtons)
630 {
631 if (rawButtons[button_idx] == 0)
632 {
633 outAxes[i] = jointProperties[i].param[1];
634 }
635 else
636 {
637 outAxes[i] = jointProperties[i].param[2];
638 }
639 }
640 else
641 {
642 yWarning ( "Button id out of bounds (%d<%d)",button_idx,numButtons);
643 outAxes[i] = 0.0;
644 }
645 }
646 else
647 {
648 outAxes[i]=0.0;
649 yWarning ( "Unknown property, joint %d\n",i);
650 }
651 }
652
653 //execute button actions
654 for (int i=0;i<numButtons;i++)
655 {
656 if (rawButtonsOld[i] == 0 && rawButtons[i] == 1)
657 {
658 //execute script
659 if (!button_actions[i].empty())
660 {
661 yInfo ("executing script %d: %s\n", i, button_actions[i].c_str());
662 int ret = system(button_actions[i].c_str());
663 }
664 else
665 {
666 yWarning ("no scripts associated to button %d\n", i);
667 }
668 }
669 }
670
671 //execute button actions
672 for (int i=0;i<numHats;i++)
673 {
674 if (rawHats[i] != SDL_HAT_CENTERED)
675 {
676 //execute script
677 if (!hat_actions[i].empty())
678 {
679 string action(hat_actions[i]);
680 action += " ";
681 //if true, the behavior is like a button, one esecution per press
682 //if false, execution is continuous
683 bool trigger_mode=true;
684 switch(rawHats[i])
685 {
686 case SDL_HAT_UP:
687 action += "up";
688 break;
689 case SDL_HAT_RIGHT:
690 action += "right";
691 break;
692 case SDL_HAT_DOWN:
693 action += "down";
694 break;
695 case SDL_HAT_LEFT:
696 action += "left";
697 break;
698 case SDL_HAT_RIGHTUP:
699 action += "rightup";
700 break;
701 case SDL_HAT_RIGHTDOWN:
702 action += "rightdown";
703 break;
704 case SDL_HAT_LEFTUP:
705 action += "leftup";
706 break;
707 case SDL_HAT_LEFTDOWN:
708 action += "leftdown";
709 break;
710 default:
711 break;
712 }
713 if (trigger_mode)
714 {
715 if (rawHatsOld[i]==SDL_HAT_CENTERED)
716 {
717 yInfo ("executing script %d: %s\n", i, action.c_str());
718 int ret = system(action.c_str());
719 }
720 }
721 else
722 {
723 yInfo ("executing script %d: %s\n", i, action.c_str());
724 int ret = system(action.c_str());
725 }
726 }
727 else
728 {
729 yWarning ("no scripts associated to button %d\n", i);
730 }
731 }
732 }
733
734 // Preparing data to be sent on the yarp ports
735 for(int i=0;i<num_outputs;i++)
736 {
737 if ( jointProperties[i].type == JTYPE_STRING)
738 data.addString(jointProperties[i].param_s.c_str());
739 else
740 data.addFloat64(outAxes[i]);
741 }
742 for (int i=0;i<numButtons;i++)
743 {
744 buttons_data.addFloat64(rawButtons[i]);
745 }
746 for (int i=0;i<numAxes; i++)
747 {
748 axis_data.addFloat64(rawAxes[i]);
749 }
750
751 // Sending data on the yarp ports
752 if (port_command.getOutputCount()>0)
753 {
754 port_command.prepare() = data;
755 port_command.write();
756 }
757 if (port_axis_only.getOutputCount()>0)
758 {
759 port_axis_only.prepare() = axis_data;
760 port_axis_only.write();
761 }
762 if (port_buttons_only.getOutputCount()>0)
763 {
764 port_buttons_only.prepare() = buttons_data;
765 port_buttons_only.write();
766 }
767
768 // Displaying status
769 if (!silent) printStatus();
770 }
771
772 virtual void threadRelease()
773 {
774 if (rawAxes) delete [] rawAxes;
775 if (rawHats) delete [] rawHats;
776 if (rawHatsOld) delete [] rawHatsOld;
777 if (outAxes) delete [] outAxes;
778 if (rawButtons) delete [] rawButtons;
779 if (inputMax) delete [] inputMax;
780 if (inputMin) delete [] inputMin;
781 if (outputMax) delete [] outputMax;
782 if (outputMin) delete [] outputMin;
783 if (jointDeadband) delete [] jointDeadband;
784 if (jointProperties) delete [] jointProperties;
785 if (reverse) delete [] reverse;
786 port_command.interrupt();
787 port_command.close();
788 port_axis_only.interrupt();
789 port_axis_only.close();
790 port_buttons_only.interrupt();
791 port_buttons_only.close();
792 }
793
794
796 {
797 double t=Time::now();
798 std::ostringstream buff;
799
800 if (t-t0>=PRINT_STATUS_PER)
801 {
802 //for (int i=0;i <numButtons; i++)
803 // sprintf (buff, "%+6d", rawButtons[i] );
804
805 for (int i=0;i <numAxes; i++)
806 {
807 buff << std::setw(9) << std::fixed << std::setprecision(1) << rawAxes[i];
808 }
809 buff << " ---> ";
810 for (int i=0;i <num_outputs; i++)
811 {
812 buff << std::setw(9) << std::fixed << std::setprecision(1) << outAxes[i];
813 }
814 yDebug() << buff.str();
815 t0=t;
816 }
817 }
818};
819
820
821
822class CtrlModule: public RFModule
823{
824protected:
826 //Port rpcPort;
827
828public:
830
831 virtual bool configure(ResourceFinder &rf)
832 {
833 int rateThread = 10;
834 if (rf.findGroup("GENERAL").check("rateThread"))
835 {
836 rateThread = rf.findGroup("GENERAL").find("rateThread").asInt32();
837 }
838 else
839 {
840 yWarning ("rateThread option not found, assuming %d ms\n", rateThread);
841 }
842 thr=new CtrlThread(rateThread,rf);
843 if (!thr->start())
844 {
845 delete thr;
846 return false;
847 }
848
849 //rpcPort.open("/joystickCtrl/rpc");
850 //attach(rpcPort);
851
852 return true;
853 }
854
855 virtual bool close()
856 {
857 thr->stop();
858 delete thr;
859
860 //rpcPort.interrupt();
861 //rpcPort.close();
862
863 return true;
864 }
865
866 virtual double getPeriod() { return 1.0; }
867 virtual bool updateModule() { return true; }
868};
869
870
871
872int main(int argc, char *argv[])
873{
874 ResourceFinder rf;
875 rf.setDefaultConfigFile("joystickControl.ini"); //overridden by --from parameter
876 rf.setDefaultContext("joystickControl"); //overridden by --context parameter
877 rf.configure(argc,argv);
878
879 if (rf.check("help"))
880 {
881 yInfo ( "Options:\n");
882 yInfo ( "--silent: supress text output\n");
883 yInfo ( "--force_configuration: force a joystick configuration for a joystick with differnt # of axes, buttons etc.\n");
884 return 0;
885 }
886
887 Network yarp;
888
889 if (!yarp.checkNetwork())
890 {
891 yError("Sorry YARP network does not seem to be available, is the yarp server available?\n");
892 return -1;
893 }
894
895 //SDL_JoystickEventState (SDL_ENABLE);
896 // this will alter the behaviour of the event queue of the sdl system
897 SDL_JoystickEventState ( SDL_QUERY );
898
899 CtrlModule mod;
900
901 return mod.runModule(rf);
902}
903
904
905
@ data
virtual bool configure(ResourceFinder &rf)
Definition main.cpp:831
virtual double getPeriod()
Definition main.cpp:866
CtrlThread * thr
Definition main.cpp:373
CtrlModule()
Definition main.cpp:829
virtual bool updateModule()
Definition main.cpp:867
virtual bool close()
Definition main.cpp:855
BufferedPort< Bottle > port_buttons_only
Definition main.cpp:122
double t0
Definition main.cpp:166
double * rawAxes
Definition main.cpp:146
int * rawHatsOld
Definition main.cpp:145
virtual bool threadInit()
Definition main.cpp:185
string button_actions[20]
Definition main.cpp:136
int * rawButtonsOld
Definition main.cpp:143
int joy_id
Definition main.cpp:132
SDL_Joystick * joy1
Definition main.cpp:133
virtual void afterStart(bool s)
Definition main.cpp:517
virtual void threadRelease()
Definition main.cpp:772
int num_inputs
Definition main.cpp:150
int numButtons
Definition main.cpp:131
int numHats
Definition main.cpp:130
struct_jointProperties * jointProperties
Definition main.cpp:158
BufferedPort< Bottle > port_command
Definition main.cpp:120
int * rawButtons
Definition main.cpp:142
double defaultExecTime
Definition main.cpp:165
int * reverse
Definition main.cpp:157
int numAxes
Definition main.cpp:128
double * inputMin
Definition main.cpp:153
double * outputMax
Definition main.cpp:154
int * rawHats
Definition main.cpp:144
ResourceFinder & rf
Definition main.cpp:149
CtrlThread(unsigned int _period, ResourceFinder &_rf)
Definition main.cpp:161
string hat_actions[20]
Definition main.cpp:139
BufferedPort< Bottle > port_axis_only
Definition main.cpp:121
bool force_cfg
Definition main.cpp:124
bool silent
Definition main.cpp:123
double * jointDeadband
Definition main.cpp:156
double * outputMin
Definition main.cpp:155
double * inputMax
Definition main.cpp:152
virtual void run()
Definition main.cpp:527
int num_outputs
Definition main.cpp:151
int numBalls
Definition main.cpp:129
void printStatus()
Definition main.cpp:332
double * outAxes
Definition main.cpp:147
#define MAX_AXES
Definition main.cpp:105
#define PRINT_STATUS_PER
Definition main.cpp:104
@ JTYPE_CONSTANT
Definition main.cpp:107
@ JTYPE_UNDEF
Definition main.cpp:107
@ JTYPE_STRING
Definition main.cpp:107
@ JTYPE_CARTESIAN
Definition main.cpp:107
@ JTYPE_BUTTON
Definition main.cpp:107
@ JTYPE_POLAR
Definition main.cpp:107
int main()
Definition main.cpp:67
Copyright (C) 2008 RobotCub Consortium.
fprintf(fid,'\n')