phymarxbot.cpp
1 /********************************************************************************
2  * WorldSim -- library for robot simulations *
3  * Copyright (C) 2012-2013 *
4  * Gianluca Massera <emmegian@yahoo.it> *
5  * Fabrizio Papi <erkito87@gmail.com> *
6  * *
7  * This program is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program; if not, write to the Free Software *
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
20  ********************************************************************************/
21 
22 #include "phymarxbot.h"
23 #include "phybox.h"
24 #include "phycylinder.h"
25 #include "phyfixed.h"
26 #include "phyballandsocket.h"
27 #include "physphere.h"
28 #include "physuspension.h"
29 #include "phycompoundobject.h"
30 #include "phycone.h"
31 #include "phyhinge.h"
32 #include "mathutils.h"
33 #include "graphicalmarkers.h"
34 #include <cmath>
35 
36 namespace farsa {
37 
38 const real PhyMarXbot::basex = 0.034f;
39 const real PhyMarXbot::basey = 0.143f;
40 const real PhyMarXbot::basez = 0.048f;
41 const real PhyMarXbot::basem = 0.4f;
42 const real PhyMarXbot::bodyr = 0.085f;
43 const real PhyMarXbot::bodyh = 0.0055f;
44 const real PhyMarXbot::bodym = 0.02f;
45 const real PhyMarXbot::axledistance = 0.104f;
46 const real PhyMarXbot::trackradius = 0.022f;
47 const real PhyMarXbot::trackheight = 0.0295f;
48 const real PhyMarXbot::trackm = 0.05f;
49 const real PhyMarXbot::treaddepth = 0.004f;
50 const real PhyMarXbot::wheelr = 0.027f;
51 const real PhyMarXbot::wheelh = 0.0215f;
52 const real PhyMarXbot::wheelm = 0.02f;
53 const real PhyMarXbot::turreth = 0.0385f;
54 const real PhyMarXbot::turretm = 0.08f;
55 const real PhyMarXbot::attachdevr = bodyr;
56 const real PhyMarXbot::attachdevx = turreth * 0.8f;
57 const real PhyMarXbot::attachdevy = turreth * 0.4f;
58 const real PhyMarXbot::attachdevz = turreth * 0.2f;
59 const real PhyMarXbot::attachdevm = 0.03f;
60 
61 PhyMarXbot::PhyMarXbot( World* w, QString name, const wMatrix& basetm ) : WObject( w, name, basetm, false ) {
62  kinematicSimulation = false;
63  frontMarker = NULL;
64 
65  // --- reference frame
66  // X
67  // ^
68  // | ------
69  // | ______|____|_________
70  // | |_|_| track |_|_|_|_|
71  // | -------------------
72  // | | battery |
73  // | -------------------
74  // | |_|_| track |_|_|_|_|
75  // | | |
76  // | ------
77  // |
78  // ---------------------> Y
79  // The front of the robot is towards -Y (positive speeds of the wheel make the robot move towards -Y)
80 
81  // --- create material for the marXbot
82  // introducing a semplification for the collision: two robot collide only with the attachring
83  w->materials().createMaterial( "marXbotLowerBody" );
84  w->materials().setElasticity( "marXbotLowerBody", "default", 0.01f );
85  w->materials().setSoftness( "marXbotLowerBody", "default", 0.01f );
86  w->materials().createMaterial( "marXbotUpperBody" );
87  w->materials().enableCollision( "marXbotLowerBody", "marXbotLowerBody", false );
88  w->materials().enableCollision( "marXbotLowerBody", "marXbotUpperBody", false );
89 
90  QVector<PhyObject*> objs;
91  PhyObject* obj;
93  // --- create the body of the base of the marxbot
94  obj = new PhyBox( basex+2.0f*trackheight, axledistance, basez+trackradius*2.0f, w );
95  obj->setMass( basem+bodym );
96  tm = wMatrix::identity();
97  tm.w_pos[2] = (basez+trackradius*2.0f)/2.0f + treaddepth;
98  obj->setMatrix( tm );
99  objs << obj;
100  // merge all togheter. Using a PhyCompoundObject even if there is only one object allows
101  // to displace the transformation matrix
102  basev = new PhyCompoundObject( objs, w, "base" );
103  basev->setMatrix( basetm );
104  basev->setMaterial("marXbotLowerBody");
105  basev->setUseColorTextureOfOwner( false );
106  basev->setOwner( this, false );
107 
108  // --- create the two external wheels
109  // they are motorized and they move the robot
110  // and create four spheres for supporting the tracks
111  // NOTE: the tracks are not simulated, they are just rigid bodies and
112  // the four sphere move freely in order to approximate the real movement
113  // --- position of wheels and their IDs in the vector
114  // +-----+
115  // |3|| ||2|
116  // |1| | | |0|
117  // |5|| ||4|
118  // +-----+
119  // --------------------> X
120  // arrays of X and Y offsets for calculate the positions
121  double xoffs[6] = { 1, -1, 1, -1, 1, -1 };
122  double yoffs[6] = { 0, 0, 1, 1, -1, -1 };
123  PhyObject* awheel;
124  PhyJoint* joint;
125  for( int i=0; i<6; i++ ) {
126  // --- relative to base
127  wMatrix wtm = wMatrix::identity();
128  wtm.w_pos = wVector(
129  xoffs[i] * (basex + trackheight)/2.0f + (yoffs[i]==0 ? xoffs[i]*(trackheight/2.0+wheelh/2.0f+0.006f) : 0.0f),
130  yoffs[i] * (axledistance/2.0f),
131  0.0f );
132  if ( i<2 ) {
133  // the two motorized wheels
134  wtm.w_pos[2] = wheelr;
135  awheel = new PhyCylinder( wheelr, wheelh, w, "motorWheel" );
136  } else {
137  // the four sphere supporting the track
138  wtm.w_pos[2] = treaddepth-0.003f;
139  awheel = new PhySphere( treaddepth, w, "passiveWheel" );
140  }
141  wheelstm.append( wtm );
142  awheel->setMass( wheelm );
143  awheel->setMaterial( "marXbotLowerBody" );
144  awheel->setUseColorTextureOfOwner( false );
145  awheel->setOwner( this, false );
146  awheel->setMatrix( wtm * basetm );
147  wheels.append( awheel );
148 
149  //--- create the joints
150  if ( i<2 ) {
151  // the two motorized wheels
152  joint = new PhySuspension(
153  basev->matrix().x_ax, // rotation axis
154  wheels[i]->matrix().w_pos,
155  basev->matrix().z_ax, // suspension 'vertical' axis
156  basev, wheels[i] );
157  joint->dofs()[0]->disableLimits();
158  } else {
159  // the four sphere supporting the track
160  joint = new PhyBallAndSocket(
161  wheels[i]->matrix().w_pos,
162  basev, wheels[i] );
163  }
164  joint->setOwner( this, false );
165  joint->updateJointInfo();
166  wheelJoints.append( joint );
167  }
168 
169  // Creating the turret
170  turretv = new PhyCylinder(bodyr, turreth, w);
171  turretv->setMass(turretm);
172  turrettm = wMatrix::yaw(toRad(-90.0f));
173  turrettm.w_pos.z = 0.005f + basez + bodyh + turreth + 0.0015f;
174  turretv->setMatrix(turrettm * basetm);
175  turretv->setMaterial("marXbotUpperBody");
176  turretv->setOwner(this, false);
177  turretv->setUseColorTextureOfOwner(true);
178 
179  // --- create the joint for sensing the force
180  forcesensor = new PhyFixed( basev, turretv, w );
181  forcesensor->setOwner( this, false );
182 
183  // By default the attachement device is disabled
184  attachdev = NULL;
185  attachdevjoint = NULL;
186  // We always create the attachment device controller, it will however not work unless the attachment
187  // device is enabled
188  attachdevCtrl = new MarXbotAttachmentDeviceMotorController(this);
189  attachdevCtrl->setOwner( this, false );
190 
191  // create the motor controller
192  QVector<PhyDOF*> motors;
193  motors << wheelJoints[0]->dofs()[0] << wheelJoints[1]->dofs()[0];
194  wheelsCtrl = new WheelMotorController( motors, w );
195  wheelsCtrl->setOwner( this, false );
196 #if defined(__GNUC__) && defined(DEVELOPER_WARNINGS)
197  #warning QUI DECIDERE PER LE VELOCITÀ MASSIME E MINIME DELLE RUOTE
198 #endif
199  wheelsCtrl->setSpeedLimits( -10.0, -10.0, 10.0, 10.0 );
200 
201  // Connecting wheels speed signals to be able to move the robot when in kinematic
202  connect(wheelJoints[0]->dofs()[0], SIGNAL(changedDesiredVelocity(real)), this, SLOT(setRightWheelDesideredVelocity(real)));
203  connect(wheelJoints[1]->dofs()[0], SIGNAL(changedDesiredVelocity(real)), this, SLOT(setLeftWheelDesideredVelocity(real)));
204 
205  // Creating the proximity IR sensors
206  QVector<SingleIR> sensors;
207 
208 #if defined(__GNUC__) && defined(DEVELOPER_WARNINGS)
209  #warning QUI DECIDERE PER I RANGE/APERTURE E LE POSIZIONI (SPECIE PER I GROUND)
210 #endif
211  // Adding the sensors. The marxbot has 24 proximity infrared sensors
212  for (unsigned int i = 0; i < 24; i++) {
213  const double curAngle = double(i) * (360.0 / 24.0) + ((360.0 / 24.0) / 2.0);
214  const double radius = bodyr;
215 
216  wMatrix mtr = wMatrix::yaw(toRad(curAngle + 90.0)) * wMatrix::pitch(PI_GRECO / 2.0);
217  mtr.w_pos.x = radius * cos(toRad(curAngle));
218  mtr.w_pos.y = radius * sin(toRad(curAngle));
219  mtr.w_pos.z = 0.005f + basez + bodyh + turreth / 2.0f + 0.0015f;
220 
221  sensors.append(SingleIR(basev, mtr, 0.0, 0.1, 10.0, 5));
222  }
223  proximityIR = new SimulatedIRProximitySensorController(world(), sensors);
224 
225  // Now creating the ground IR sensors below the battery pack
226  sensors.clear();
227  wMatrix mtr = wMatrix::yaw(PI_GRECO);
228  const double distFromBorder = 0.003;
229 
230  // Adding the sensors. The marxbot has 4 ground infrared sensors below the battery pack
231  mtr.w_pos = wVector(basex / 2.0f + trackheight - distFromBorder, axledistance / 2.0f - distFromBorder, treaddepth);
232  sensors.append(SingleIR(basev, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
233  mtr.w_pos = wVector(basex / 2.0f + trackheight - distFromBorder, -axledistance / 2.0f + distFromBorder, treaddepth);
234  sensors.append(SingleIR(basev, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
235  mtr.w_pos = wVector(-basex / 2.0f - trackheight + distFromBorder, axledistance / 2.0f - distFromBorder, treaddepth);
236  sensors.append(SingleIR(basev, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
237  mtr.w_pos = wVector(-basex / 2.0f - trackheight + distFromBorder, -axledistance / 2.0f + distFromBorder, treaddepth);
238  sensors.append(SingleIR(basev, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
239  groundBottomIR = new SimulatedIRGroundSensorController(world(), sensors);
240 
241  // Creating the ground IR sensors below the base
242  sensors.clear();
243 
244  // Adding the sensors. The marxbot has 8 ground infrared sensors below the base
245  for (unsigned int i = 0; i < 8; i++) {
246  const double curAngle = double(i) * (360.0 / 8.0);
247  const double radius = bodyr - 0.003;
248 
249  wMatrix mtr = wMatrix::yaw(PI_GRECO);
250  mtr.w_pos.x = radius * cos(toRad(curAngle));
251  mtr.w_pos.y = radius * sin(toRad(curAngle));
252  mtr.w_pos.z = 0.005f + basez + bodyh + turreth / 2.0f + 0.0015f;
253 
254  sensors.append(SingleIR(basev, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
255  }
256  groundAroundIR = new SimulatedIRGroundSensorController(world(), sensors);
257 
258  // Creating the traction sensor
259  tractionSensor = new TractionSensorController(world(), *forcesensor);
260 
261  w->pushObject( this );
262 
263  uniformColor.append(PhyCylinder::SegmentColor(SimpleInterval(-PI_GRECO, PI_GRECO), color()));
264 }
265 
267  // First of all signalling we are about to delete the attachment device (and all the rest)
268  attachdevCtrl->attachmentDeviceAboutToBeDestroyed();
269 
270  delete wheelsCtrl;
271  delete attachdevCtrl;
272  delete proximityIR;
273  delete groundBottomIR;
274  delete groundAroundIR;
275  foreach( PhyJoint* susp, wheelJoints ) {
276  delete susp;
277  }
278  foreach( PhyObject* w, wheels ) {
279  delete w;
280  }
281  delete forcesensor;
282  delete attachdevjoint;
283  delete turretv;
284  delete basev;
285  delete attachdev;
286 }
287 
289 {
290  // Updating motors
291  if (wheelsCtrl->isEnabled()) {
292  wheelsCtrl->update();
293  }
294  if (attachdevCtrl->isEnabled()) {
295  attachdevCtrl->update();
296  }
297 
298  if (kinematicSimulation) {
299  // In kinematic mode, we have to manually move the robot depending on the wheel velocities
300  wMatrix mtr = matrix();
301  wheeledRobotsComputeKinematicMovement(mtr, leftWheelVelocity, rightWheelVelocity, wheelr, wheelstm[0].w_pos.x - wheelstm[1].w_pos.x, world()->timeStep());
302 
303  // This will also update the position of all pieces
304  setMatrix(mtr);
305  }
306 }
307 
309 {
310  // Updating sensors
311  if (proximityIR->isEnabled()) {
312  proximityIR->update();
313  }
314  if (groundBottomIR->isEnabled()) {
315  groundBottomIR->update();
316  }
317  if (groundAroundIR->isEnabled()) {
318  groundAroundIR->update();
319  }
320 
321  // Updating the transformation matrix of the robot. It is coincident with the matrix of the base
322  tm = basev->matrix();
323 }
324 
325 void PhyMarXbot::setProximityIRSensorsGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
326 {
327  proximityIR->setGraphicalProperties(drawSensor, drawRay, drawRealRay);
328 }
329 
330 void PhyMarXbot::setGroundBottomIRSensorsGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
331 {
332  groundBottomIR->setGraphicalProperties(drawSensor, drawRay, drawRealRay);
333 }
334 
335 void PhyMarXbot::setGroundAroundIRSensorsGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
336 {
337  groundAroundIR->setGraphicalProperties(drawSensor, drawRay, drawRealRay);
338 }
339 
340 void PhyMarXbot::setDrawFrontMarker(bool drawMarker)
341 {
342  if (getDrawFrontMarker() == drawMarker) {
343  return;
344  }
345 
346  if (drawMarker) {
347  frontMarker = new PlanarArrowGraphicalMarker(PhyMarXbot::bodyr, PhyMarXbot::bodyr / 6.0f, PhyMarXbot::bodyr / 4.0f, 0.7f, world());
348  frontMarker->setUseColorTextureOfOwner(false);
349  frontMarker->setColor(Qt::green);
350  frontMarker->setTexture("");
351 
352  wMatrix displacement = wMatrix::roll(-PI_GRECO / 2.0f);
353  displacement.w_pos = wVector(0.0, 0.0, basez + trackradius * 2.0f + treaddepth + turreth - 0.010f + 0.0001f);
354  frontMarker->attachToObject(this, true, displacement);
355  } else {
356  delete frontMarker;
357  frontMarker = NULL;
358  }
359 }
360 
362 {
363  return (frontMarker != NULL);
364 }
365 
367 {
368  if (attachmentDeviceEnabled() == enable) {
369  return;
370  }
371 
372  if (enable) {
373  // This little cube shows the position of the attachment fingers
374  attachdev = new PhyBox(attachdevx, attachdevy, attachdevz, world());
375  attachdev->setMass(attachdevm);
376  attachdevtm = turretv->matrix();
377  attachdevtm.w_pos.y -= attachdevr;
378  attachdev->setMatrix(attachdevtm);
379  attachdev->setOwner(this, false);
380 
381  // Creating the joint for the attachment device
382  attachdevjoint = new PhyHinge(wVector(1.0f, 0.0, 0.0), wVector(0.0, 0.0, 0.0), 0.0, turretv, attachdev, world());
383  attachdevjoint->dofs()[0]->disableLimits();
384  attachdevjoint->dofs()[0]->setDesiredPosition(0.0); // This way the attachdev doesn't rotate
385  attachdevjoint->dofs()[0]->setStiffness(0.1f); // This way the attachdev motor is not very strong
386  attachdevjoint->setOwner(this, false);
387  } else {
388  // Notifying the attachment device controller
389  attachdevCtrl->attachmentDeviceAboutToBeDestroyed();
390  // Destroying the joint and the attachment device
391  delete attachdevjoint;
392  attachdevjoint = NULL;
393  delete attachdev;
394  attachdev = NULL;
395  }
396 }
397 
399 {
400  // If the attachment device is enabled, we simply disable and then re-enable it
401  if (attachmentDeviceEnabled()) {
402  enableAttachmentDevice(false);
404  }
405 }
406 
408 {
409  if (kinematicSimulation == k) {
410  return;
411  }
412 
413  kinematicSimulation = k;
414  if (kinematicSimulation) {
415  // First disabling all joints...
416  for (int i = 0; i < wheelJoints.size(); i++) {
417  wheelJoints[i]->enable(false);
418  }
419  forcesensor->enable(false);
420  if (attachdevjoint != NULL) {
421  attachdevjoint->enable(false);
422  }
423 
424  // ... then setting all objects to kinematic behaviour
425  basev->setKinematic(true, true);
426  for (int i = 0; i < wheels.size(); i++) {
427  wheels[i]->setKinematic(true, true);
428  }
429  turretv->setKinematic(true, true);
430  if (attachdev != NULL) {
431  attachdev->setKinematic(true, true);
432  }
433  } else {
434  // First setting all objects to dynamic behaviour...
435  basev->setKinematic(false);
436  for (int i = 0; i < wheels.size(); i++) {
437  wheels[i]->setKinematic(false);
438  }
439  turretv->setKinematic(false);
440  if (attachdev != NULL) {
441  attachdev->setKinematic(false);
442  }
443 
444  // ... then enabling all joints (if the corresponding part is enabled)
445  for (int i = 0; i < wheelJoints.size(); i++) {
446  wheelJoints[i]->enable(true);
447  wheelJoints[i]->updateJointInfo();
448  }
449  forcesensor->enable(true);
450  forcesensor->updateJointInfo();
451  if (attachdevjoint != NULL) {
452  attachdevjoint->enable(true);
453  attachdevjoint->updateJointInfo();
454  }
455  }
456 }
457 
458 #if defined(__GNUC__) && defined(DEVELOPER_WARNINGS)
459  #warning PROBLEMA RELATIVO AI LED DEL MARXBOT: NON C È L'ATTACHRING, SOLO LA TORRETTA CHE PERÃ’ È FISSA. NEL ROBOT REALE I LED SONO SULL' ATTACHRING, QUINDI RUOTANO (CONTROLLARE!!!), QUI SONO SULLA TORRETTA QUINDI SONO FISSI
460 #endif
461 void PhyMarXbot::setLedColors(QList<QColor> c)
462 {
463  if (c.size() != 12) {
464  return;
465  }
466 
467  turretv->setUseColorTextureOfOwner(false);
468 
469  ledColorsv = c;
470  QList<PhyCylinder::SegmentColor> s;
471  const real startAngle = (PI_GRECO / 2.0f) - (PI_GRECO / 12.0f);
472  for (int i = 0; i < 12; i++) {
473  const real rangeMin = (real(i) * PI_GRECO / 6.0) + startAngle;
474  const real rangeMax = (real(i + 1) * PI_GRECO / 6.0) + startAngle;
475  s.append(PhyCylinder::SegmentColor(SimpleInterval(normalizeRad(rangeMin), normalizeRad(rangeMax)), ledColorsv[i]));
476  }
477  turretv->setSegmentsColor(Qt::white, s);
478  turretv->setUpperBaseColor(color());
479  turretv->setLowerBaseColor(color());
480 }
481 
482 QList<QColor> PhyMarXbot::ledColors() const
483 {
484  if (ledColorsv.isEmpty()) {
485  QList<QColor> c;
486  for (int i = 0; i < 12; i++) {
487  c.append(color());
488  }
489  return c;
490  } else {
491  return ledColorsv;
492  }
493 }
494 
495 const QList<PhyCylinder::SegmentColor>& PhyMarXbot::segmentsColor() const
496 {
497  if (ledColorsv.isEmpty()) {
498  uniformColor[0].color = color();
499  return uniformColor;
500  } else {
501  return turretv->segmentsColor();
502  }
503 }
504 
506 {
507  leftWheelVelocity = velocity;
508 }
509 
511 {
512  rightWheelVelocity = velocity;
513 }
514 
516  wMatrix tm = matrix();
517  basev->setMatrix( tm );
518  for( int i=0; i<wheels.size(); i++ ) {
519  wheels[i]->setMatrix( wheelstm[i] * tm );
520  }
521  foreach( PhyJoint* ajoint, wheelJoints ) {
522  ajoint->updateJointInfo();
523  }
524  turretv->setMatrix( turrettm * tm );
525  forcesensor->updateJointInfo();
526  if ((attachdev != NULL) && (attachdevjoint != NULL)) {
527  attachdev->setMatrix( attachdevtm * tm );
528  attachdevjoint->updateJointInfo();
529  }
530 }
531 
532 namespace previous {
533  const real PhyMarXbot::basex = 0.034f;
534  const real PhyMarXbot::basey = 0.143f;
535  const real PhyMarXbot::basez = 0.048f;
536  const real PhyMarXbot::basem = 0.4f;
537  const real PhyMarXbot::bodyr = 0.085f;
538  const real PhyMarXbot::bodyh = 0.0055f;
539  const real PhyMarXbot::bodym = 0.02f;
540  const real PhyMarXbot::axledistance = 0.104f;
541  const real PhyMarXbot::trackradius = 0.022f;
542  const real PhyMarXbot::trackheight = 0.0295f;
543  const real PhyMarXbot::trackm = 0.05f;
544  const real PhyMarXbot::treaddepth = 0.004f;
545  const real PhyMarXbot::wheelr = 0.027f;
546  const real PhyMarXbot::wheelh = 0.0215f;
547  const real PhyMarXbot::wheelm = 0.02f;
548  const real PhyMarXbot::attachringh = 0.0285f;
549  const real PhyMarXbot::attachringm = 0.08f;
550  const real PhyMarXbot::ledsh = 0.010f;
551  const real PhyMarXbot::ledsradius = 0.080f;
552  const real PhyMarXbot::ledsm = 0.03f;
553 
554  PhyMarXbot::PhyMarXbot( World* w, QString name, const wMatrix& basetm ) : WObject( w, name, basetm, false ) {
555  kinematicSimulation = false;
556 
557  // --- reference frame
558  // X
559  // ^
560  // | ------
561  // | ______|____|_________
562  // | |_|_| track |_|_|_|_|
563  // | -------------------
564  // | | battery |
565  // | -------------------
566  // | |_|_| track |_|_|_|_|
567  // | | |
568  // | ------
569  // |
570  // ---------------------> Y
571  // The front of the robot is towards -Y (positive speeds of the wheel make the robot move towards -Y)
572 
573  // --- create material for the marXbot
574  // introducing a semplification for the collision: two robot collide only with the attachring
575  w->materials().createMaterial( "marXbotLowerBody" );
576  w->materials().setElasticity( "marXbotLowerBody", "default", 0.01f );
577  w->materials().setSoftness( "marXbotLowerBody", "default", 0.01f );
578  w->materials().createMaterial( "marXbotUpperBody" );
579  w->materials().enableCollision( "marXbotLowerBody", "marXbotLowerBody", false );
580  w->materials().enableCollision( "marXbotLowerBody", "marXbotUpperBody", false );
581 
582  QVector<PhyObject*> objs;
583  PhyObject* obj;
584  // --- create the body of the base of the marxbot
585  #ifdef MARXBOT_DETAILED
587  // battery container
588  obj = new PhyBox( basex, basey, basez, w );
589  tm.w_pos[2] = basez/2.0f + 0.015f;
590  obj->setMass( basem );
591  obj->setMatrix( tm );
592  objs << obj;
593  // cylinder body
594  obj = new PhyCylinder( bodyr, bodyh, w );
595  obj->setMass( bodym );
596  tm = wMatrix::yaw( toRad(90.0f) );
597  tm.w_pos[2] = 0.015f + basez + bodyh/2.0f;
598  obj->setMatrix( tm );
599  objs << obj;
600  // right track
601  obj = new PhyBox( trackheight, axledistance, trackradius*2.0f, w );
602  tm = wMatrix::identity();
603  tm.w_pos[0] = (basex + trackheight)/2.0f;
604  tm.w_pos[2] = trackradius + treaddepth;
605  obj->setMass( trackm );
606  obj->setMatrix( tm );
607  objs << obj;
608  obj = new PhyCylinder( trackradius, trackheight, w );
609  obj->setMass( wheelm );
610  tm.w_pos[1] = axledistance/2.0;
611  obj->setMatrix( tm );
612  objs << obj;
613  obj = new PhyCylinder( trackradius, trackheight, w );
614  obj->setMass( wheelm );
615  tm.w_pos[1] = -axledistance/2.0;
616  obj->setMatrix( tm );
617  objs << obj;
618  // left track
619  obj = new PhyBox( trackheight, axledistance, trackradius*2.0f, w );
620  tm = wMatrix::identity();
621  tm.w_pos[0] = -(basex + trackheight)/2.0f;
622  tm.w_pos[2] = trackradius + treaddepth;
623  obj->setMass( trackm );
624  obj->setMatrix( tm );
625  objs << obj;
626  obj = new PhyCylinder( trackradius, trackheight, w );
627  obj->setMass( wheelm );
628  tm.w_pos[1] = axledistance/2.0;
629  obj->setMatrix( tm );
630  objs << obj;
631  obj = new PhyCylinder( trackradius, trackheight, w );
632  obj->setMass( wheelm );
633  tm.w_pos[1] = -axledistance/2.0;
634  obj->setMatrix( tm );
635  objs << obj;
636  #else
637  // simplified version of the marxbot physic
638  obj = new PhyBox( basex+2.0f*trackheight, axledistance, basez+trackradius*2.0f, w );
639  obj->setMass( basem+bodym );
640  tm = wMatrix::identity();
641  tm.w_pos[2] = (basez+trackradius*2.0f)/2.0f + treaddepth;
642  obj->setMatrix( tm );
643  objs << obj;
644  #endif
645  // merge all togheter
646  base = new PhyCompoundObject( objs, w, "base" );
647  base->setMatrix( basetm );
648  base->setMaterial("marXbotLowerBody");
649  base->setOwner( this, false );
650 
651  // --- create the two external wheels
652  // they are motorized and they move the robot
653  // and create four spheres for supporting the tracks
654  // NOTE: the tracks are not simulated, they are just rigid bodies and
655  // the four sphere move freely in order to approximate the real movement
656  // --- position of wheels and their IDs in the vector
657  // +-----+
658  // |3|| ||2|
659  // |1| | | |0|
660  // |5|| ||4|
661  // +-----+
662  // --------------------> X
663  // arrays of X and Y offsets for calculate the positions
664  double xoffs[6] = { 1, -1, 1, -1, 1, -1 };
665  double yoffs[6] = { 0, 0, 1, 1, -1, -1 };
666  PhyObject* awheel;
667  PhyJoint* joint;
668  for( int i=0; i<6; i++ ) {
669  // --- relative to base
670  wMatrix wtm = wMatrix::identity();
671  wtm.w_pos = wVector(
672  xoffs[i] * (basex + trackheight)/2.0f + (yoffs[i]==0 ? xoffs[i]*(trackheight/2.0+wheelh/2.0f+0.006f) : 0.0f),
673  yoffs[i] * (axledistance/2.0f),
674  0.0f );
675  if ( i<2 ) {
676  // the two motorized wheels
677  wtm.w_pos[2] = wheelr;
678  awheel = new PhyCylinder( wheelr, wheelh, w, "motorWheel" );
679  } else {
680  // the four sphere supporting the track
681  wtm.w_pos[2] = treaddepth-0.003f;
682  awheel = new PhySphere( treaddepth, w, "passiveWheel" );
683  }
684  wheelstm.append( wtm );
685  awheel->setMass( wheelm );
686  awheel->setColor( Qt::blue );
687  awheel->setMaterial( "marXbotLowerBody" );
688  awheel->setOwner( this, false );
689  awheel->setMatrix( wtm * basetm );
690  wheels.append( awheel );
691 
692  //--- create the joints
693  if ( i<2 ) {
694  // the two motorized wheels
695  joint = new PhySuspension(
696  base->matrix().x_ax, // rotation axis
697  wheels[i]->matrix().w_pos,
698  base->matrix().z_ax, // suspension 'vertical' axis
699  base, wheels[i] );
700  joint->dofs()[0]->disableLimits();
701  } else {
702  // the four sphere supporting the track
703  joint = new PhyBallAndSocket(
704  wheels[i]->matrix().w_pos,
705  base, wheels[i] );
706  }
707  joint->setOwner( this, false );
708  joint->updateJointInfo();
709  wheelJoints.append( joint );
710  }
711 
712  // --- create the attachment module with the 12 RGB LEDs part
713  #ifdef MARXBOT_DETAILED
714  objs.clear();
715  obj = new PhyCone( bodyr, attachringh+0.010f, w );
716  obj->setMass( attachringm );
717  tm = wMatrix::identity();
718  tm.w_pos[0] = 0.005f;
719  obj->setMatrix( tm );
720  objs << obj;
721  obj = new PhyCone( bodyr, attachringh+0.010f, w );
722  obj->setMass( attachringm );
723  tm = wMatrix::roll( toRad(180.0f) );
724  tm.w_pos[0] = -0.005f;
725  obj->setMatrix( tm );
726  objs << obj;
727  obj = new PhyCylinder( ledsradius, ledsh, w );
728  obj->setMass( ledsm );
729  obj->setTexture( "marXbot_12leds" );
730  obj->setUseColorTextureOfOwner( false );
731  tm.w_pos[0] = attachringh/2.0f + ledsh/2.0f + 0.0015f;
732  obj->setMatrix( tm );
733  objs << obj;
734  #else
735  objs.clear();
736  obj = new PhyCylinder( bodyr, attachringh+ledsh, w );
737  obj->setMass( attachringm );
738  tm = wMatrix::identity();
739  tm.w_pos[0] = attachringh/2.0f-0.010f;
740  obj->setMatrix( tm );
741  objs << obj;
742  #endif
743  // merge all toghether
744  attachring = new PhyCompoundObject( objs, w );
745  attachring->setMaterial("marXbotUpperBody");
746  attachring->setOwner( this, false );
747  attachring->setUseColorTextureOfOwner( false );
748  attachringtm = wMatrix::yaw( toRad(-90.0f) );
749  attachringtm.w_pos[2] = 0.015f + basez + bodyh + attachringh/2.0f + 0.0015f;
750  attachring->setMatrix( attachringtm * basetm );
751  // --- create the joint for sensing the force
752  forcesensor = new PhyFixed( base, attachring, w );
753  forcesensor->setOwner( this, false );
754 
755  // create the motor controller
756  QVector<PhyDOF*> motors;
757  motors << wheelJoints[0]->dofs()[0] << wheelJoints[1]->dofs()[0];
758  wheelsCtrl = new WheelMotorController( motors, w );
759  wheelsCtrl->setOwner( this, false );
760  #if defined(__GNUC__) && defined(DEVELOPER_WARNINGS)
761  #warning QUI DECIDERE PER LE VELOCITÀ MASSIME E MINIME DELLE RUOTE
762  #endif
763  wheelsCtrl->setSpeedLimits( -10.0, -10.0, 10.0, 10.0 );
764 
765  // Connecting wheels speed signals to be able to move the robot when in kinematic
766  connect(wheelJoints[0]->dofs()[0], SIGNAL(changedDesiredVelocity(real)), this, SLOT(setRightWheelDesideredVelocity(real)));
767  connect(wheelJoints[1]->dofs()[0], SIGNAL(changedDesiredVelocity(real)), this, SLOT(setLeftWheelDesideredVelocity(real)));
768 
769  // Creating the proximity IR sensors
770  QVector<SingleIR> sensors;
771 
772  #if defined(__GNUC__) && defined(DEVELOPER_WARNINGS)
773  #warning QUI DECIDERE PER I RANGE/APERTURE E LE POSIZIONI (SPECIE PER I GROUND)
774  #endif
775  // Adding the sensors. The marxbot has 24 proximity infrared sensors
776  for (unsigned int i = 0; i < 24; i++) {
777  const double curAngle = double(i) * (360.0 / 24.0) + ((360.0 / 24.0) / 2.0);
778  const double radius = bodyr;
779 
780  wMatrix mtr = wMatrix::yaw(toRad(curAngle + 90.0)) * wMatrix::pitch(PI_GRECO / 2.0);
781  mtr.w_pos.x = radius * cos(toRad(curAngle));
782  mtr.w_pos.y = radius * sin(toRad(curAngle));
783  mtr.w_pos.z = 0.015f + basez + bodyh/2.0f;
784 
785  sensors.append(SingleIR(base, mtr, 0.02, 0.1, 10.0, 5));
786  }
787  proximityIR = new SimulatedIRProximitySensorController(world(), sensors);
788 
789  // Now creating the ground IR sensors below the battery pack
790  sensors.clear();
791  wMatrix mtr = wMatrix::yaw(PI_GRECO);
792  const double distFromBorder = 0.003;
793 
794  // Adding the sensors. The marxbot has 4 ground infrared sensors below the battery pack
795  mtr.w_pos = wVector(basex / 2.0f - distFromBorder, basey / 2.0f - distFromBorder, 0.015f);
796  sensors.append(SingleIR(base, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
797  mtr.w_pos = wVector(basex / 2.0f - distFromBorder, -basey / 2.0f + distFromBorder, 0.015f);
798  sensors.append(SingleIR(base, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
799  mtr.w_pos = wVector(-basex / 2.0f + distFromBorder, basey / 2.0f - distFromBorder, 0.015f);
800  sensors.append(SingleIR(base, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
801  mtr.w_pos = wVector(-basex / 2.0f + distFromBorder, -basey / 2.0f + distFromBorder, 0.015f);
802  sensors.append(SingleIR(base, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
803  groundBottomIR = new SimulatedIRGroundSensorController(world(), sensors);
804 
805  // Creating the ground IR sensors below the base
806  sensors.clear();
807 
808  // Adding the sensors. The marxbot has 8 ground infrared sensors below the base
809  for (unsigned int i = 0; i < 8; i++) {
810  const double curAngle = double(i) * (360.0 / 8.0);
811  const double radius = bodyr - 0.003;
812 
813  wMatrix mtr = wMatrix::yaw(PI_GRECO);
814  mtr.w_pos.x = radius * cos(toRad(curAngle));
815  mtr.w_pos.y = radius * sin(toRad(curAngle));
816  mtr.w_pos.z = 0.015f + basez;
817 
818  sensors.append(SingleIR(base, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
819  }
820  groundAroundIR = new SimulatedIRGroundSensorController(world(), sensors);
821 
822  // Creating the traction sensor
823  tractionSensor = new TractionSensorController(world(), *forcesensor);
824 
825  w->pushObject( this );
826  }
827 
829  foreach( PhyJoint* susp, wheelJoints ) {
830  delete susp;
831  }
832  foreach( PhyObject* w, wheels ) {
833  delete w;
834  }
835  delete wheelsCtrl;
836  delete forcesensor;
837  delete attachring;
838  delete base;
839  delete proximityIR;
840  delete groundBottomIR;
841  delete groundAroundIR;
842  }
843 
845  {
846  // Updating motors
847  if (wheelsCtrl->isEnabled()) {
848  wheelsCtrl->update();
849  }
850 
851  if (kinematicSimulation) {
852  // In kinematic mode, we have to manually move the robot depending on the wheel velocities
853  wMatrix mtr = matrix();
854  wheeledRobotsComputeKinematicMovement(mtr, leftWheelVelocity, rightWheelVelocity, wheelr, wheelstm[0].w_pos.x - wheelstm[1].w_pos.x, world()->timeStep());
855 
856  // This will also update the position of all pieces
857  setMatrix(mtr);
858  }
859  }
860 
862  {
863  // Updating sensors
864  if (proximityIR->isEnabled()) {
865  proximityIR->update();
866  }
867  if (groundBottomIR->isEnabled()) {
868  groundBottomIR->update();
869  }
870  if (groundAroundIR->isEnabled()) {
871  groundAroundIR->update();
872  }
873 
874  // Updating the transformation matrix of the robot. It is coincident with the matrix of the base
875  tm = base->matrix();
876  }
877 
878  void PhyMarXbot::setProximityIRSensorsGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
879  {
880  proximityIR->setGraphicalProperties(drawSensor, drawRay, drawRealRay);
881  }
882 
883  void PhyMarXbot::setGroundBottomIRSensorsGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
884  {
885  groundBottomIR->setGraphicalProperties(drawSensor, drawRay, drawRealRay);
886  }
887 
888  void PhyMarXbot::setGroundAroundIRSensorsGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
889  {
890  groundAroundIR->setGraphicalProperties(drawSensor, drawRay, drawRealRay);
891  }
892 
894  {
895  if (kinematicSimulation == k) {
896  return;
897  }
898 
899  kinematicSimulation = k;
900  if (kinematicSimulation) {
901  // First disabling all joints...
902  for (int i = 0; i < wheelJoints.size(); i++) {
903  wheelJoints[i]->enable(false);
904  }
905  forcesensor->enable(false);
906 
907  // ... then setting all objects to kinematic behaviour
908  base->setKinematic(true, true);
909  for (int i = 0; i < wheels.size(); i++) {
910  wheels[i]->setKinematic(true, true);
911  }
912  attachring->setKinematic(true, true);
913  } else {
914  // First setting all objects to dynamic behaviour...
915  base->setKinematic(false);
916  for (int i = 0; i < wheels.size(); i++) {
917  wheels[i]->setKinematic(false);
918  }
919  attachring->setKinematic(false);
920 
921  // ... then enabling all joints (if the corresponding part is enabled)
922  for (int i = 0; i < wheelJoints.size(); i++) {
923  wheelJoints[i]->enable(true);
924  wheelJoints[i]->updateJointInfo();
925  }
926  forcesensor->enable(true);
927  forcesensor->updateJointInfo();
928  }
929  }
930 
932  {
933  leftWheelVelocity = velocity;
934  }
935 
937  {
938  rightWheelVelocity = velocity;
939  }
940 
942  wMatrix tm = matrix();
943  base->setMatrix( tm );
944  for( int i=0; i<wheels.size(); i++ ) {
945  wheels[i]->setMatrix( wheelstm[i] * tm );
946  }
947  foreach( PhyJoint* ajoint, wheelJoints ) {
948  ajoint->updateJointInfo();
949  }
950  attachring->setMatrix( attachringtm * tm );
951  forcesensor->updateJointInfo();
952  }
953 }
954 
955 } // end namespace farsa
FARSA_UTIL_TEMPLATE real toRad(real x)
void enableCollision(QString mat1, QString mat2, bool enable=true)
Enable/Disable the collision between materials passed.
Definition: world.cpp:119
World's Object class.
Definition: wobject.h:39
static wMatrix identity()
create an identity matrix
Definition: wmatrix.h:460
void setKinematic(bool b, bool c=false)
Changes between kinematic/dynamic behaviour for the object.
Definition: phyobject.cpp:56
wMatrix tm
Trasformation matrix.
Definition: wobject.h:193
PhySphere class.
Definition: physphere.h:37
The class modelling the motor for the attachment device of the MarXbot.
FARSA_UTIL_TEMPLATE real normalizeRad(real x)
void enable(bool b)
enable/disable the joint
Definition: phyjoint.cpp:63
void resetAttachmentDevice()
Resets the attachment device.
Definition: phymarxbot.cpp:398
void setUseColorTextureOfOwner(bool b)
set if the object will be rendered with the color and texture of our owner (if we have one) ...
Definition: wobject.cpp:97
void setMass(real)
Set the mass without touching the Inertia data.
Definition: phyobject.cpp:219
virtual void postUpdate()
postUpdate the robot this method is called at each step of the world just after the physic update...
Definition: phymarxbot.cpp:308
void setLowerBaseColor(QColor color)
Sets the color of the lower base.
Definition: phycylinder.cpp:64
void setLeftWheelDesideredVelocity(real velocity)
Sets the desidered velocity of the left wheel.
Definition: phymarxbot.cpp:505
World * world()
Return the world.
Definition: wobject.cpp:61
virtual void updateJointInfo()
Update the Joint informations (each PhyDOF will be updated)
Definition: phyhinge.cpp:181
QColor color() const
return the color of this object
Definition: wobject.cpp:89
PhyFixed class.
Definition: phyfixed.h:43
virtual void updateJointInfo()=0
Update the Joint informations (each PhyDOF will be updated)
void setUpperBaseColor(QColor color)
Sets the color of the upper base.
Definition: phycylinder.cpp:51
void attachToObject(WObject *object, bool makeOwner=false, const wMatrix &displacement=wMatrix::identity())
Attaches this object to another WObject.
void setTexture(QString textureName)
Set the texture to use for this WObject when rendered.
Definition: wobject.cpp:73
virtual ~PhyMarXbot()
Destroy the MarXbot.
Definition: phymarxbot.cpp:266
virtual void postUpdate()
postUpdate the robot this method is called at each step of the world just after the physic update ...
Definition: phymarxbot.cpp:861
void setRightWheelDesideredVelocity(real velocity)
Sets the desidered velocity of the right wheel.
Definition: phymarxbot.cpp:936
World class.
Definition: world.h:223
void setGroundAroundIRSensorsGraphicalProperties(bool drawSensor, bool drawRay=false, bool drawRealRay=false)
Sets whether ground around IR sensors are drawn or not and how.
Definition: phymarxbot.cpp:335
void setColor(QColor c)
Set the color to use on rendering.
Definition: wobject.cpp:81
virtual QVector< PhyDOF * > dofs()
Return descriptions of DOF.
Definition: phyjoint.h:391
static wMatrix roll(real ang)
create a rotation around Z axis of ang radians
Definition: wmatrix.h:512
static wMatrix pitch(real ang)
create a rotation around X axis of ang radians
Definition: wmatrix.h:494
bool isEnabled()
Returns true if the sensor is enabled.
const QList< PhyCylinder::SegmentColor > & segmentsColor() const
Returns the colors of segments of the attachring.
Definition: phymarxbot.cpp:495
void setSpeedLimits(QVector< double > minSpeeds, QVector< double > maxSpeeds)
sets the minimum and maximum velocities for each wheel
PhyMarXbot(World *world, QString name, const wMatrix &tm=wMatrix::identity())
Create a MarXbot.
Definition: phymarxbot.cpp:61
The structure used to define the color of intervals of the cylinder.
Definition: phycylinder.h:63
void setElasticity(QString mat1, QString mat2, real)
configure the default Elasticity between materials specified the order doesn't matter ...
Definition: world.cpp:80
PhyJoint class.
Definition: phyjoint.h:359
virtual void update()
Updates sensor reading.
wMatrix class
Definition: wmatrix.h:48
void setLedColors(QList< QColor > c)
Sets the color of the leds on the attachring of the MarXbot.
Definition: phymarxbot.cpp:461
const wMatrix & matrix() const
return a reference to the transformation matrix
Definition: wobject.cpp:47
bool attachmentDeviceEnabled() const
Returns true if the attachment device is enabled.
Definition: phymarxbot.h:178
void setGroundBottomIRSensorsGraphicalProperties(bool drawSensor, bool drawRay=false, bool drawRealRay=false)
Sets whether ground bottom IR sensors are drawn or not and how.
Definition: phymarxbot.cpp:883
PhyMarXbot(World *world, QString name, const wMatrix &tm=wMatrix::identity())
Create a MarXbot.
Definition: phymarxbot.cpp:554
virtual void update()
Updates sensor reading.
void setSoftness(QString mat1, QString mat2, real)
configure the default Softness between materials specified the order doesn't matter ...
Definition: world.cpp:93
PhyCompoundObject class.
PhySuspension class PhySuspension is a joint implementing the system of springs, shock absorbers and ...
Definition: physuspension.h:41
void doKinematicSimulation(bool k)
Changes the robot model from dynamic to kinematic and vice-versa.
Definition: phymarxbot.cpp:407
void setProximityIRSensorsGraphicalProperties(bool drawSensor, bool drawRay=false, bool drawRealRay=false)
Sets whether proximity IR sensors are drawn or not and how.
Definition: phymarxbot.cpp:325
void setGroundAroundIRSensorsGraphicalProperties(bool drawSensor, bool drawRay=false, bool drawRealRay=false)
Sets whether ground around IR sensors are drawn or not and how.
Definition: phymarxbot.cpp:888
bool getDrawFrontMarker() const
Returns whether a marker in the front part of the robot is drawn or not.
Definition: phymarxbot.cpp:361
void setOwner(Ownable *owner, bool destroy=true)
Sets the owner of this object.
Definition: ownable.cpp:47
virtual void preUpdate()
preUpdate the robot this method is called at each step of the world just before the physic update...
Definition: phymarxbot.cpp:288
virtual void preUpdate()
preUpdate the robot this method is called at each step of the world just before the physic update ...
Definition: phymarxbot.cpp:844
bool isEnabled()
return true is if enable (hence if it is on)
bool createMaterial(QString name)
Create a new material It return false if already exists a material with name passed.
Definition: world.cpp:40
A collection of SingleIR modelling ground sensors.
const QList< SegmentColor > & segmentsColor() const
Returns the color of segments of the cylinder.
Definition: phycylinder.h:180
A single proximity IR sensor.
float real
MaterialDB & materials()
return the MaterialDB object for managing World's materials
Definition: world.h:334
void setDrawFrontMarker(bool drawMarker)
Whether to draw a marker in the front part of the robot or not.
Definition: phymarxbot.cpp:340
The controller for traction sensor.
void setSegmentsColor(QColor base, const QList< SegmentColor > &segmentsColor)
Sets the color of segments of the cylinder.
void setGroundBottomIRSensorsGraphicalProperties(bool drawSensor, bool drawRay=false, bool drawRealRay=false)
Sets whether ground bottom IR sensors are drawn or not and how.
Definition: phymarxbot.cpp:330
static wMatrix yaw(real ang)
create a rotation around Y axis of ang radians
Definition: wmatrix.h:503
void enableAttachmentDevice(bool enable)
Enables or disables the attachment device.
Definition: phymarxbot.cpp:366
virtual void update()
apply the velocities on the wheels
virtual void changedMatrix()
update the matrix of all sub-objects
Definition: phymarxbot.cpp:941
void setGraphicalProperties(bool drawSensor, bool drawRay=false, bool drawRealRay=false)
Sets graphical properties of all sensors.
PhyCylinder class.
Definition: phycylinder.h:53
void setMatrix(const wMatrix &newm)
set a new matrix
Definition: wobject.cpp:109
void setProximityIRSensorsGraphicalProperties(bool drawSensor, bool drawRay=false, bool drawRealRay=false)
Sets whether proximity IR sensors are drawn or not and how.
Definition: phymarxbot.cpp:878
void setRightWheelDesideredVelocity(real velocity)
Sets the desidered velocity of the right wheel.
Definition: phymarxbot.cpp:510
A graphical object displaying a planar arrow.
PhyBallAndSocket class.
PhyBox class.
Definition: phybox.h:37
QList< QColor > ledColors() const
Returns the color of the leds on the attachring.
Definition: phymarxbot.cpp:482
PhyCone class.
Definition: phycone.h:37
void doKinematicSimulation(bool k)
Changes the robot model from dynamic to kinematic and vice-versa.
Definition: phymarxbot.cpp:893
virtual void changedMatrix()
update the matrix of all sub-objects
Definition: phymarxbot.cpp:515
virtual void update()
The method updating the attachment device at each timestep.
Dedicated controller for wheeled robots.
virtual void updateJointInfo()
Update the Joint informations (each PhyDOF will be updated)
Definition: phyfixed.cpp:79
PhyObject class.
Definition: phyobject.h:46
void setGraphicalProperties(bool drawSensor, bool drawRay=false, bool drawRealRay=false)
Sets graphical properties of all sensors.
void setLeftWheelDesideredVelocity(real velocity)
Sets the desidered velocity of the left wheel.
Definition: phymarxbot.cpp:931
PhyHinge class.
Definition: phyhinge.h:43
virtual ~PhyMarXbot()
Destroy the MarXbot.
Definition: phymarxbot.cpp:828