icub-basic-demos
main.cpp
1 /*
2  * Copyright (C) 2011 Department of Robotics Brain and Cognitive Sciences - Istituto Italiano di Tecnologia
3  * Author: Marco Randazzo
4  * email: marco.randazzo@iit.it
5  * Permission is granted to copy, distribute, and/or modify this program
6  * under the terms of the GNU General Public License, version 2 or any
7  * later version published by the Free Software Foundation.
8  *
9  * A copy of the license can be found at
10  * http://www.robotcub.org/icub/license/gpl.txt
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15  * Public License for more details
16 */
17 
18 #include <yarp/os/all.h>
19 #include <yarp/sig/all.h>
20 #include <yarp/dev/all.h>
21 #include <iCub/ctrl/math.h>
22 #include <iCub/skinDynLib/skinContact.h>
23 #include <iCub/skinDynLib/skinContactList.h>
24 #include <string>
25 
26 #include "robot_interfaces.h"
27 
28 using namespace iCub::skinDynLib;
29 using namespace yarp::os;
30 using namespace yarp::sig;
31 using namespace yarp::dev;
32 using namespace std;
33 
34 #define POS 0
35 #define TRQ 1
36 
37 // robot->icmd[rd->id]->setPositionMode(0);
38 
39 
40 #define jjj 0
41 class CtrlThread: public yarp::os::PeriodicThread
42 {
43  public:
44  robot_interfaces *robot;
45  bool left_arm_master;
46  double encoders_master [16];
47  double encoders_slave [16];
48  bool autoconnect;
49  bool stiff;
50  Stamp info;
51 
52  BufferedPort<iCub::skinDynLib::skinContactList> *port_skin_contacts;
53  BufferedPort<Vector> *port_left_arm;
54  BufferedPort<Vector> *port_right_arm;
55 
56 
57  CtrlThread(unsigned int _period, ResourceFinder &_rf) :
58  PeriodicThread((double)_period/1000.0)
59  {
60  autoconnect = false;
61  robot=0;
62  left_arm_master=false;
63  port_skin_contacts=0;
64  stiff = _rf.check("stiff");
65  };
66 
67  virtual bool threadInit()
68  {
69  robot=new robot_interfaces(LEFT_ARM, RIGHT_ARM);
70  robot->init();
71 
72  port_skin_contacts = new BufferedPort<skinContactList>;
73  port_left_arm = new BufferedPort<Vector>;
74  port_right_arm = new BufferedPort<Vector>;
75  port_skin_contacts->open("/demoForceImitation/skin_contacts:i");
76  port_left_arm->open("/demoForceImitation/left_arm:o");
77  port_right_arm->open("/demoForceImitation/right_arm:o");
78 
79  if (autoconnect)
80  {
81  Network::connect("/skinManager/skin_events:o","/demoForceImitation/skin_contacs:i","tcp",false);
82  }
83 
84  robot->iimp[LEFT_ARM]->setImpedance(0,0.2,0.02);
85  robot->iimp[LEFT_ARM]->setImpedance(1,0.2,0.02);
86  robot->iimp[LEFT_ARM]->setImpedance(2,0.2,0.02);
87  robot->iimp[LEFT_ARM]->setImpedance(3,0.2,0.02);
88  robot->iimp[LEFT_ARM]->setImpedance(4,0.1,0.00);
89 
90  robot->iimp[RIGHT_ARM]->setImpedance(0,0.2,0.02);
91  robot->iimp[RIGHT_ARM]->setImpedance(1,0.2,0.02);
92  robot->iimp[RIGHT_ARM]->setImpedance(2,0.2,0.02);
93  robot->iimp[RIGHT_ARM]->setImpedance(3,0.2,0.02);
94  robot->iimp[RIGHT_ARM]->setImpedance(4,0.1,0.00);
95 
96  yInfo("Going to home position...");
97  for (int i=0; i<5; i++)
98  {
99  double tmp_pos=0.0;
100  robot->ienc[RIGHT_ARM]->getEncoder(i,&tmp_pos);
101  robot->icmd[LEFT_ARM]->setControlMode(i, VOCAB_CM_POSITION);
102  robot->icmd[RIGHT_ARM]->setControlMode(i, VOCAB_CM_POSITION);
103  robot->iint[LEFT_ARM]->setInteractionMode(i,VOCAB_IM_STIFF);
104  robot->iint[RIGHT_ARM]->setInteractionMode(i,VOCAB_IM_STIFF);
105  robot->ipos[LEFT_ARM]->setRefSpeed(i,10);
106  robot->ipos[LEFT_ARM]->positionMove(i,tmp_pos);
107  }
108  double timeout = 0;
109  do
110  {
111  int ok=0;
112  for (int i=0; i<5; i++)
113  {
114  double tmp_pos_l=0;
115  double tmp_pos_r=0;
116  robot->ienc[LEFT_ARM]->getEncoder(i,&tmp_pos_l);
117  robot->ienc[RIGHT_ARM]->getEncoder(i,&tmp_pos_r);
118  if (fabs(tmp_pos_l-tmp_pos_r)<1.0) ok++;
119  }
120  if (ok==5) break;
121  yarp::os::Time::delay(1.0);
122  timeout++;
123  }
124  while (timeout < 10); //10 seconds
125  if (timeout >=10)
126  {
127  yError("Unable to reach safe initial position! Closing module");
128  return false;
129  }
130 
131  change_master();
132 
133  yInfo("Position tracking started");
134  return true;
135  }
136  virtual void run()
137  {
138  int i_touching_left=0;
139  int i_touching_right=0;
140  int i_touching_diff=0;
141  info.update();
142 
143  skinContactList *skinContacts = port_skin_contacts->read(false);
144  if(skinContacts)
145  {
146  for(skinContactList::iterator it=skinContacts->begin(); it!=skinContacts->end(); it++){
147  if(it->getBodyPart() == LEFT_ARM)
148  i_touching_left += it->getActiveTaxels();
149  else if(it->getBodyPart() == RIGHT_ARM)
150  i_touching_right += it->getActiveTaxels();
151  }
152  }
153  i_touching_diff=i_touching_left-i_touching_right;
154 
155  if (abs(i_touching_diff)<5)
156  {
157  yInfo("nothing!\n");
158  }
159  else
160  if (i_touching_left>i_touching_right)
161  {
162  yInfo("Touching left arm! \n");
163  if (!left_arm_master) change_master();
164  }
165  else
166  if (i_touching_right>i_touching_left)
167  {
168  yInfo("Touching right arm! \n");
169  if (left_arm_master) change_master();
170  }
171 
172  if (left_arm_master)
173  {
174  robot->ienc[LEFT_ARM] ->getEncoders(encoders_master);
175  robot->ienc[RIGHT_ARM]->getEncoders(encoders_slave);
176  if (port_left_arm->getOutputCount()>0)
177  {
178  port_left_arm->prepare()= Vector(16,encoders_master);
179  port_left_arm->setEnvelope(info);
180  port_left_arm->write();
181  }
182  if (port_right_arm->getOutputCount()>0)
183  {
184  port_right_arm->prepare()= Vector(16,encoders_slave);
185  port_right_arm->setEnvelope(info);
186  port_right_arm->write();
187  }
188 
189  for (int i=jjj; i<5; i++)
190  {
191  robot->idir[RIGHT_ARM]->setPosition(i,encoders_master[i]);
192  }
193  }
194  else
195  {
196  robot->ienc[RIGHT_ARM]->getEncoders(encoders_master);
197  robot->ienc[LEFT_ARM] ->getEncoders(encoders_slave);
198  for (int i=jjj; i<5; i++)
199  {
200  robot->idir[LEFT_ARM]->setPosition(i,encoders_master[i]);
201  }
202 
203  }
204  }
205 
206  void change_master()
207  {
208  left_arm_master=(!left_arm_master);
209  if (left_arm_master)
210  {
211  for (int i=jjj; i<5; i++)
212  {
213  robot->icmd[LEFT_ARM]->setControlMode(i, VOCAB_CM_TORQUE);
214  robot->icmd[RIGHT_ARM]->setControlMode(i, VOCAB_CM_POSITION_DIRECT);
215  if (stiff==false) robot->iint[RIGHT_ARM]->setInteractionMode(i,VOCAB_IM_COMPLIANT);
216  else robot->iint[RIGHT_ARM]->setInteractionMode(i,VOCAB_IM_STIFF);
217  }
218  }
219  else
220  {
221  for (int i=jjj; i<5; i++)
222  {
223  robot->icmd[LEFT_ARM]->setControlMode(i, VOCAB_CM_POSITION_DIRECT);
224  if (stiff==false) robot->iint[LEFT_ARM]->setInteractionMode(i,VOCAB_IM_COMPLIANT);
225  else robot->iint[LEFT_ARM]->setInteractionMode(i,VOCAB_IM_STIFF);
226  robot->icmd[RIGHT_ARM]->setControlMode(i, VOCAB_CM_TORQUE);
227  }
228  }
229  }
230 
231  void closePort(Contactable *_port)
232  {
233  if (_port)
234  {
235  _port->interrupt();
236  _port->close();
237 
238  delete _port;
239  _port = 0;
240  }
241  }
242 
243  virtual void threadRelease()
244  {
245  for (int i=0; i<5; i++)
246  {
247  robot->icmd[LEFT_ARM] ->setControlMode(i, VOCAB_CM_POSITION);
248  robot->icmd[RIGHT_ARM]->setControlMode(i, VOCAB_CM_POSITION);
249  robot->iint[LEFT_ARM] ->setInteractionMode(i,VOCAB_IM_STIFF);
250  robot->iint[RIGHT_ARM]->setInteractionMode(i,VOCAB_IM_STIFF);
251  }
252  closePort(port_skin_contacts);
253  closePort(port_left_arm);
254  closePort(port_right_arm);
255  }
256 };
257 
258 
259 
260 class CtrlModule: public RFModule
261 {
262  public:
263  CtrlThread *control_thr;
264  CtrlModule();
265 
266  virtual bool configure(ResourceFinder &rf)
267  {
268  int rate = rf.check("period",Value(20)).asInt32();
269  control_thr=new CtrlThread(rate,rf);
270  if (!control_thr->start())
271  {
272  delete control_thr;
273  return false;
274  }
275  return true;
276  }
277 
278  virtual double getPeriod() { return 1.0; }
279  virtual bool updateModule() { return true; }
280  virtual bool close()
281  {
282  if (control_thr)
283  {
284  control_thr->stop();
285  delete control_thr;
286  }
287  return true;
288  }
289  bool respond(const Bottle& command, Bottle& reply)
290  {
291  yInfo("rpc respond, still to be implemented\n");
292  Bottle cmd;
293  reply.clear();
294 
295  return true;
296  }
297 };
298 
299 CtrlModule::CtrlModule()
300 {
301 
302 }
303 
304 int main(int argc, char * argv[])
305 {
306  ResourceFinder rf;
307  rf.configure(argc,argv);
308  //rf.setDefaultContext("empty");
309  //rf.setDefaultConfigFile("empty");
310 
311  if (rf.check("help"))
312  {
313  yInfo("help not yet implemented\n");
314  }
315 
316  //initialize yarp network
317  Network yarp;
318 
319  if (!yarp.checkNetwork())
320  {
321  yError("Sorry YARP network does not seem to be available, is the yarp server available?\n");
322  return 1;
323  }
324 
325  CtrlModule mod;
326 
327  return mod.runModule(rf);
328 }
329 
330