00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "sensorcontrollers.h"
00025 #include "logger.h"
00026 #include "mathutils.h"
00027 #include "phyobject.h"
00028 #include "graphicalwobject.h"
00029
00030 namespace farsa {
00031
00032 SensorController::SensorController(World* world) :
00033 Ownable(),
00034 m_world(world),
00035 m_enabled(true)
00036 {
00037 }
00038
00039 SensorController::~SensorController()
00040 {
00041
00042 }
00043
00044 IRSensorController::IRSensorController(World* world, unsigned int numSensors) :
00045 SensorController(world),
00046 m_activations(numSensors)
00047 {
00048 }
00049
00050 IRSensorController::~IRSensorController()
00051 {
00052
00053 }
00054
00055 namespace __SingleIR_internal {
00056 #ifndef GLMultMatrix
00057 #define GLMultMatrix glMultMatrixf
00058
00059 #endif
00060
00064 const float sensorCubeSide = 0.005f;
00065
00069 class SingleIRGraphic : public GraphicalWObject
00070 {
00071 public:
00099 SingleIRGraphic(WObject *object, const wMatrix& offset, const QVector<wVector>& startingRayPoints, const QVector<wVector>& endingRayPoints, bool drawRay, bool drawRealRay, QString name = "unamed") :
00100 GraphicalWObject(object->world(), name),
00101 m_object(object),
00102 m_offset(offset),
00103 m_startingRayPoints(startingRayPoints),
00104 m_endingRayPoints(endingRayPoints),
00105 m_drawRay(drawRay),
00106 m_drawRealRay(drawRealRay)
00107 {
00108
00109 attachToObject(m_object, true);
00110
00111
00112 setUseColorTextureOfOwner(false);
00113 setTexture("");
00114 setColor(Qt::black);
00115 }
00116
00120 ~SingleIRGraphic()
00121 {
00122 }
00123
00124 protected:
00133 virtual void render(RenderWObject* renderer, QGLContext* gw)
00134 {
00135
00136
00137
00138 wMatrix mtr = tm * m_offset;
00139
00140 glPushMatrix();
00141 GLMultMatrix(&tm[0][0]);
00142
00143 glPushMatrix();
00144 GLMultMatrix(&m_offset[0][0]);
00145
00146 renderer->container()->setupColorTexture(gw, renderer);
00147
00148
00149
00150
00151
00152 glBegin(GL_QUADS);
00153 const float hside = sensorCubeSide / 2.0;
00154
00155
00156 glColor3f(0.0, 1.0, 0.0);
00157 glNormal3f(0.0, 0.0, 1.0);
00158 glVertex3f(-hside, 0.0, hside);
00159 glVertex3f( hside, 0.0, hside);
00160 glVertex3f( hside, hside, hside);
00161 glVertex3f(-hside, hside, hside);
00162
00163
00164 glColor3f(0.0, 0.0, 0.0);
00165 glNormal3f(0.0, 0.0, 1.0);
00166 glVertex3f(-hside, -hside, hside);
00167 glVertex3f( hside, -hside, hside);
00168 glVertex3f( hside, 0.0, hside);
00169 glVertex3f(-hside, 0.0, hside);
00170
00171
00172 glNormal3f(0.0, 0.0, -1.0);
00173 glVertex3f( hside, -hside, -hside);
00174 glVertex3f(-hside, -hside, -hside);
00175 glVertex3f(-hside, hside, -hside);
00176 glVertex3f( hside, hside, -hside);
00177
00178
00179 glNormal3f(0.0, 1.0, 0.0);
00180 glVertex3f(-hside, hside, hside);
00181 glVertex3f( hside, hside, hside);
00182 glVertex3f( hside, hside, -hside);
00183 glVertex3f(-hside, hside, -hside);
00184
00185
00186 glNormal3f(0.0, -1.0, 0.0);
00187 glVertex3f(-hside, -hside, -hside);
00188 glVertex3f( hside, -hside, -hside);
00189 glVertex3f( hside, -hside, hside);
00190 glVertex3f(-hside, -hside, hside);
00191
00192
00193 glNormal3f(-1.0, 0.0, 0.0);
00194 glVertex3f(-hside, -hside, -hside);
00195 glVertex3f(-hside, -hside, hside);
00196 glVertex3f(-hside, hside, hside);
00197 glVertex3f(-hside, hside, -hside);
00198
00199
00200 glNormal3f(1.0, 0.0, 0.0);
00201 glVertex3f( hside, -hside, hside);
00202 glVertex3f( hside, -hside, -hside);
00203 glVertex3f( hside, hside, -hside);
00204 glVertex3f( hside, hside, hside);
00205
00206 glEnd();
00207
00208
00209 glPopMatrix();
00210
00211
00212 glDisable(GL_LIGHTING);
00213
00214
00215 if (m_drawRay) {
00216 glLineWidth(2.5);
00217 glColor3f(1.0, 0.0, 0.0);
00218
00219 glBegin(GL_LINES);
00220 for (int i = 0; i < m_startingRayPoints.size(); i++) {
00221 const wVector& s = m_startingRayPoints[i];
00222 const wVector& e = m_endingRayPoints[i];
00223 if (m_drawRealRay) {
00224 glVertex3f(s.x, s.y, s.z);
00225 glVertex3f(e.x, e.y, e.z);
00226 } else {
00227 const wVector d = (e - s).normalize().scale(sensorCubeSide * 5.0);
00228 glVertex3f(m_offset.w_pos.x, m_offset.w_pos.y, m_offset.w_pos.z);
00229 glVertex3f(m_offset.w_pos.x + d.x, m_offset.w_pos.y + d.y, m_offset.w_pos.z + d.z);
00230 }
00231 }
00232 glEnd();
00233 }
00234
00235
00236 glEnable(GL_LIGHTING);
00237
00238 glPopMatrix();
00239 }
00240
00245 WObject* const m_object;
00246
00251 const wMatrix m_offset;
00252
00259 const QVector<wVector> m_startingRayPoints;
00260
00267 const QVector<wVector> m_endingRayPoints;
00268
00273 const bool m_drawRay;
00274
00282 const bool m_drawRealRay;
00283 };
00284 }
00285
00286 using namespace __SingleIR_internal;
00287
00288 SingleIR::SingleIR() :
00289 m_object(NULL),
00290 m_transformation(wMatrix::identity()),
00291 m_minDist(0.0),
00292 m_maxDist(0.0),
00293 m_aperture(0.0),
00294 m_numRays(0),
00295 m_drawSensor(false),
00296 m_drawRay(false),
00297 m_drawRealRay(false),
00298 m_startingRayPoints(),
00299 m_endingRayPoints(),
00300 m_rayCastHit(),
00301 m_sensorGraphics(NULL)
00302 {
00303 m_rayCastHit.object = NULL;
00304 m_rayCastHit.distance = 1.0;
00305 }
00306
00307 SingleIR::SingleIR(WObject* obj, wMatrix mtr, double minDist, double maxDist, double aperture, unsigned int numRays) :
00308 m_object(obj),
00309 m_transformation(mtr),
00310 m_minDist(minDist),
00311 m_maxDist(maxDist),
00312 m_aperture(aperture),
00313 m_numRays(numRays),
00314 m_drawSensor(false),
00315 m_drawRay(false),
00316 m_drawRealRay(false),
00317 m_startingRayPoints(),
00318 m_endingRayPoints(),
00319 m_rayCastHit(),
00320 m_sensorGraphics(NULL)
00321 {
00322 m_rayCastHit.object = NULL;
00323 m_rayCastHit.distance = 1.0;
00324
00325 if (m_numRays != 0) {
00326 m_startingRayPoints.resize(m_numRays);
00327 m_endingRayPoints.resize(m_numRays);
00328 }
00329
00330
00331 computeRayPoints();
00332 updateGraphicalRepresentation();
00333 }
00334
00335 SingleIR::SingleIR(const SingleIR& other) :
00336 m_object(other.m_object),
00337 m_transformation(other.m_transformation),
00338 m_minDist(other.m_minDist),
00339 m_maxDist(other.m_maxDist),
00340 m_aperture(other.m_aperture),
00341 m_numRays(other.m_numRays),
00342 m_drawSensor(other.m_drawSensor),
00343 m_drawRay(other.m_drawRay),
00344 m_drawRealRay(other.m_drawRealRay),
00345 m_startingRayPoints(other.m_startingRayPoints),
00346 m_endingRayPoints(other.m_endingRayPoints),
00347 m_rayCastHit(other.m_rayCastHit),
00348 m_sensorGraphics(NULL)
00349 {
00350 updateGraphicalRepresentation();
00351 }
00352
00353 SingleIR& SingleIR::operator=(const SingleIR& other)
00354 {
00355 if (&other == this) {
00356 return *this;
00357 }
00358
00359
00360 m_object = other.m_object;
00361 m_transformation = other.m_transformation;
00362 m_minDist = other.m_minDist;
00363 m_maxDist = other.m_maxDist;
00364 m_aperture = other.m_aperture;
00365 m_numRays = other.m_numRays;
00366 m_drawSensor = other.m_drawSensor;
00367 m_drawRay = other.m_drawRay;
00368 m_drawRealRay = other.m_drawRealRay;
00369 m_startingRayPoints = other.m_startingRayPoints;
00370 m_endingRayPoints = other.m_endingRayPoints;
00371 m_rayCastHit = other.m_rayCastHit;
00372
00373 updateGraphicalRepresentation();
00374
00375 return *this;
00376 }
00377
00378 SingleIR::~SingleIR()
00379 {
00380
00381 }
00382
00383 void SingleIR::update()
00384 {
00385
00386 if (!isValid()) {
00387 return;
00388 }
00389
00390
00391 m_rayCastHit.object = NULL;
00392 m_rayCastHit.distance = 1.0;
00393
00394
00395 QSet<PhyObject*> ignoredObjs;
00396 PhyObject* phyObj = dynamic_cast<PhyObject*>(m_object);
00397 if (phyObj != NULL) {
00398 ignoredObjs.insert(phyObj);
00399 }
00400
00401
00402 double minDist = 2.0;
00403 for (unsigned int i = 0; i < m_numRays; i++) {
00404
00405 const wVector start = m_object->matrix().transformVector(m_startingRayPoints[i]);
00406 const wVector end = m_object->matrix().transformVector(m_endingRayPoints[i]);
00407
00408
00409 const rayCastHitVector v = m_object->world()->worldRayCast(start, end, true, ignoredObjs);
00410
00411
00412
00413 if ((v.size() != 0) && (v[0].distance < minDist)) {
00414 minDist = v[0].distance;
00415 m_rayCastHit = v[0];
00416 }
00417 }
00418 }
00419
00420 void SingleIR::set(WObject* obj, wMatrix mtr, double minDist, double maxDist, double aperture, unsigned int numRays)
00421 {
00422
00423 m_object = obj;
00424 m_transformation = mtr;
00425 m_minDist = minDist;
00426 m_maxDist = maxDist;
00427 m_aperture = aperture;
00428 m_numRays = numRays;
00429 if (m_numRays != 0) {
00430 m_startingRayPoints.resize(m_numRays);
00431 m_endingRayPoints.resize(m_numRays);
00432 } else {
00433 m_startingRayPoints.clear();
00434 m_endingRayPoints.clear();
00435 }
00436 m_rayCastHit.object = NULL;
00437 m_rayCastHit.distance = 1.0;
00438
00439 computeRayPoints();
00440 updateGraphicalRepresentation();
00441 }
00442
00443 void SingleIR::setGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
00444 {
00445 m_drawSensor = drawSensor;
00446 m_drawRay = drawRay;
00447 m_drawRealRay = drawRealRay;
00448
00449 updateGraphicalRepresentation();
00450 }
00451
00452 void SingleIR::computeRayPoints()
00453 {
00454
00455 if (!isValid()) {
00456 return;
00457 }
00458
00459
00460
00461
00462 const double startAngle = (m_numRays == 1) ? 0.0 : -(deg2rad(m_aperture) / 2.0);
00463 const double angularIncrement = (m_numRays == 1) ? 0.0 : (deg2rad(m_aperture) / double(m_numRays - 1));
00464
00465
00466 for (unsigned int i = 0; i < m_numRays; i++) {
00467 const double curAngle = startAngle + i * angularIncrement;
00468
00469
00470
00471 const wVector localRay = wVector::Z().rotateAround(wVector::Y(), curAngle);
00472 const wVector localStart = localRay.scale(m_minDist);
00473 const wVector localEnd = localRay.scale(m_maxDist);
00474
00475
00476 m_startingRayPoints[i] = m_transformation.transformVector(localStart);
00477 m_endingRayPoints[i] = m_transformation.transformVector(localEnd);
00478 }
00479 }
00480
00481 void SingleIR::updateGraphicalRepresentation()
00482 {
00483 delete m_sensorGraphics;
00484 m_sensorGraphics = NULL;
00485
00486
00487 if (m_drawSensor && isValid()) {
00488
00489 m_sensorGraphics = new SingleIRGraphic(m_object, m_transformation, m_startingRayPoints, m_endingRayPoints, m_drawRay, m_drawRealRay);
00490 }
00491 }
00492
00493 SimulatedIRProximitySensorController::SimulatedIRProximitySensorController(World* world, const QVector<SingleIR>& sensors) :
00494 IRSensorController(world, sensors.size()),
00495 m_sensors(sensors)
00496 {
00497
00498 }
00499
00500 SimulatedIRProximitySensorController::~SimulatedIRProximitySensorController()
00501 {
00502
00503 }
00504
00505 void SimulatedIRProximitySensorController::update()
00506 {
00507 for (int i = 0; i < m_sensors.size(); i++) {
00508 m_sensors[i].update();
00509
00510 m_activations[i] = 1.0 - m_sensors[i].getRayCastHit().distance;
00511 }
00512 }
00513
00514 void SimulatedIRProximitySensorController::setGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
00515 {
00516 for (int i = 0; i < m_sensors.size(); i++) {
00517 m_sensors[i].setGraphicalProperties(drawSensor, drawRay, drawRealRay);
00518 }
00519 }
00520
00521 SimulatedIRGroundSensorController::SimulatedIRGroundSensorController(World* world, const QVector<SingleIR>& sensors) :
00522 IRSensorController(world, sensors.size()),
00523 m_sensors(sensors)
00524 {
00525 }
00526
00527 SimulatedIRGroundSensorController::~SimulatedIRGroundSensorController()
00528 {
00529
00530 }
00531
00532 void SimulatedIRGroundSensorController::update()
00533 {
00534 for (int i = 0; i < m_sensors.size(); i++) {
00535 m_sensors[i].update();
00536
00537
00538
00539 if (m_sensors[i].getRayCastHit().object != NULL) {
00540 m_activations[i] = m_sensors[i].getRayCastHit().object->color().lightnessF();
00541 } else {
00542 m_activations[i] = 0.0;
00543 }
00544 }
00545 }
00546
00547 void SimulatedIRGroundSensorController::setGraphicalProperties(bool drawSensor, bool drawRay, bool drawRealRay)
00548 {
00549 for (int i = 0; i < m_sensors.size(); i++) {
00550 m_sensors[i].setGraphicalProperties(drawSensor, drawRay, drawRealRay);
00551 }
00552 }
00553
00554 }