00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "phymarxbot.h"
00023 #include "phybox.h"
00024 #include "phycylinder.h"
00025 #include "phyfixed.h"
00026 #include "phyballandsocket.h"
00027 #include "physphere.h"
00028 #include "physuspension.h"
00029 #include "phycompoundobject.h"
00030 #include "phycone.h"
00031 #include "mathutils.h"
00032
00033 namespace farsa {
00034
00035 PhyMarXbot::PhyMarXbot( World* w, QString name, const wMatrix& basetm ) : WObject( w, name, basetm, false ) {
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 real basex = 0.034f, basey = 0.143f, basez = 0.048f, basem = 0.4f;
00054
00055 real bodyr = 0.085f, bodyh = 0.0055f, bodym = 0.02f;
00056
00057 real axledistance = 0.104f, trackradius = 0.022f, trackheight = 0.0295f,trackm = 0.05f;
00058
00059 real treaddepth = 0.004f;
00060
00061 real wheelr = 0.027f, wheelh = 0.0215f, wheelm = 0.02f;
00062
00063 real attachringh = 0.0285f, attachringm = 0.08f;
00064
00065 real ledsh = 0.010f, ledsradius = 0.080f, ledsm = 0.03f;
00066
00067
00068 w->materials().createMaterial( "marXbotMaterial" );
00069 w->materials().setProperties( "marXbotMaterial", "default", 0.0f, 0.0f, 0.01f, 0.01f, true );
00070 w->materials().createMaterial( "marXbotTire" );
00071 w->materials().setProperties( "marXbotTire", "default", 1.2f, 0.9f, 0.01f, 0.01f, true );
00072
00073
00074 QVector<PhyObject*> objs;
00075 wMatrix tm = wMatrix::identity();
00076
00077 PhyObject* obj = new PhyBox( basex, basey, basez, w );
00078 tm.w_pos[2] = basez/2.0f + 0.015f;
00079 obj->setMass( basem );
00080 obj->setMatrix( tm );
00081 objs << obj;
00082
00083 obj = new PhyCylinder( bodyr, bodyh, w );
00084 obj->setMass( bodym );
00085 tm = wMatrix::yaw( toRad(90.0f) );
00086 tm.w_pos[2] = 0.015f + basez + bodyh/2.0f;
00087 obj->setMatrix( tm );
00088 objs << obj;
00089
00090 obj = new PhyBox( trackheight, axledistance, trackradius*2.0f, w );
00091 tm = wMatrix::identity();
00092 tm.w_pos[0] = (basex + trackheight)/2.0f;
00093 tm.w_pos[2] = trackradius + treaddepth;
00094 obj->setMass( trackm );
00095 obj->setMatrix( tm );
00096 objs << obj;
00097 obj = new PhyCylinder( trackradius, trackheight, w );
00098 obj->setMass( wheelm );
00099 tm.w_pos[1] = axledistance/2.0;
00100 obj->setMatrix( tm );
00101 objs << obj;
00102 obj = new PhyCylinder( trackradius, trackheight, w );
00103 obj->setMass( wheelm );
00104 tm.w_pos[1] = -axledistance/2.0;
00105 obj->setMatrix( tm );
00106 objs << obj;
00107
00108 obj = new PhyBox( trackheight, axledistance, trackradius*2.0f, w );
00109 tm = wMatrix::identity();
00110 tm.w_pos[0] = -(basex + trackheight)/2.0f;
00111 tm.w_pos[2] = trackradius + treaddepth;
00112 obj->setMass( trackm );
00113 obj->setMatrix( tm );
00114 objs << obj;
00115 obj = new PhyCylinder( trackradius, trackheight, w );
00116 obj->setMass( wheelm );
00117 tm.w_pos[1] = axledistance/2.0;
00118 obj->setMatrix( tm );
00119 objs << obj;
00120 obj = new PhyCylinder( trackradius, trackheight, w );
00121 obj->setMass( wheelm );
00122 tm.w_pos[1] = -axledistance/2.0;
00123 obj->setMatrix( tm );
00124 objs << obj;
00125
00126 base = new PhyCompoundObject( objs, w );
00127 base->setMaterial("marXbotMaterial");
00128 base->setOwner( this, false );
00129 base->setMatrix( basetm );
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 double xoffs[6] = { 1, -1, 1, -1, 1, -1 };
00145 double yoffs[6] = { 0, 0, 1, 1, -1, -1 };
00146 PhyObject* awheel;
00147 PhyJoint* joint;
00148 for( int i=0; i<6; i++ ) {
00149
00150 wMatrix wtm = wMatrix::identity();
00151 wtm.w_pos = wVector(
00152 xoffs[i] * (basex + trackheight)/2.0f + (yoffs[i]==0 ? xoffs[i]*(trackheight/2.0+wheelh/2.0f+0.006f) : 0.0f),
00153 yoffs[i] * (axledistance/2.0f),
00154 0.0f );
00155 if ( i<2 ) {
00156
00157 wtm.w_pos[2] = wheelr;
00158 awheel = new PhyCylinder( wheelr, wheelh, w );
00159 } else {
00160
00161 wtm.w_pos[2] = treaddepth;
00162 awheel = new PhySphere( treaddepth, w );
00163 }
00164 wheelstm.append( wtm );
00165 awheel->setMass( wheelm );
00166 awheel->setColor( Qt::blue );
00167 awheel->setMaterial( "marXbotTire" );
00168 awheel->setOwner( this, false );
00169 awheel->setMatrix( wtm * basetm );
00170 wheels.append( awheel );
00171
00172
00173 if ( i<2 ) {
00174
00175 joint = new PhySuspension(
00176 base->matrix().x_ax,
00177 wheels[i]->matrix().w_pos,
00178 base->matrix().z_ax,
00179 base, wheels[i] );
00180 joint->dofs()[0]->disableLimits();
00181 } else {
00182
00183 joint = new PhyBallAndSocket(
00184 wheels[i]->matrix().w_pos,
00185 base, wheels[i] );
00186 }
00187 joint->setOwner( this, false );
00188 joint->updateJointInfo();
00189 wheelJoints.append( joint );
00190 }
00191
00192
00193 QVector<PhyDOF*> motors;
00194 motors << wheelJoints[0]->dofs()[0] << wheelJoints[1]->dofs()[0];
00195 wheelsCtrl = new WheelMotorController( motors, w );
00196 wheelsCtrl->setOwner( this, false );
00197 #ifdef __GNUC__
00198 #warning QUI DECIDERE PER LE VELOCITÀ MASSIME E MINIME DELLE RUOTE
00199 #endif
00200 wheelsCtrl->setSpeedLimits( -10.0, -10.0, 10.0, 10.0 );
00201
00202
00203 objs.clear();
00204 obj = new PhyCone( bodyr, attachringh+0.010f, w );
00205 obj->setMass( attachringm );
00206 tm = wMatrix::identity();
00207 tm.w_pos[0] = 0.005f;
00208 obj->setMatrix( tm );
00209 objs << obj;
00210 obj = new PhyCone( bodyr, attachringh+0.010f, w );
00211 obj->setMass( attachringm );
00212 tm = wMatrix::roll( toRad(180.0f) );
00213 tm.w_pos[0] = -0.005f;
00214 obj->setMatrix( tm );
00215 objs << obj;
00216 obj = new PhyCylinder( ledsradius, ledsh, w );
00217 obj->setMass( ledsm );
00218 obj->setTexture( "marXbot_12leds" );
00219 obj->setUseColorTextureOfOwner( false );
00220 tm.w_pos[0] = attachringh/2.0f + ledsh/2.0f + 0.0015f;
00221 obj->setMatrix( tm );
00222 objs << obj;
00223
00224 attachring = new PhyCompoundObject( objs, w );
00225 attachring->setMaterial("marXbotMaterial");
00226 attachring->setOwner( this, false );
00227 attachring->setUseColorTextureOfOwner( false );
00228 attachringtm = wMatrix::yaw( toRad(-90.0f) );
00229 attachringtm.w_pos[2] = 0.015f + basez + bodyh + attachringh/2.0f + 0.0015f;
00230 attachring->setMatrix( attachringtm * basetm );
00231
00232 forcesensor = new PhyFixed( base, attachring, w );
00233 forcesensor->setOwner( this, false );
00234
00235
00236 QVector<SingleIR> sensors;
00237
00238 #ifdef __GNUC__
00239 #warning QUI DECIDERE PER I RANGE/APERTURE E LE POSIZIONI (SPECIE PER I GROUND). INOLTRE IL CENTRO DI MASSA DEL ROBOT È SUL TAVOLO, SOTTO LA BASE: NON È TROPPO BASSO?
00240 #endif
00241
00242 for (unsigned int i = 0; i < 24; i++) {
00243 const double curAngle = double(i) * (360.0 / 24.0) + ((360.0 / 24.0) / 2.0);
00244 const double radius = bodyr;
00245
00246 wMatrix mtr = wMatrix::yaw(deg2rad(curAngle + 90.0)) * wMatrix::pitch(deg2rad(90.0f));
00247 mtr.w_pos.x = radius * cos(deg2rad(curAngle));
00248 mtr.w_pos.y = radius * sin(deg2rad(curAngle));
00249 mtr.w_pos.z = 0.015f + basez + bodyh/2.0f;
00250
00251 sensors.append(SingleIR(base, mtr, 0.02, 0.1, 10.0, 5));
00252 }
00253 proximityIR = new SimulatedIRProximitySensorController(world(), sensors);
00254
00255
00256 sensors.clear();
00257 wMatrix mtr = wMatrix::yaw(deg2rad(180.0));
00258 const double distFromBorder = 0.003;
00259
00260
00261 mtr.w_pos = wVector(basex / 2.0f - distFromBorder, basey / 2.0f - distFromBorder, 0.015f);
00262 sensors.append(SingleIR(base, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
00263 mtr.w_pos = wVector(basex / 2.0f - distFromBorder, -basey / 2.0f + distFromBorder, 0.015f);
00264 sensors.append(SingleIR(base, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
00265 mtr.w_pos = wVector(-basex / 2.0f + distFromBorder, basey / 2.0f - distFromBorder, 0.015f);
00266 sensors.append(SingleIR(base, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
00267 mtr.w_pos = wVector(-basex / 2.0f + distFromBorder, -basey / 2.0f + distFromBorder, 0.015f);
00268 sensors.append(SingleIR(base, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
00269 groundBottomIR = new SimulatedIRGroundSensorController(world(), sensors);
00270
00271
00272 sensors.clear();
00273
00274
00275 for (unsigned int i = 0; i < 8; i++) {
00276 const double curAngle = double(i) * (360.0 / 8.0);
00277 const double radius = bodyr - 0.003;
00278
00279 wMatrix mtr = wMatrix::yaw(deg2rad(180.0));
00280 mtr.w_pos.x = radius * cos(deg2rad(curAngle));
00281 mtr.w_pos.y = radius * sin(deg2rad(curAngle));
00282 mtr.w_pos.z = 0.015f + basez;
00283
00284 sensors.append(SingleIR(base, mtr, 0.0, mtr.w_pos.z + 0.005, 0.0, 1));
00285 }
00286 groundAroundIR = new SimulatedIRGroundSensorController(world(), sensors);
00287
00288 w->pushObject( this );
00289 }
00290
00291 PhyMarXbot::~PhyMarXbot() {
00292 foreach( PhyJoint* susp, wheelJoints ) {
00293 delete susp;
00294 }
00295 foreach( PhyObject* w, wheels ) {
00296 delete w;
00297 }
00298 delete wheelsCtrl;
00299 delete forcesensor;
00300 delete attachring;
00301 delete base;
00302 delete proximityIR;
00303 }
00304
00305 void PhyMarXbot::preUpdate()
00306 {
00307
00308 if (wheelsCtrl->isEnabled()) {
00309 wheelsCtrl->update();
00310 }
00311 }
00312
00313 void PhyMarXbot::postUpdate()
00314 {
00315
00316 if (proximityIR->isEnabled()) {
00317 proximityIR->update();
00318 }
00319 if (groundBottomIR->isEnabled()) {
00320 groundBottomIR->update();
00321 }
00322 if (groundAroundIR->isEnabled()) {
00323 groundAroundIR->update();
00324 }
00325 }
00326
00327 void PhyMarXbot::setProximityIRSensorsGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
00328 {
00329 proximityIR->setGraphicalProperties(drawSensor, drawRay, drawRealRay);
00330 }
00331
00332 void PhyMarXbot::setGroundBottomIRSensorsGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
00333 {
00334 groundBottomIR->setGraphicalProperties(drawSensor, drawRay, drawRealRay);
00335 }
00336
00337 void PhyMarXbot::setGroundAroundIRSensorsGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
00338 {
00339 groundAroundIR->setGraphicalProperties(drawSensor, drawRay, drawRealRay);
00340 }
00341
00342 void PhyMarXbot::changedMatrix() {
00343 wMatrix tm = matrix();
00344 base->setMatrix( tm );
00345 for( int i=0; i<wheels.size(); i++ ) {
00346 wheels[i]->setMatrix( wheelstm[i] * tm );
00347 }
00348 foreach( PhyJoint* ajoint, wheelJoints ) {
00349 ajoint->updateJointInfo();
00350 }
00351 attachring->setMatrix( attachringtm * tm );
00352 forcesensor->updateJointInfo();
00353 }
00354
00355 }