00001
00002
00003
00004
00005
00006
00007 #include <iostream>
00008 #include <fmod/fmod.hpp>
00009 #include <fmod/fmod_errors.h>
00010 #include <fmod/fmod_event.hpp>
00011 #include <fmod/fmod_event_net.hpp>
00012
00013 #include <boost/algorithm/string.hpp>
00014
00015 #include <GL/glut.h>
00016 #include <SOIL/SOIL.h>
00017
00018 #include <math.h>
00019 #include <string.h>
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <stack>
00023 #include <string>
00024 #include <fstream>
00025 #include <sstream>
00026 #include <time.h>
00027
00028 #include <ros/ros.h>
00029 #include <boost/thread.hpp>
00030 #include <sensor_msgs/Joy.h>
00031 #include <auv_msgs/NavSts.h>
00032 #include <std_msgs/Float32MultiArray.h>
00033 #include <geometry_msgs/PointStamped.h>
00034
00035 #include <labust/gui/AAGui.hpp>
00036
00037 #include <auv_msgs/BodyForceReq.h>
00038
00039 namespace LABUST
00040 {
00041 struct JoystickData
00042 {
00043 std::vector<short> axes;
00044 std::vector<bool> buttons;
00045 };
00046 };
00047
00048
00049 boost::mutex joyMux;
00050 LABUST::JoystickData joystickData;
00051
00052 auv_msgs::NavSts state, target;
00053 labust::gui::AAGui::Ptr gui;
00054
00055 ros::Publisher infopub;
00056 std::vector<float> configInfo(8,0.0);
00057
00058 namespace FMOD
00059 {
00060
00061
00062 #define GL_CLAMP_TO_EDGE 0x812F
00063 #define FMOD_INIT_DSOUND_HRTFFULL 0x00000800
00064
00065 double Head;
00066 double HeadIni=0.0f;
00067
00068 unsigned char key1 =0;
00069
00070 void ERRCHECK(FMOD_RESULT result)
00071 {
00072 if (result != FMOD_OK)
00073 {
00074 printf("FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
00075 exit(-1);
00076 }
00077 }
00078
00079 int INTERFACE_UPDATETIME = 15;
00080
00081 int intMax = 32767;
00082 int r;
00083 int iDiter = 0;
00084 int KDiterTime = 1;
00085 double AmpDiter = 0.0f;
00086 double FreqDiter = 1.0f;
00087 double tDiter[13] ={10,15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70};
00088 double FiDiter[13] = {0, 15, -10, -25, 0, 5, -15, 15, -10, -3, -10, 5, 0};
00089 double ti=0;
00090 double Integral=0.0f;
00091 bool fullscreen = false;
00092 bool wait = true;
00093 float LogData[12]={0,0,0,0,0,0,0,0,0,0,0,0};
00094
00095 double forw=0.0f;
00096 double InputStoh=0.0f;
00097 int InputStoh1=0;
00098 double lastObjectLong = 0.0;
00099 double zPos = 0.0;
00100 double aSQR = 1.0f;
00101 double bSQR = 0.0f;
00102 double cSQR = 0.0f;
00103
00104 double Altitude = 2.5f;
00105 double ROVLat = 43.5f;
00106 double ROVLong = 15.5f;
00107 double ROVHeading = 0.0f;
00108 double ROVRoll = 0.0f;
00109 double ROVPitch = 0.0f;
00110 double Depth = 0.0f;
00111 double VelVec = 0.0f;
00112 double HE = 0.0f;
00113
00114
00115 double AltitudeSetPoint = 10.0f;
00116 bool TrajectoryTracking = false;
00117 bool WPupdateFlage=true;
00118 double ObjectLat = 43.5;
00119 double ObjectLong = 15.5;
00120 double ObjectDepth = 20.0f;
00121 double Doppler = 100.0f;
00122 double SilenceAngle = 0.00f;
00123 double VerbalAngle = 5.00f;
00124 double NonLinearCoeff = 1.0f;
00125 double NonLinearCoeffDist = 1.0f;
00126 double TransformAngle = 0.00f;
00127 double PathVelocity = 0.0f;
00128 double Ki = 0.0f;
00129 int Sound=0;
00130 int GuidanceMode = 1;
00131 int TaskMode = 1;
00132 int JoyStickMode=1;
00133 int SpeedProfile='C';
00134 double velAtitude = 0.0f;
00135 double lastvelAtitude = 0.0f;
00136 double PathStartX = 10.0f;
00137 double PathStartY = 10.0f;
00138 double PathStartX1 = 0.0f;
00139 double PathStartY1 = 0.0f;
00140 double PathX = 0.0f;
00141 double PathY = 0.0f;
00142 double DistanceToPath = 0.0f;
00143 double RabbitDistance = 0.0f;
00144 double RabbitNorth = 0;
00145 double RabbitNorth1 = 0;
00146 double RabbitNorth2 = 0;
00147 double RabbitNorthOld = 0;
00148 double RabbitEast = 0;
00149 double RabbitEastOld = 0;
00150 double HeadingErr = 0.0f;
00151 double TauX = 0.0f;
00152 double TauY = 0.0f;
00153 double TauZ = 0.0f;
00154 double TauK = 0.0f;
00155 double TauM = 0.0f;
00156 double TauN = 0.0f;
00157 double frwVelVector = 0.0f;
00158 double latVelVector = 0.0f;
00159 double zVelVector = 0.0f;
00160
00161
00162 int NumberOfWP = 15;
00163 const int MaxNumberOfWP = 15;
00164
00165 int WPindex = 1;
00166 int ActualWPindex = 1;
00167 int ActualWPindexOld = 1;
00168 float WPnorth[MaxNumberOfWP];
00169 float WPeast[MaxNumberOfWP];
00170 float WPz[MaxNumberOfWP];
00171
00172
00173
00174 int width = 500;
00175 int height = 500;
00176
00177
00178 bool doRotate = false;
00179 int xMouse = 0;
00180 int yMouse = 0;
00181
00182
00183 float xRotation = 0.0f;
00184 float yRotation = 0.0f;
00185 float zRotation = 0.0f;
00186 float lastyRotation = 0.0f;
00187
00188
00189 float xListenerPos = 0.0f;
00190
00191 float yListenerPos = 50.0f;
00192 float zListenerPos = 20.0f;
00193 float DirectionToTarget = 0.0f;
00194 float zListenerPosRel = 0.0f;
00195 float xListenerPosRel = 0.0f;
00196
00197
00198 bool moveForward = false;
00199 bool moveBackward = false;
00200 bool moveRotateClock = false;
00201 bool moveRotateAntiClock = false;
00202 bool moveLeft = false;
00203 bool moveRight = false;
00204 bool moveUp = false;
00205 bool moveDown = false;
00206 bool moveFast = false;
00207 bool ambientVolUp = false;
00208 bool ambientVolDown = false;
00209 bool masterVolUp = false;
00210 bool masterVolDown = false;
00211
00212 #undef PI
00213 const float PI = 3.14159265f;
00214
00215 float accumulatedTime = 0.0f;
00216
00218 GLuint texture;
00219 GLuint skyboxTexture[6];
00220
00221
00222 struct Object
00223 {
00224 float xPos;
00225 float yPos;
00226 float zPos;
00227 float intensity;
00228 int sound;
00229 FMOD::Event *event;
00230 };
00231
00232 const int NUM_OBJECTS = 8;
00233 Object objects[NUM_OBJECTS] =
00234 {
00235
00236 { 0.0f, 10.0f, 0.0f, 1.0f, 0, 0 },
00237 { 0.0f, 10.0f, 0.0f, 1.0f, 1, 0 },
00238 { 45.0f, 10.0f, 0.0f, 1.0f, 3, 0 },
00239 { -30.0f, 1.0f, 21.0f, 1.0f, 2, 0 },
00240 { -30.0f, 1.0f, -21.0f, 1.0f, 3, 0 },
00241 { 12.0f, 1.0f, -27.0f, 1.0f, 0, 0 },
00242 { 0.0f, 10.0f, 0.0f, 1.0f, 0, 0 },
00243 { 0.0f, 10.0f, 0.0f, 1.0f, 1, 0 },
00244 };
00245
00247 struct Polygon
00248 {
00249 int numVertices;
00250 int indicesOffset;
00251 float directOcclusion;
00252 float reverbOcclusion;
00253 FMOD_VECTOR normal;
00254 };
00255
00256 struct Mesh
00257 {
00258 int numVertices;
00259 FMOD_VECTOR *vertices;
00260 float (*texcoords)[2];
00261 int numPolygons;
00262 Polygon* polygons;
00263 int numIndices;
00264 int *indices;
00265 FMOD::Geometry *geometry;
00266 };
00267
00268 class GlutCloseClass
00269 {
00270 public:
00271 GlutCloseClass() {};
00272 ~GlutCloseClass();
00273 };
00274
00275
00276 GlutCloseClass gCloseObject;
00277
00278 Mesh walls;
00279 Mesh rotatingMesh;
00280
00281
00282 FMOD::EventSystem *fmodEventSystem = 0;
00283 FMOD::EventProject *fmodEventProject = 0;
00284 FMOD::EventGroup *fmodEventGroup = 0;
00285 FMOD::EventParameter *fmodEventParameter = 0;
00286 FMOD::System *fmodSystem = 0;
00287 FMOD::Geometry *geometry = 0;
00288 FMOD::DSP *global_lowpass = 0;
00289
00290 float ambientVolume = 0.2f;
00291 float masterVolume;
00292
00293
00294
00295
00296
00297
00298 #ifdef SHOW_GUI_DEBUG_TEXT
00299 std::stack<std::string> debugText;
00300 std::stack<std::string> statusText;
00301 #endif
00302
00303 GLenum rendermode = GL_FILL;
00304
00305 bool showdebug = false;
00306 bool showhelp = false;
00307
00308 void outputText(int x, int y, std::string text)
00309 {
00310 int i;
00311 const char *txt = text.c_str();
00312
00313 glRasterPos2f(x, y);
00314 for (i = 0; i < (int)text.length(); i++)
00315 {
00316 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, txt[i]);
00317 }
00318 }
00319
00320 #ifdef SHOW_GUI_DEBUG_TEXT
00321 void renderText(int x, int y, std::stack<std::string> *text)
00322 {
00323 glColor3f(1.0f, 1.0f, 1.0f);
00324 for (int count = 0; count < text->size(); count++)
00325 {
00326 outputText(x, y, text->top());
00327 text->pop();
00328
00329 y -= 17;
00330 }
00331 }
00332 #endif
00333
00334 void renderUiText()
00335 {
00336
00337
00338
00339 if (showhelp)
00340 {
00341 int x = 10;
00342 int y = height - 20;
00343
00344 glColor3f(1.0f, 1.0f, 1.0f);
00345 outputText(x, y, "F1 - Toggle help");
00346 outputText(x, y-=18, "F2 - Toggle fullscreen");
00347 outputText(x, y-=18, "F3 - Toggle wireframe rendering");
00348 outputText(x, y-=18, "F11 - Toggle debug info");
00349 outputText(x, y-=18, "--");
00350 outputText(x, y-=18, "w - Move forward");
00351 outputText(x, y-=18, "s - Move backward");
00352 outputText(x, y-=18, "a - Move left");
00353 outputText(x, y-=18, "d - Move right");
00354 outputText(x, y-=18, "space - Move up");
00355 outputText(x, y-=18, "c - Move down");
00356 outputText(x, y-=18, "Mouse (hold left button) - look direction");
00357 outputText(x, y-=18, "--");
00358
00359 outputText(x, y-=18, "Z/z - Ambient sound volume up/down");
00360 }
00361 else
00362 {
00363 glColor3f(1.0f, 1.0f, 1.0f);
00364 outputText(10, height - 20, "F1 - Help");
00365 }
00366
00367
00368
00369
00370 #ifdef SHOW_GUI_DEBUG_TEXT
00371 if (showdebug)
00372 {
00373 renderText(width - (width/2), height - 20, &debugText);
00374 }
00375 else
00376 {
00377
00378
00379
00380 for (int count = 0; count < debugText.size(); count++)
00381 {
00382 debugText.pop();
00383 }
00384 }
00385
00386
00387
00388
00389 renderText(10, 20, &statusText);
00390 #endif
00391 }
00392
00393 void initGeometry(const char* szFileName, Mesh& mesh, bool alter = false)
00394 {
00395 FMOD_RESULT result;
00396
00397 FILE* file = fopen(szFileName, "rb");
00398 if (file)
00399 {
00400
00401 fread(&mesh.numVertices, sizeof (mesh.numVertices), 1, file);
00402 mesh.vertices = new FMOD_VECTOR[mesh.numVertices];
00403 mesh.texcoords = new float[mesh.numVertices][2];
00404 fread(mesh.vertices, sizeof (float) * 3, mesh.numVertices, file);
00405 fread(mesh.texcoords, sizeof (float) * 2, mesh.numVertices, file);
00406
00407
00408 fread(&mesh.numIndices, sizeof (mesh.numIndices), 1, file);
00409 mesh.indices = new int[mesh.numIndices];
00410 fread(mesh.indices, sizeof (int), mesh.numIndices, file);
00411
00412
00413 fread(&mesh.numPolygons, sizeof (mesh.numPolygons), 1, file);
00414 mesh.polygons = new Polygon[mesh.numPolygons];
00415
00416
00417 for (int poly = 0; poly < mesh.numPolygons; poly++)
00418 {
00419 Polygon* polygon = &mesh.polygons[poly];
00420
00421
00422 fread(&polygon->numVertices, sizeof (polygon->numVertices), 1, file);
00423 fread(&polygon->indicesOffset, sizeof (polygon->indicesOffset), 1, file);
00424 fread(&polygon->directOcclusion, sizeof (polygon->directOcclusion), 1, file);
00425 fread(&polygon->reverbOcclusion, sizeof (polygon->reverbOcclusion), 1, file);
00426
00427 int* indices = &mesh.indices[polygon->indicesOffset];
00428
00429
00430 float xN = 0.0f;
00431 float yN = 0.0f;
00432 float zN = 0.0f;
00433
00434 for (int vertex = 0; vertex < polygon->numVertices - 2; vertex++)
00435 {
00436 float xA = mesh.vertices[indices[vertex + 1]].x -mesh.vertices[indices[0]].x;
00437 float yA = mesh.vertices[indices[vertex + 1]].y -mesh.vertices[indices[0]].y;
00438 float zA = mesh.vertices[indices[vertex + 1]].z -mesh.vertices[indices[0]].z;
00439 float xB = mesh.vertices[indices[vertex + 2]].x -mesh.vertices[indices[0]].x;
00440 float yB = mesh.vertices[indices[vertex + 2]].y -mesh.vertices[indices[0]].y;
00441 float zB = mesh.vertices[indices[vertex + 2]].z -mesh.vertices[indices[0]].z;
00442
00443 xN += yA * zB - zA * yB;
00444 yN += zA * xB - xA * zB;
00445 zN += xA * yB - yA * xB;
00446 }
00447 float fMagnidued = (float)sqrt(xN * xN + yN * yN + zN * zN);
00448 if (fMagnidued > 0.0f)
00449 {
00450 xN /= fMagnidued;
00451 yN /= fMagnidued;
00452 zN /= fMagnidued;
00453 }
00454 polygon->normal.x = xN;
00455 polygon->normal.y = yN;
00456 polygon->normal.z = zN;
00457 }
00458 fclose(file);
00459 }
00460
00461 result = fmodSystem->createGeometry(mesh.numPolygons, mesh.numIndices, &mesh.geometry);
00462 ERRCHECK(result);
00463
00464
00465
00466
00467 for (int poly = 0; poly < mesh.numPolygons; poly++)
00468 {
00469 Polygon* polygon = &mesh.polygons[poly];
00470 FMOD_VECTOR vertices[16];
00471 for (int i = 0; i < polygon->numVertices; i++)
00472 vertices[i] = mesh.vertices[mesh.indices[polygon->indicesOffset + i]];
00473 int polygonIndex = 0;
00474
00475 if (alter && polygon->directOcclusion == 0.85f)
00476 {
00477
00478 }
00479
00480 result = mesh.geometry->addPolygon(
00481 polygon->directOcclusion,
00482 polygon->reverbOcclusion,
00483 false,
00484 polygon->numVertices,
00485 vertices,
00486 &polygonIndex);
00487 ERRCHECK(result);
00488 }
00489 }
00490
00491
00492 void freeGeometry(Mesh& mesh)
00493 {
00494 mesh.geometry->release();
00495
00496 delete [] mesh.vertices;
00497 delete [] mesh.texcoords;
00498 delete [] mesh.polygons;
00499 delete [] mesh.indices;
00500 }
00501
00502
00503 void inWater()
00504 {
00505 FMOD_RESULT result;
00506 FMOD_REVERB_PROPERTIES reverbprops;
00507 static bool inwater = false;
00508
00509 if (xListenerPos > -14.75f && xListenerPos < -7.6f
00510 && zListenerPos > -10.85f && zListenerPos < -3.75f
00511 && yListenerPos < 5.0f)
00512 {
00513
00514
00515
00516 if (!inwater)
00517 {
00518 glEnable(GL_FOG);
00519
00520 result = fmodEventSystem->getReverbPreset("UnderWater", &reverbprops);
00521 ERRCHECK(result);
00522 result = fmodEventSystem->setReverbProperties(&reverbprops);
00523 ERRCHECK(result);
00524 result = global_lowpass->setBypass(false);
00525 ERRCHECK(result);
00526
00527 inwater = true;
00528 }
00529 }
00530 else
00531 {
00532
00533
00534
00535 if (inwater)
00536 {
00537 glDisable(GL_FOG);
00538
00539 result = fmodEventSystem->getReverbPreset("StdReverb", &reverbprops);
00540 ERRCHECK(result);
00541 result = fmodEventSystem->setReverbProperties(&reverbprops);
00542 ERRCHECK(result);
00543 if (global_lowpass)
00544 {
00545 result = global_lowpass->setBypass(true);
00546 ERRCHECK(result);
00547 }
00548
00549 inwater = false;
00550 }
00551 }
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 void drawWaterRoom()
00622 {
00623 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
00624 glEnable(GL_BLEND);
00625
00626 glPushMatrix();
00627 glColor4f(0.0f,0.1f,0.8f,1.0f);
00628 glDisable(GL_LIGHTING);
00629
00630 glBegin(GL_QUADS);
00631 glVertex3f(-14.72f, 4.0f, -10.85f);
00632 glVertex3f(-7.68f, 4.0f, -10.85f);
00633 glVertex3f(-7.68f, 4.0f, -3.85f);
00634 glVertex3f(-14.72f, 4.0f, -3.85f);
00635 glEnd();
00636
00637 glEnable(GL_LIGHTING);
00638 glPopMatrix();
00639
00640 glDisable(GL_BLEND);
00641 }
00642
00643 void drawGeometry(Mesh& mesh)
00644 {
00645 FMOD_RESULT result;
00646
00647 FMOD_VECTOR pos;
00648 result = mesh.geometry->getPosition(&pos);
00649 ERRCHECK(result);
00650
00651 glPushMatrix();
00652
00653 glTranslatef(pos.x, pos.y, pos.z);
00654 FMOD_VECTOR forward;
00655 FMOD_VECTOR up;
00656 result = mesh.geometry->getRotation(&forward, &up);
00657 ERRCHECK(result);
00658 float matrix[16] =
00659 {
00660 up.y * forward.z - up.z * forward.y, up.x, forward.x, 0.0f,
00661 up.z * forward.x - up.x * forward.z, up.y, forward.y, 0.0f,
00662 up.x * forward.y - up.y * forward.x, up.z, forward.z, 0.0f,
00663 0.0f, 0.0f, 0.0f, 1.0f,
00664 };
00665 glMultMatrixf(matrix);
00666
00667
00668 glEnable(GL_LIGHTING);
00669 glPolygonMode(GL_FRONT_AND_BACK, rendermode);
00670 for (int poly = 0; poly < mesh.numPolygons; poly++)
00671 {
00672 Polygon* polygon = &mesh.polygons[poly];
00673 if (polygon->directOcclusion == 0.0f)
00674 {
00675 continue;
00676 }
00677 glBegin(GL_TRIANGLE_FAN);
00678 glNormal3fv(&polygon->normal.x);
00679
00680 for (int i = 0; i < polygon->numVertices; i++)
00681 {
00682 int index = mesh.indices[polygon->indicesOffset + i];
00683 glTexCoord2f(mesh.texcoords[index][0], mesh.texcoords[index][1]);
00684 glVertex3fv(&mesh.vertices[index].x);
00685 }
00686 glEnd();
00687 }
00688 glPopMatrix();
00689 }
00690
00691 void initObjects()
00692 {
00693 FMOD_RESULT result;
00694
00695 if (GuidanceMode < 3)
00696 {if (Sound==0)
00697 {result = fmodEventGroup->getEvent("PinkNew 500m", FMOD_EVENT_DEFAULT, &objects[0].event);
00698 ERRCHECK(result);
00699
00700 result = fmodEventGroup->getEvent("Click1 500m", FMOD_EVENT_DEFAULT, &objects[1].event);
00701 ERRCHECK(result);}
00702 else
00703 {
00704 {
00705 result = fmodEventGroup->getEvent("PinkNew 500m", FMOD_EVENT_DEFAULT, &objects[1].event);
00706 ERRCHECK(result);
00707
00708 result = fmodEventGroup->getEvent("Click1 500m", FMOD_EVENT_DEFAULT, &objects[0].event);
00709 ERRCHECK(result);
00710 }
00711 }
00712 }
00713
00714 if (GuidanceMode > 1 && GuidanceMode < 4)
00715 {
00716 result = fmodEventGroup->getEvent("up", FMOD_EVENT_DEFAULT, &objects[2].event);
00717 ERRCHECK(result);
00718
00719 result = fmodEventGroup->getEvent("down", FMOD_EVENT_DEFAULT, &objects[3].event);
00720 ERRCHECK(result);
00721 }
00722
00723 if (GuidanceMode > 2)
00724 {result = fmodEventGroup->getEvent("left", FMOD_EVENT_DEFAULT, &objects[4].event);
00725 ERRCHECK(result);
00726
00727 result = fmodEventGroup->getEvent("right", FMOD_EVENT_DEFAULT, &objects[5].event);
00728 ERRCHECK(result);
00729 }
00730
00731 if (TaskMode == 3)
00732 {
00733 if (Sound==0)
00734 {result = fmodEventGroup->getEvent("PinkNew", FMOD_EVENT_DEFAULT, &objects[6].event);
00735 ERRCHECK(result);
00736 result = fmodEventGroup->getEvent("Click1", FMOD_EVENT_DEFAULT, &objects[7].event);
00737 ERRCHECK(result);}
00738 else
00739 {result = fmodEventGroup->getEvent("PinkNew", FMOD_EVENT_DEFAULT, &objects[7].event);
00740 ERRCHECK(result);
00741 result = fmodEventGroup->getEvent("Click1", FMOD_EVENT_DEFAULT, &objects[6].event);
00742 ERRCHECK(result);}
00743 }
00744
00745
00746 for (int i=0; i < NUM_OBJECTS-1; i++)
00747 {
00748 FMOD_VECTOR pos = { objects[i].xPos, objects[i].yPos, objects[i].zPos };
00749 FMOD_VECTOR vel = { 0.0f, 0.0f, 0.0f };
00750
00751 if (objects[i].event)
00752 {
00753
00754 result = objects[i].event->set3DAttributes(&pos, &vel);
00755 ERRCHECK(result);
00756
00757
00758 result = objects[i].event->start();
00759 ERRCHECK(result);
00760 }
00761 }
00762 }
00763
00764
00765 void updateObjectSoundPos(Object* object)
00766 {
00767 FMOD_RESULT result;
00768
00769 if (object->event)
00770 {
00771
00772
00773 FMOD_VECTOR pos = { object->xPos, object->yPos, object->zPos };
00774 FMOD_VECTOR oldPos;
00775 object->event->get3DAttributes(&oldPos, 0);
00776
00777
00778 FMOD_VECTOR vel;
00779 vel.x = 0;
00780 vel.y = 0;
00781 vel.z = 0;
00782 result = object->event->set3DAttributes(&pos, &vel);
00783
00784
00785 }
00786 }
00787
00788
00789 void mouseFunc(int button, int state, int x, int y)
00790 {
00791 switch (button)
00792 {
00793 case GLUT_LEFT_BUTTON:
00794 if (state == GLUT_DOWN)
00795 {
00796 doRotate = true;
00797 xMouse = x;
00798 yMouse = y;
00799 }
00800 else
00801 if (state == GLUT_UP)
00802 {
00803 doRotate = false;
00804 }
00805 break;
00806
00807 default:
00808 break;
00809 }
00810 }
00811
00812 void motionFunc(int x, int y)
00813 {
00814
00815 std::string SingleLog;
00816 int test = 0;
00817
00818 int dx = x - xMouse;
00819 int dy = y - yMouse;
00820
00821
00822 yRotation += (float)dx * 0.5f;
00823 if (yRotation > 180.0f)
00824 yRotation -= 360.0f;
00825 else
00826 if (yRotation < -180.0f)
00827 yRotation += 360.0f;
00828
00829
00830 const float xExtent = 88.0f;
00831
00832 xRotation += 0.0f;
00833 if (xRotation > xExtent)
00834 xRotation = xExtent;
00835 else
00836 if (xRotation < -xExtent)
00837 xRotation = -xExtent;
00838
00839 xMouse = x;
00840 yMouse = y;
00841 }
00842
00843 void doGeometryMovement()
00844 {
00845 FMOD_RESULT result;
00846
00847
00848 int xGeometryWarpPos = -30.0f;
00849 int zGeometryWarpPos = -21.0f;
00850 int dx = xListenerPos - xGeometryWarpPos;
00851 int dz = zListenerPos - zGeometryWarpPos;
00852 if (dx * dx + dz * dz < 30.0f * 30.0f)
00853 {
00854 if (sin(accumulatedTime * 1.0f) > 0.0f)
00855 {
00856 static FMOD_VECTOR lastOffset = { 0.0f, 0.0f, 0.0f };
00857 FMOD_VECTOR offset = { sin(accumulatedTime * 2.0f), 0.0f, cos(accumulatedTime * 2.0f) };
00858 for (int poly = 0; poly < walls.numPolygons; poly++)
00859 {
00860 Polygon* polygon = &walls.polygons[poly];
00861 for (int i = 0; i < polygon->numVertices; i++)
00862 {
00863 FMOD_VECTOR& vertex = walls.vertices[walls.indices[polygon->indicesOffset + i]];
00864
00865 dx = vertex.x - xGeometryWarpPos;
00866 dz = vertex.z - zGeometryWarpPos;
00867 if (dx * dx + dz * dz > 90.0f)
00868 continue;
00869 vertex.x -= lastOffset.x;
00870 vertex.y -= lastOffset.y;
00871 vertex.z -= lastOffset.z;
00872
00873 vertex.x += offset.x;
00874 vertex.y += offset.y;
00875 vertex.z += offset.z;
00876 result = walls.geometry->setPolygonVertex(poly, i, &vertex);
00877 ERRCHECK(result);
00878 }
00879 }
00880 lastOffset = offset;
00881 }
00882 }
00883
00884
00885 FMOD_VECTOR up = { 0.0f, 1.0f, 0.0f };
00886 FMOD_VECTOR forward = { (float)sin(accumulatedTime * 0.5f), 0.0f, (float)cos(accumulatedTime * 0.5f) };
00887 result = rotatingMesh.geometry->setRotation(&forward, &up);
00888 ERRCHECK(result);
00889 FMOD_VECTOR pos;
00890 pos.x = 12.0f;
00891 pos.y = (float)sin(accumulatedTime) * 0.4f + 0.1f;
00892 pos.z = 0.0f;
00893 result = rotatingMesh.geometry->setPosition(&pos);
00894 ERRCHECK(result);
00895
00896 }
00897
00898 void doSoundMovement()
00899 {
00900
00901
00902 float azim = 0, DistanceErr = 0;
00903 float distance = sqrt((xListenerPos-RabbitEast)*(xListenerPos-RabbitEast)+(zListenerPos-RabbitNorth)*(zListenerPos-RabbitNorth));
00904 float TransformDistance=1.0f, NewDist=distance;
00905
00906
00907 DistanceErr = distance - 10;
00908 if (ActualWPindex==1)
00909 {Integral=0;}
00910 else
00911 {Integral += DistanceErr*INTERFACE_UPDATETIME/1000;}
00912 NewDist = 10/PI*atan2((2*NonLinearCoeffDist*sin(2*(PI/2)*DistanceErr/10)),(1-NonLinearCoeffDist*NonLinearCoeffDist+(1+NonLinearCoeffDist*NonLinearCoeffDist)*cos(2*(PI/2)*DistanceErr/10)))+10;
00913 NewDist += Ki*Integral;
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932 if (ActualWPindex==1)
00933 {TransformDistance = 1;}
00934 else
00935 {TransformDistance = NewDist/RabbitDistance;}
00936
00937
00938
00939
00940
00941 std::cout<<latVelVector<<","<<frwVelVector<<std::endl;
00942 VelVec = atan2(latVelVector,frwVelVector);
00943 if (fabs(frwVelVector) < 0.3)
00944 {VelVec = fabs(frwVelVector)/0.3*VelVec;}
00945 HeadingErr = DirectionToTarget - yRotation - VelVec*180/PI;
00946
00947 if (HeadingErr<-180.0f)
00948 {HeadingErr = HeadingErr + 360;
00949 }
00950
00951
00952 HE = HeadingErr;
00953 azim = HE*PI/180;
00954 if (fabs(HeadingErr) < 90)
00955 {
00956
00957 TransformAngle = 0.5*atan2((2*NonLinearCoeff*sin(2*azim)),(1-NonLinearCoeff*NonLinearCoeff+(1+NonLinearCoeff*NonLinearCoeff)*cos(2*azim)));
00958 }
00959 else
00960 {TransformAngle = azim;
00961 }
00962
00963
00964
00965
00966
00967 if (TaskMode == 1)
00968 {
00969 if ((accumulatedTime > KDiterTime * tDiter[iDiter]) && (iDiter < 12))
00970 {iDiter++;}
00971 objects[0].xPos = xListenerPos*(1-cos(TransformAngle))+zListenerPos*sin(TransformAngle);
00972 objects[0].zPos = zListenerPos*(1-cos(TransformAngle))-xListenerPos*sin(TransformAngle);
00973 objects[1].xPos = 0;
00974 objects[1].zPos = 0;
00975 }
00976 else
00977 {objects[0].xPos = xListenerPos + RabbitDistance*sin(TransformAngle + yRotation*PI/180 + VelVec);
00978 objects[0].zPos = zListenerPos - RabbitDistance*cos(TransformAngle + yRotation*PI/180 + VelVec);
00979 objects[0].xPos = xListenerPos + (objects[0].xPos - xListenerPos)*TransformDistance;
00980 objects[0].zPos = zListenerPos + (objects[0].zPos - zListenerPos)*TransformDistance;
00981 objects[1].xPos = RabbitEast;
00982 objects[1].zPos = RabbitNorth;
00983 objects[6].xPos = objects[0].xPos;
00984 objects[6].zPos = objects[0].zPos;
00985 }
00986
00987
00988
00989 if (fabs(HeadingErr) < SilenceAngle)
00990 {
00991 objects[0].yPos = yListenerPos + 5000;
00992 objects[1].yPos = yListenerPos + 5000;
00993 }
00994 else
00995 {
00996 if (TaskMode<3)
00997 {
00998 objects[0].yPos = yListenerPos;
00999 objects[6].yPos = yListenerPos + 5000;
01000 }
01001 else
01002 {
01003 objects[6].yPos = yListenerPos;
01004 objects[0].yPos = yListenerPos + 5000;
01005 }
01006 objects[1].yPos = yListenerPos + 5000;
01007 }
01008
01009
01010 if ((fabs(xListenerPos) < 2 && fabs(zListenerPos) < 2 && TaskMode==1) || ((ActualWPindex > 2)))
01011 {
01012 objects[0].yPos = yListenerPos + 5000;
01013 objects[6].yPos = yListenerPos + 5000;
01014 objects[1].yPos = yListenerPos;
01015 }
01016
01017 std::cout<<distance<<" "<<HE<<" "<<yRotation<<" "<<RabbitNorth<<" "<<RabbitEast<<" "<<ActualWPindex<<std::endl;
01018 std::cout<<std::endl;
01019
01020
01021
01022
01023
01024
01025
01026
01027 updateObjectSoundPos(&objects[0]);
01028 updateObjectSoundPos(&objects[6]);
01029 updateObjectSoundPos(&objects[1]);
01030
01031
01032
01033
01034 if (Altitude < AltitudeSetPoint - 1.0f)
01035
01036 {
01037 objects[2].xPos = xListenerPos;
01038 objects[2].zPos = zListenerPos;
01039 objects[2].yPos = yListenerPos + 5;
01040 }
01041 else
01042 {
01043 objects[2].yPos = yListenerPos + 5000;
01044 }
01045 updateObjectSoundPos(&objects[2]);
01046 if (Altitude > AltitudeSetPoint + 1.0f)
01047
01048 {
01049 objects[3].xPos = xListenerPos;
01050 objects[3].zPos = zListenerPos;
01051 objects[3].yPos = yListenerPos - 5;
01052 }
01053 else
01054 {
01055 objects[3].yPos = yListenerPos + 5000;
01056 }
01057 updateObjectSoundPos(&objects[3]);
01058
01059
01060
01061
01062 if (HeadingErr > VerbalAngle && HeadingErr < 360-VerbalAngle && sin(HeadingErr*PI/180) < 0)
01063 {
01064 objects[4].xPos = xListenerPos;
01065 objects[4].zPos = zListenerPos;
01066 objects[4].yPos = yListenerPos;
01067 }
01068 else
01069 {
01070 objects[4].yPos = yListenerPos + 5000;
01071 }
01072 updateObjectSoundPos(&objects[4]);
01073 if (HeadingErr > VerbalAngle && HeadingErr < 360-VerbalAngle && sin(HeadingErr*PI/180) > 0)
01074 {
01075 objects[5].xPos = xListenerPos;
01076 objects[5].zPos = zListenerPos;
01077 objects[5].yPos = yListenerPos;
01078 }
01079 else
01080 {
01081 objects[5].yPos = yListenerPos + 5000;
01082 }
01083 updateObjectSoundPos(&objects[5]);
01084
01085 }
01086
01087 void doListenerMovement()
01088 {
01089
01090
01091 std::string SingleLog;
01092 float step;
01093 const float MOVEMENT_SPEED = 0.1f;
01094 float forward = 0.0f;
01095 switch (SpeedProfile)
01096 {
01097 case 'V':
01098 step=(float)INTERFACE_UPDATETIME/1000*PathVelocity+0.3*(float)INTERFACE_UPDATETIME/1000*PathVelocity*(float)sin(accumulatedTime/3);
01099 break;
01100 case 'S':
01101 if (ActualWPindex > 1 && sqrt((xListenerPos - WPeast[ActualWPindex])*(xListenerPos - WPeast[ActualWPindex]) + (zListenerPos-WPnorth[ActualWPindex])*(zListenerPos-WPnorth[ActualWPindex])) < 40)
01102 {
01103 step=(float)INTERFACE_UPDATETIME/1000*PathVelocity*1.2;
01104 }
01105 else
01106 {
01107 step=(float)INTERFACE_UPDATETIME/1000*PathVelocity;
01108 }
01109 break;
01110 default:
01111 step=(float)INTERFACE_UPDATETIME/1000*PathVelocity;
01112 }
01113
01114 Head = 0.0f;
01115
01116
01117
01118
01120
01122 boost::mutex::scoped_lock lock(joyMux);
01123 if ((ObjectLong != target.position.north) || (ObjectLat != target.position.east))
01124 {WPupdateFlage=true;}
01125 ObjectLong = target.position.north;
01126 ObjectLat = target.position.east;
01127 ObjectDepth = 20;
01128
01129 if (JoyStickMode==2)
01130 {yListenerPos = 20;}
01131 else
01132 {
01133 if (TaskMode == 1)
01134 {
01135 zListenerPos = (state.position.north - ObjectLong);
01136 xListenerPos = -(state.position.east - ObjectLat);
01137 yListenerPos = 20;
01138 }
01139 else
01140 {
01141 zListenerPos = -(state.position.north - 0*ObjectLong);
01142 xListenerPos = (state.position.east - 0*ObjectLat);
01143 yListenerPos = 20;
01144 }
01145 }
01146
01147 NumberOfWP = 2;
01148 if (WPupdateFlage)
01149 {
01150 ActualWPindex = 1;
01151 WPnorth[2] = -ObjectLong;
01152 WPeast[2] = ObjectLat;
01153
01154
01155
01156
01157
01158
01159 if (TaskMode==3)
01160 {
01161 WPnorth[1] = zListenerPos + cos(atan2((WPeast[2]-xListenerPos),(WPnorth[2]-zListenerPos)))*15;
01162 WPeast[1] = xListenerPos + sin(atan2((WPeast[2]-xListenerPos),(WPnorth[2]-zListenerPos)))*15;
01163 }
01164 else
01165 {
01166 WPnorth[1] = zListenerPos + cos(atan2((WPeast[2]-xListenerPos),(WPnorth[2]-zListenerPos)))*5;
01167 WPeast[1] = xListenerPos + sin(atan2((WPeast[2]-xListenerPos),(WPnorth[2]-zListenerPos)))*5;
01168 }
01169
01170 WPupdateFlage=false;
01171 }
01172
01173 zRotation = state.orientation.roll;
01174 xRotation = state.orientation.pitch;
01175 if (JoyStickMode==1)
01176 {
01177 yRotation = 180*state.orientation.yaw/M_PI;
01178
01179 ROS_ERROR("Output: %f %f %f %f %f %f %f %f %i",zListenerPos,xListenerPos,state.position.north,state.position.east,WPnorth[ActualWPindex],WPeast[ActualWPindex],RabbitNorth,RabbitEast,ActualWPindex);
01180
01181 TauX = 0;
01182 TauY = 0;
01183 TauZ = 0;
01184 TauK = 0;
01185 TauM = 0;
01186 TauN = 0;
01187 frwVelVector = state.body_velocity.x;
01188 latVelVector = state.body_velocity.y;
01189 }
01190 Altitude = state.altitude;
01191 if (fabs(xListenerPos - WPeast[ActualWPindex]) < 2 && fabs(zListenerPos-WPnorth[ActualWPindex]) < 2 && ActualWPindex > 1)
01192 {
01193 ActualWPindex += 1;}
01194 if (TaskMode==3)
01195 {if (ActualWPindex == 1 && sqrt((xListenerPos - WPeast[ActualWPindex])*(xListenerPos - WPeast[ActualWPindex]) + (zListenerPos-WPnorth[ActualWPindex])*(zListenerPos-WPnorth[ActualWPindex])) < RabbitDistance)
01196 {
01197 ActualWPindex += 1;}
01198 }
01199 else
01200 {if (ActualWPindex == 1 && sqrt((xListenerPos - WPeast[ActualWPindex])*(xListenerPos - WPeast[ActualWPindex]) + (zListenerPos-WPnorth[ActualWPindex])*(zListenerPos-WPnorth[ActualWPindex])) < 2)
01201 {
01202 ActualWPindex += 1;}
01203 }
01204
01205
01206 if (TaskMode>1 && ActualWPindex>1)
01207 {
01208 PathStartY = WPeast[ActualWPindex-1] - WPeast[ActualWPindex];
01209 PathStartX = WPnorth[ActualWPindex-1] - WPnorth[ActualWPindex];
01210 }
01211 float kLine = 1000000;
01212 float kLineAngle = PI/2;
01213 if (PathStartX != 0)
01214 {
01215 kLine = PathStartY / PathStartX;
01216 kLineAngle = atan2(PathStartY,PathStartX);
01217 }
01218 aSQR = 1 + kLine*kLine;
01219
01220
01221 if (TaskMode>1)
01222 {
01223 if (PathStartX == 0)
01224 {
01225 PathX = WPnorth[ActualWPindex];
01226 PathY =xListenerPos;
01227 }
01228 else
01229 {
01230 PathX = (kLine*(xListenerPos - WPeast[ActualWPindex] + kLine*WPnorth[ActualWPindex]) + zListenerPos)/aSQR;
01231 PathY = WPeast[ActualWPindex] + kLine*PathX - kLine*WPnorth[ActualWPindex];
01232 }
01233 }
01234 else
01235 {
01236 PathX = PathStartX*(PathStartY * xListenerPos + PathStartX * zListenerPos)/(PathStartX * PathStartX + PathStartY * PathStartY);
01237 PathY = PathStartY*(PathStartY * xListenerPos + PathStartX * zListenerPos)/(PathStartX * PathStartX + PathStartY * PathStartY);
01238 }
01239
01240 DistanceToPath = sqrt((xListenerPos - PathY) * (xListenerPos - PathY) + (zListenerPos - PathX) * (zListenerPos - PathX));
01241
01242
01243 if ((TaskMode > 1 && sqrt((zListenerPos-WPnorth[NumberOfWP])*(zListenerPos-WPnorth[NumberOfWP]) + (xListenerPos-WPeast[NumberOfWP])*(xListenerPos-WPeast[NumberOfWP])) > RabbitDistance))
01244
01245 {
01246
01247 if (TaskMode==3)
01248 {
01249 if (ActualWPindex>2 && ActualWPindex>ActualWPindexOld)
01250 {
01251 RabbitNorth = WPnorth[ActualWPindex-1] - cos(kLineAngle)*RabbitDistance;
01252 RabbitEast = WPeast[ActualWPindex-1] + sin(kLineAngle)*RabbitDistance;
01253 wait = true;
01254 }
01255 else
01256 {
01257 if ((wait==false || (wait==true && fabs(HE)<10)) && ActualWPindex>1)
01258 {
01259 RabbitNorth = RabbitNorthOld - cos(kLineAngle)*step;
01260 RabbitEast = RabbitEastOld - sin(kLineAngle)*step;
01261 wait=false;
01262 }
01263 }
01264 RabbitNorthOld = RabbitNorth;
01265 RabbitEastOld = RabbitEast;
01266 ActualWPindexOld=ActualWPindex;
01267
01268 }
01269 else
01270 {
01271 if (DistanceToPath > RabbitDistance)
01272 {
01273 RabbitNorth = PathX;
01274 RabbitEast = PathY;
01275 RabbitNorthOld = RabbitNorth;
01276 RabbitEastOld = RabbitEast;
01277 }
01278 else
01279 {
01280 if (PathStartX == 0)
01281 {
01282 RabbitNorth = WPnorth[ActualWPindex];
01283 if (PathStartY<0)
01284 {
01285 RabbitEast = xListenerPos + sqrt(RabbitDistance*RabbitDistance-(zListenerPos - RabbitNorth)*(zListenerPos - RabbitNorth));
01286 }
01287 else
01288 {
01289 RabbitEast = xListenerPos - sqrt(RabbitDistance*RabbitDistance-(zListenerPos - RabbitNorth)*(zListenerPos - RabbitNorth));
01290 }
01291 }
01292 else
01293 {
01294 bSQR = -2*((PathX-WPnorth[ActualWPindex]) + kLine*(PathY-WPeast[ActualWPindex]));
01295 cSQR = (PathX-WPnorth[ActualWPindex])*(PathX-WPnorth[ActualWPindex])+(PathY-WPeast[ActualWPindex])*(PathY-WPeast[ActualWPindex])+DistanceToPath*DistanceToPath-RabbitDistance*RabbitDistance;
01296 RabbitNorth1 = (-bSQR+sqrt(bSQR*bSQR-4*aSQR*cSQR))/(2*aSQR);
01297 RabbitNorth2 = (-bSQR-sqrt(bSQR*bSQR-4*aSQR*cSQR))/(2*aSQR);
01298 if (fabs(RabbitNorth1)<fabs(RabbitNorth2))
01299 {
01300 RabbitNorth = RabbitNorth1 + WPnorth[ActualWPindex];
01301 RabbitEast = kLine * RabbitNorth1 + WPeast[ActualWPindex];
01302 }
01303 else
01304 {
01305 RabbitNorth= RabbitNorth2 + WPnorth[ActualWPindex];
01306 RabbitEast = kLine * RabbitNorth2 + WPeast[ActualWPindex];
01307 }
01308 }
01309 }
01310 }
01311 }
01312 else
01313 {
01314 RabbitNorth = WPnorth[ActualWPindex];
01315 RabbitEast = WPeast[ActualWPindex];
01316 }
01317 if (TaskMode == 1)
01318 {
01319 RabbitNorth = 0.0f;
01320 RabbitEast = 0.0f;
01321 }
01322 if (ActualWPindex == 1)
01323 {
01324 if (TaskMode==3)
01325 {
01326 RabbitNorth = zListenerPos + cos(atan2((WPeast[1]-xListenerPos),(WPnorth[1]-zListenerPos)))*RabbitDistance;
01327 RabbitEast = xListenerPos + sin(atan2((WPeast[1]-xListenerPos),(WPnorth[1]-zListenerPos)))*RabbitDistance;
01328 }
01329 else
01330 {
01331 RabbitNorth = WPnorth[1];
01332 RabbitEast = WPeast[1];
01333 RabbitNorthOld = RabbitNorth;
01334 RabbitEastOld = RabbitEast;
01335 }
01336 }
01337
01338 ti += (float)INTERFACE_UPDATETIME / 1000.0f;
01339 if (ti > 2)
01340 {r = rand()%3;
01341 ti = 0.0f;}
01342
01343
01344
01345 if (JoyStickMode==2)
01346 {
01347 if (abs(joystickData.axes[1])>2000)
01348 {
01349 forw = -0.1*joystickData.axes[1]/intMax;
01350 }
01351 else
01352 {
01353 forw = 0;
01354 }
01355 }
01356 if (JoyStickMode==2)
01357 {
01358 if (abs(joystickData.axes[0])>2000)
01359 {
01360 yRotation += 1.0f*joystickData.axes[0]/intMax;
01361 if (yRotation < 0)
01362 {yRotation = yRotation + 360;}
01363 else
01364 {
01365 if (yRotation > 360)
01366 {yRotation = yRotation - 360;}
01367 }
01368 }
01369
01370 }
01371
01372
01373 lastyRotation=yRotation;
01374
01375
01376
01377 float xRight = (float)cos(yRotation * (PI / 180.0f));
01378 float yRight = 0.0f;
01379 float zRight = (float)sin(yRotation * (PI / 180.0f));
01380
01381
01382 float xForward = (float)sin(yRotation * (PI / 180.0f)) * cos(xRotation * (PI / 180.0f));
01383 float yForward = -(float)sin(xRotation * (PI / 180.0f));
01384 float zForward = -(float)cos(yRotation * (PI / 180.0f)) * cos(xRotation * (PI / 180.0f));
01385
01386 if (JoyStickMode==2)
01387 {
01388 xListenerPos += xForward * forw;
01389 yListenerPos += yForward * forw;
01390 zListenerPos += zForward * forw;
01391 }
01392
01393 yRotation=lastyRotation;
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403 if (yListenerPos < 0.0f)
01404 {
01405 yListenerPos = 0.0f;
01406 }
01407
01408
01409 float xUp = yRight * zForward - zRight * yForward;
01410 float yUp = zRight * xForward - xRight * zForward;
01411 float zUp = xRight * yForward - yRight * xForward;
01412
01413
01414
01415
01416
01417
01418
01419 if (TaskMode ==1)
01420 {
01421 if (JoyStickMode == 1)
01422 {
01423 zListenerPosRel = zListenerPos;
01424 xListenerPosRel = xListenerPos;
01425 }
01426 else
01427 {
01428 zListenerPosRel = 0;
01429 xListenerPosRel = -25;
01430 }
01431
01432 zListenerPosRel = zListenerPos;
01433 xListenerPosRel = xListenerPos;
01434 }
01435 else
01436 {
01437 zListenerPosRel = zListenerPos - RabbitNorth;
01438 xListenerPosRel = xListenerPos - RabbitEast;
01439 }
01440
01441 DirectionToTarget = atan2(-xListenerPosRel,zListenerPosRel)*180.0f/PI;
01442
01443
01444
01445 {
01446
01447 FMOD_VECTOR listenerVector;
01448 if (JoyStickMode==2)
01449 {
01450 listenerVector.x = xListenerPosRel;
01451 listenerVector.y = yListenerPos;
01452 listenerVector.z = zListenerPosRel;
01453 }
01454 else
01455 {
01456 listenerVector.x = xListenerPos;
01457 listenerVector.y = yListenerPos;
01458 listenerVector.z = zListenerPos;
01459 }
01460
01461 static FMOD_VECTOR lastpos = { 0.0f, 0.0f, 0.0f };
01462 static bool bFirst = true;
01463
01464 FMOD_VECTOR forward;
01465 FMOD_VECTOR up;
01466 FMOD_VECTOR vel;
01467
01468 forward.x = xForward;
01469 forward.y = yForward;
01470 forward.z = zForward;
01471 up.x = xUp;
01472 up.y = yUp;
01473 up.z = zUp;
01474
01475
01476
01477
01478 vel.x = (listenerVector.x - lastpos.x) * (Doppler * 1000.0f / (float)INTERFACE_UPDATETIME);
01479 vel.y = (listenerVector.y - lastpos.y) * (Doppler * 1000.0f / (float)INTERFACE_UPDATETIME);
01480 vel.z = (listenerVector.z - lastpos.z) * (Doppler * 1000.0f / (float)INTERFACE_UPDATETIME);
01481
01482 if (bFirst)
01483 {
01484 bFirst = false;
01485 vel.x = 0;
01486 vel.y = 0;
01487 vel.z = 0;
01488 HeadIni = Head;
01489 }
01490 if (vel.x==0 && vel.z==0)
01491 {velAtitude = lastvelAtitude;}
01492 else
01493 {
01494 if (vel.z < 0.0f)
01495 {velAtitude = atan(-vel.x/vel.z);}
01496 else
01497 {
01498 if (vel.z == 0.0f)
01499 {
01500 if (vel.x < 0.0f)
01501 {velAtitude = 1.5*PI;}
01502 else
01503 {velAtitude = 0.5*PI;}
01504 }
01505 else
01506 {
01507 velAtitude = atan(-vel.x/vel.z)+PI;
01508 }
01509 }
01510 velAtitude = fmod(180*velAtitude/PI+360,360);
01511 lastvelAtitude = velAtitude;
01512 }
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526 lastpos = listenerVector;
01527 lastObjectLong = zPos;
01528
01529 FMOD_RESULT result = fmodSystem->set3DListenerAttributes(0, &listenerVector, &vel, &forward, &up);
01530 ERRCHECK(result);
01531 }
01532 }
01533
01534 void doUpdateVolume()
01535 {
01536
01537 if (ambientVolUp)
01538 {
01539 char volumestring[64];
01540
01541 ambientVolume += 0.025;
01542 if (ambientVolume > 1.0f)
01543 {
01544 ambientVolume = 1.0f;
01545 }
01546
01547 sprintf(volumestring, "Ambient Volume: %0.3f", ambientVolume);
01548
01549 #ifdef SHOW_GUI_DEBUG_TEXT
01550 statusText.push(volumestring);
01551 #endif
01552 }
01553 else if (ambientVolDown)
01554 {
01555 char volumestring[64];
01556
01557 ambientVolume -= 0.025;
01558 if (ambientVolume < 0.0f)
01559 {
01560 ambientVolume = 0.0f;
01561 }
01562
01563 sprintf(volumestring,"Ambient Volume: %0.3f", ambientVolume);
01564
01565 #ifdef SHOW_GUI_DEBUG_TEXT
01566 statusText.push(volumestring);
01567 #endif
01568 }
01569 }
01570
01571 void timerFunc(int nValue)
01572 {
01573 std::string TimeLog;
01574 static bool firsttime = true;
01575 FMOD_RESULT result;
01576
01577
01578
01579 doSoundMovement();
01580 doListenerMovement();
01581 doUpdateVolume();
01582
01583 result = FMOD::NetEventSystem_Update();
01584 ERRCHECK(result);
01585 result = fmodEventSystem->update();
01586 ERRCHECK(result);
01587
01588 accumulatedTime += (float)INTERFACE_UPDATETIME / 1000.0f;
01589
01590 glutPostRedisplay();
01591 glutTimerFunc(INTERFACE_UPDATETIME, timerFunc, 0);
01592
01593 #if 0
01594 if (firsttime)
01595 {
01596 SetWindowPos(
01597 GetForegroundWindow(),
01598 HWND_TOPMOST,
01599 0,
01600 0,
01601 width,
01602 height,
01603 SWP_NOMOVE
01604 );
01605 firsttime = false;
01606 }
01607 #endif
01608 }
01609
01610 void keyboardFunc(unsigned char key, int x, int y)
01611 {
01612 key1 = key;
01613 switch (key)
01614 {
01615 case 'w':
01616 moveForward = true;
01617 break;
01618 case 's':
01619 moveBackward = true;
01620 break;
01621 case 'j':
01622 moveRotateAntiClock = true;
01623 break;
01624 case 'l':
01625 moveRotateClock = true;
01626 break;
01627 case 'a':
01628 moveLeft = true;
01629 break;
01630 case 'd':
01631 moveRight = true;
01632 break;
01633 case ' ':
01634 moveUp = true;
01635 break;
01636 case 'c':
01637 moveDown = true;
01638 break;
01639 case 'z' :
01640 ambientVolDown = true;
01641 break;
01642 case 'Z' :
01643 ambientVolUp = true;
01644 break;
01645 case 'v':
01646 masterVolDown = true;
01647 break;
01648 case 'V':
01649 masterVolUp = true;
01650 break;
01651
01652 case 'p':
01653 {
01654 float value;
01655
01656 fmodEventParameter->getValue(&value);
01657
01658 fmodEventParameter->setValue(value - 20.0f);
01659 }
01660 break;
01661
01662 case 'P':
01663 {
01664 float value;
01665
01666 fmodEventParameter->getValue(&value);
01667
01668 fmodEventParameter->setValue(value + 20.0f);
01669 }
01670 break;
01671
01672 case 'f':
01673 moveFast = true;
01674 break;
01675 }
01676 }
01677
01678 void keyboardUpFunc(unsigned char key, int x, int y)
01679 {
01680 key1 = 0;
01681 switch (key)
01682 {
01683 case 'w':
01684 moveForward = false;
01685 break;
01686 case 's':
01687 moveBackward = false;
01688 break;
01689 case 'j':
01690 moveRotateAntiClock = false;
01691 break;
01692 case 'l':
01693 moveRotateClock = false;
01694 case 'a':
01695 moveLeft = false;
01696 break;
01697 case 'd':
01698 moveRight = false;
01699 break;
01700 case ' ':
01701 moveUp = false;
01702 break;
01703 case 'c':
01704 moveDown = false;
01705 break;
01706 case 'z' :
01707 ambientVolDown = false;
01708 break;
01709 case 'Z' :
01710 ambientVolUp = false;
01711 break;
01712 case 'v':
01713 masterVolDown = false;
01714 break;
01715 case 'V':
01716 masterVolUp = false;
01717 break;
01718 case 'f':
01719 moveFast = false;
01720 break;
01721 case 27:
01722 exit(1);
01723 break;
01724 }
01725 }
01726
01727 void specialKeyUpFunc(int key, int x, int y)
01728 {
01729 switch (key)
01730 {
01731 case GLUT_KEY_F1:
01732 showhelp = !showhelp;
01733 break;
01734 case GLUT_KEY_F2:
01735 if(fullscreen)
01736 {
01737 glutPositionWindow(20,40);
01738 glutReshapeWindow(500,500);
01739 fullscreen = false;
01740 }
01741 else
01742 {
01743 glutFullScreen();
01744 fullscreen = true;
01745 }
01746 break;
01747 case GLUT_KEY_F3:
01748 rendermode = (rendermode == GL_LINE ? GL_FILL : GL_LINE);
01749 break;
01750 case GLUT_KEY_F11:
01751 showdebug = !showdebug;
01752 break;
01753 case GLUT_KEY_F8:
01754 rotatingMesh.geometry->setActive(false);
01755 walls.geometry->setActive(false);
01756 break;
01757 case GLUT_KEY_F9:
01758 rotatingMesh.geometry->setActive(true);
01759 walls.geometry->setActive(true);
01760 break;
01761 }
01762 }
01763
01764 void display(void)
01765 {
01766
01767 {
01768 char text[64];
01769
01770 sprintf(text, "Listener Pos: (%.2f, %.2f, %.2f)", xListenerPos, yListenerPos, zListenerPos);
01771 #ifdef SHOW_GUI_DEBUG_TEXT
01772 debugText.push(std::string(text));
01773 #endif
01774 }
01775
01776 {
01777 char text[64];
01778 float dsp, stream, geometry, update, total;
01779
01780 fmodSystem->getCPUUsage(&dsp, &stream, &geometry, &update, &total);
01781 sprintf(text, "CPU Usage : (%.2f, %.2f, %.2f, %.2f, %.2f)", dsp, stream, geometry, update, total);
01782 #ifdef SHOW_GUI_DEBUG_TEXT
01783 debugText.push(std::string(text));
01784 #endif
01785 }
01786
01787
01788
01789
01790
01791
01792 glMatrixMode(GL_PROJECTION);
01793 glLoadIdentity();
01794 gluPerspective(
01795 60.0,
01796 (float)width / (float)height,
01797 0.1,
01798 500.0
01799 );
01800
01801
01802 glRotatef(xRotation, 1.0f, 0.0f, 0.0f);
01803 glRotatef(yRotation, 0.0f, 1.0f, 0.0f);
01804 glTranslatef(-xListenerPosRel, -yListenerPos, -zListenerPosRel);
01805 glMatrixMode(GL_MODELVIEW);
01806 glLoadIdentity();
01807
01808
01809 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01810 glClearColor(0.4, 0.6f, 1.0f, 0.0f);
01811
01812 glEnable(GL_TEXTURE_2D);
01813 glBindTexture( GL_TEXTURE_2D, texture );
01814
01815
01816
01817
01818
01819
01820 gui->drawSkyBox(xListenerPos, yListenerPos);
01821
01822 glDisable(GL_TEXTURE_2D);
01823
01824
01825 int object;
01826 if (TaskMode == 3)
01827 {object=6;}
01828 else
01829 {object=0;}
01830
01831 {
01832 char txt[256];
01833
01834
01835 float directOcclusion = 1.0f;
01836 float reverbOcclusion = 1.0f;
01837
01838
01839
01840 float intensity = 1.0f;
01841
01842 glPolygonMode(GL_FRONT_AND_BACK, rendermode);
01843 glPushMatrix();
01844
01845 glTranslatef(0, objects[object].yPos, 0);
01846
01847 sprintf(txt, "Sound object (%d): %.2f, %.2f, %.2f", object, objects[object].xPos, objects[object].yPos, objects[object].zPos);
01848 #ifdef SHOW_GUI_DEBUG_TEXT
01849 debugText.push(std::string(txt));
01850 #endif
01851
01852 glPushAttrib(GL_LIGHTING_BIT);
01853
01854 intensity *= 0.75f;
01855 float color[4] = { intensity, intensity, 0.0f, 0.0f };
01856 if(object == 0)
01857 {
01858 color[1] = 0;
01859
01860
01861 }
01862 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color);
01863 intensity *= 0.5f;
01864 float ambient[4] = { intensity, intensity, 0.0f, 0.0f };
01865 if(object == 0)
01866 {
01867 ambient[1] = 0;
01868 }
01869
01870 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
01871
01872
01873 glRotatef(accumulatedTime * 200.0f, 0.0f, 1.0f, 0.0f);
01874 {
01875 FMOD_VECTOR soundorientation;
01876 float rad = (accumulatedTime * 200.0f);
01877
01878 rad *= 3.14159f;
01879 rad /= 180.0f;
01880
01881 soundorientation.x = 0;
01882 soundorientation.y = 0;
01883 soundorientation.z = 0;
01884
01885 objects[object].event->set3DAttributes(0, 0, &soundorientation);
01886 }
01887
01888 glutSolidTeapot(0.1f);
01889 glPopAttrib();
01890 glPopMatrix();
01891 }
01892
01893
01894
01895
01896 drawWaterRoom();
01897
01898
01899
01900
01901 inWater();
01902
01903
01904
01905
01906
01907 glMatrixMode(GL_PROJECTION);
01908 glLoadIdentity();
01909 gluOrtho2D(0.0f, (GLsizei)width, 0.0f, (GLsizei)height);
01910 glMatrixMode(GL_MODELVIEW);
01911 glLoadIdentity();
01912
01913 glDisable(GL_LIGHTING);
01914 glDisable(GL_NORMALIZE);
01915 glDisable(GL_DEPTH_TEST);
01916
01917
01918
01919
01920 renderUiText();
01921
01922
01923 glEnable(GL_DEPTH_TEST);
01924 glEnable(GL_LIGHTING);
01925 glEnable(GL_LIGHT0);
01926 glEnable(GL_NORMALIZE);
01927 glShadeModel(GL_SMOOTH);
01928 glPolygonMode(GL_FRONT_AND_BACK, rendermode);
01929
01930
01931 glutSwapBuffers();
01932 }
01933
01934 void reshapeFunc(int w, int h)
01935 {
01936 width = w;
01937 height = h;
01938 glViewport(0, 0, (GLsizei)w, (GLsizei)h);
01939 }
01940
01941 GLuint loadTexturePNG(const char *filename)
01942 {
01943 GLuint texture = SOIL_load_OGL_texture(filename, 0, 0, 0);
01944 glBindTexture(GL_TEXTURE_2D, texture);
01945 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
01946 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
01947
01948 return texture;
01949 }
01950
01951 GLuint loadTexture(const char *filename)
01952 {
01953 GLuint texture;
01954 int width;
01955 int height;
01956 unsigned char *data;
01957 FILE *file;
01958
01959
01960 file = fopen( filename, "rb" );
01961 if ( file == NULL )
01962 return 0;
01963
01964 width = 128;
01965 height = 128;
01966 data = (unsigned char*)malloc(width * height * 3);
01967
01968 fread(data, width * height * 3, 1, file );
01969 fclose(file);
01970
01971 glGenTextures(1, &texture);
01972 glBindTexture(GL_TEXTURE_2D, texture);
01973
01974 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
01975 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
01976 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
01977 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
01978 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
01979
01980 gluBuild2DMipmaps(
01981 GL_TEXTURE_2D,
01982 3,
01983 width,
01984 height,
01985 GL_RGB,
01986 GL_UNSIGNED_BYTE,
01987 data);
01988
01989 free(data);
01990
01991 return texture;
01992 }
01993
01994
01995 void init(void)
01996 {
01997 FMOD_RESULT result;
01998 bool listenerflag = true;
01999 FMOD_VECTOR listenerpos = { 0.0f, 0.0f, 0.0f };
02000 FMOD_SPEAKERMODE speakermode;
02001
02002 printf("==================================================================\n");
02003 printf("3D example. Copyright (c) Firelight Technologies 2004-2011.\n");
02004 printf("==================================================================\n\n");
02005
02006 result = FMOD::EventSystem_Create(&fmodEventSystem);
02007 ERRCHECK(result);
02008 result = FMOD::NetEventSystem_Init(fmodEventSystem);
02009 ERRCHECK(result);
02010 result = fmodEventSystem->getSystemObject(&fmodSystem);
02011 ERRCHECK(result);
02012 result = fmodSystem->getDriverCaps(0,0,0,&speakermode);
02013 ERRCHECK(result);
02014 result = fmodSystem->setSpeakerMode(speakermode);
02015 ERRCHECK(result);
02016
02017 result = fmodEventSystem->init(32, FMOD_INIT_3D_RIGHTHANDED, 0, FMOD_EVENT_INIT_NORMAL);
02018
02019 ERRCHECK(result);
02020
02021 ERRCHECK(result);
02022 ros::NodeHandle ph("~");
02023 std::string mediaPath("files");
02024 ph.param("MediaPath",mediaPath,mediaPath);
02025 result = fmodEventSystem->load((mediaPath + "/examples1.fev").c_str(), 0, &fmodEventProject);
02026 ERRCHECK(result);
02027 result = fmodEventProject->getGroup("FeatureDemonstration/3D Events", true, &fmodEventGroup);
02028 ERRCHECK(result);
02029
02030
02031
02032
02033 result = fmodSystem->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &global_lowpass);
02034 ERRCHECK(result);
02035
02036 result = global_lowpass->setParameter(FMOD_DSP_LOWPASS_CUTOFF, 1000);
02037 ERRCHECK(result);
02038
02039 result = global_lowpass->setBypass(true);
02040 ERRCHECK(result);
02041
02042 result = fmodSystem->addDSP(global_lowpass, 0);
02043 ERRCHECK(result);
02044
02045
02046 initObjects();
02047
02048 result = fmodSystem->setGeometrySettings(200.0f);
02049 ERRCHECK(result);
02050
02051 printf("Loading geometry...");
02052
02053
02054
02055
02056
02057
02058
02059 printf("done.\n");
02060
02061
02062
02063
02064 printf("Loading textures...\n");
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110 }
02111
02112 GlutCloseClass::~GlutCloseClass()
02113 {
02114 glDeleteTextures( 1, &texture );
02115
02116 freeGeometry(walls);
02117 freeGeometry(rotatingMesh);
02118
02119 fmodEventSystem->release();
02120 FMOD::NetEventSystem_Shutdown();
02121
02122
02123 }
02124 }
02125
02126 using namespace FMOD;
02127
02128 void handleManual(const sensor_msgs::Joy::ConstPtr& joy)
02129 {
02130 boost::mutex::scoped_lock l(joyMux);
02131 joystickData.axes.resize(6);
02132 joystickData.axes[0] = joy->axes[0]*32768;
02133 joystickData.axes[1] = joy->axes[1]*32768;
02134 }
02135
02136 void handleTarget(const auv_msgs::NavSts::ConstPtr& ref)
02137 {
02138 boost::mutex::scoped_lock l(joyMux);
02139 target = *ref;
02140 }
02141
02142 void handleTarget2(const geometry_msgs::PointStamped::ConstPtr& ref)
02143 {
02144 boost::mutex::scoped_lock l(joyMux);
02145 target.position.north = ref->point.x;
02146 target.position.east = ref->point.y;
02147 target.position.depth = ref->point.z;
02148 }
02149
02150 void handleEstimates(const auv_msgs::NavSts::ConstPtr& estimate)
02151 {
02152 boost::mutex::scoped_lock l(joyMux);
02153 state = *estimate;
02154 std_msgs::Float32MultiArrayPtr data(new std_msgs::Float32MultiArray());
02155
02156 LogData[0] = DistanceToPath;
02157 LogData[1] = DirectionToTarget;
02158 LogData[2] = RabbitNorth;
02159 LogData[3] = RabbitEast;
02160 LogData[4] = objects[0].zPos;
02161 LogData[5] = objects[0].xPos;
02162 LogData[6] = objects[6].zPos;;
02163 LogData[7] = objects[6].xPos;;
02164 LogData[8] = WPnorth[1];
02165 LogData[9] = WPeast[1];
02166 LogData[10] = WPnorth[2];
02167 LogData[11] = WPeast[2];
02168
02169 data->data.insert(data->data.begin(), &LogData[0], &LogData[12]);
02170 data->data.insert(data->data.end(), configInfo.begin(), configInfo.end());
02171 infopub.publish(data);
02172 }
02173
02174
02175 int main(int argc, char **argv)
02176 {
02177 ros::init(argc,argv,"audioex");
02178 ros::NodeHandle nh;
02179 ros::Subscriber manualIn = nh.subscribe<sensor_msgs::Joy>("joy",1,&handleManual);
02180
02181 infopub = nh.advertise<std_msgs::Float32MultiArray>("acousticvr_info",1);
02182
02183 ros::Subscriber targetRef = nh.subscribe<auv_msgs::NavSts>("target_navsts", 1,
02184 &handleTarget);
02185 ros::Subscriber targetRef2 = nh.subscribe<geometry_msgs::PointStamped>("target_point", 1,
02186 &handleTarget2);
02187 ros::Subscriber stateHat = nh.subscribe<auv_msgs::NavSts>("stateHat", 1,
02188 &handleEstimates);
02189 boost::thread t(static_cast<void(*)(void)>(&ros::spin));
02190 joystickData.axes.resize(6);
02191
02192
02193 try
02194 {
02195 ros::NodeHandle ph("~");
02196 ph.param("ObjectLat",ObjectLat,ObjectLat);
02197 ph.param("ObjectLong", ObjectLong, ObjectLong);
02198 ph.param("AltitudeSetPoint", AltitudeSetPoint, AltitudeSetPoint);
02199 ph.param("Doppler", Doppler, Doppler);
02200 ph.param("Silence_angle", SilenceAngle, SilenceAngle);
02201 ph.param("Verbal_angle", VerbalAngle, VerbalAngle);
02202 ph.param("NonLinear_coeff", NonLinearCoeff, NonLinearCoeff);
02203 ph.param("Guidance_Mode", GuidanceMode, GuidanceMode);
02204 ph.param("Task_Mode", TaskMode, TaskMode);
02205 ph.param("K_Diter_Time", KDiterTime, KDiterTime);
02206 ph.param("AmpDiter", AmpDiter, AmpDiter);
02207 ph.param("FreqDiter", FreqDiter, FreqDiter);
02208 ph.param("JoyStick_Mode", JoyStickMode, JoyStickMode);
02209 ph.param("PathVelocity", PathVelocity, PathVelocity);
02210 ph.param("SpeedProfile", SpeedProfile, SpeedProfile);
02211 ph.param("NonLinear_coeff_distance", NonLinearCoeffDist, NonLinearCoeffDist);
02212 ph.param("Kintegral", Ki, Ki);
02213 ph.param("Sound", Sound, Sound);
02214 ph.param("PathStartX", PathStartX1, PathStartX1);
02215 ph.param("PathStartY", PathStartY1, PathStartY1);
02216 ph.param("RabbitDistance", RabbitDistance, RabbitDistance);
02217
02218 float LogConfig[8] = {NonLinearCoeff,TaskMode,PathVelocity,SpeedProfile,RabbitDistance,NonLinearCoeffDist,Ki,Sound};
02219 configInfo.assign(&LogConfig[0], &LogConfig[8]);
02220
02221
02222
02223 srand((unsigned)time(0));
02224
02225
02226
02227
02228
02229
02230 std::string texturePath("files");
02231 ph.param("TexturePath",texturePath,texturePath);
02232
02233 gui.reset(new labust::gui::AAGui(texturePath));
02234 glutDisplayFunc(display);
02235 glutReshapeFunc(reshapeFunc);
02236 glutMouseFunc(mouseFunc);
02237 glutMotionFunc(motionFunc);
02238 glutKeyboardFunc(keyboardFunc);
02239 glutKeyboardUpFunc(keyboardUpFunc);
02240 glutSpecialUpFunc(specialKeyUpFunc);
02241 glutTimerFunc(INTERFACE_UPDATETIME, timerFunc, 0);
02242 init();
02243
02244 gui->start();
02245
02246
02247
02248
02249
02250 }
02251 catch(std::exception &e)
02252 {
02253 std::cout<<e.what()<<std::endl;
02254 }
02255 return 0;
02256 }