Changeset 15 in flair-src for trunk/lib/FlairSimulator/src/Model_impl.cpp
- Timestamp:
- 04/08/16 15:40:57 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/FlairSimulator/src/Model_impl.cpp
r10 r15 50 50 51 51 #ifdef GL 52 Model_impl::Model_impl(Model* self,std::string name,ISceneManager* scenemanager,vrpn_Connection_IP* vrpn) 53 : ISceneNode(scenemanager->getRootSceneNode(), scenemanager, -1),Thread(self,name,50),vrpn_Tracker( name.c_str(), vrpn ) 52 Model_impl::Model_impl(Model *self, std::string name, 53 ISceneManager *scenemanager, vrpn_Connection_IP *vrpn) 54 : ISceneNode(scenemanager->getRootSceneNode(), scenemanager, -1), 55 Thread(self, name, 50), vrpn_Tracker(name.c_str(), vrpn) 54 56 55 57 #else 56 Model_impl::Model_impl(Model * self,std::string name,vrpn_Connection_IP*vrpn)57 : Thread(self, name,50),vrpn_Tracker( name.c_str(), vrpn)58 Model_impl::Model_impl(Model *self, std::string name, vrpn_Connection_IP *vrpn) 59 : Thread(self, name, 50), vrpn_Tracker(name.c_str(), vrpn) 58 60 #endif 59 61 { 60 this->self=self; 61 62 #ifdef GL 63 //for sync with gui 64 cond=new ConditionVariable(this,name); 65 sync_count=0; 66 67 //collisions 68 collision_mutex=new Mutex(this); 69 collision_occured=false; 70 71 //selector for collisions 72 selector = getSceneManager()->createTriangleSelectorFromBoundingBox(this); 73 setTriangleSelector(selector); 74 meta_selector = getSceneManager()->createMetaTriangleSelector(); 75 76 anim = getSceneManager()->createCollisionResponseAnimator(meta_selector, this,vector3df(1,1,1),vector3df(0,0,0), vector3df(0,0,0)); 77 addAnimator(anim); 78 79 //camera 80 camera =getSceneManager()->addCameraSceneNode(); 81 camera->setAspectRatio(getGui()->getAspectRatio());//on force a cause du view port 82 camera->setUpVector(vector3df(0,0,1)); 83 84 animator=new AnimPoursuite(this); 85 camera->addAnimator(animator); 86 camera->setFarValue(8000); 87 88 position_init=false; 89 #endif 90 91 //init user interface 92 Tab* tab=new Tab(getSimulator()->GetTabWidget(),ObjectName()); 93 tabwidget=new TabWidget(tab->NewRow(),"tabs"); 94 Tab* sampl=new Tab(tabwidget,"sampling"); 95 dT=new DoubleSpinBox(sampl->NewRow(),"Tech (s):",0.001,1,0.001,3); 96 Tab* layout=new Tab(tabwidget,"optitrack"); 97 enable_opti=new CheckBox(layout->NewRow(),"enabled"); 98 Tab* init=new Tab(tabwidget,"init"); 99 pos_init=new Vector3DSpinBox(init->NewRow(),"position",-50,50,1); 100 yaw_init=new SpinBox(init->NewRow(),"yaw (deg):",-180,180,10); 101 102 //modele 103 states_mutex=new Mutex(this); 104 self->state[0].Pos=pos_init->Value(); 105 self->state[0].Vel.x=0; 106 self->state[0].Vel.y=0; 107 self->state[0].Vel.z=0; 108 self->state[0].Quat=ComputeInitRotation(Quaternion(1,0,0,0)); 109 self->state[0].W.x=0; 110 self->state[0].W.y=0; 111 self->state[0].W.z=0; 112 113 self->state[-1]=self->state[0]; 114 self->state[-2]=self->state[0]; 115 116 cvmatrix_descriptor* desc=new cvmatrix_descriptor(13,1); 117 desc->SetElementName(0,0,"q0"); 118 desc->SetElementName(1,0,"q1"); 119 desc->SetElementName(2,0,"q2"); 120 desc->SetElementName(3,0,"q3"); 121 desc->SetElementName(4,0,"x"); 122 desc->SetElementName(5,0,"y"); 123 desc->SetElementName(6,0,"z"); 124 desc->SetElementName(7,0,"wx"); 125 desc->SetElementName(8,0,"wy"); 126 desc->SetElementName(9,0,"wz"); 127 desc->SetElementName(10,0,"vx"); 128 desc->SetElementName(11,0,"vy"); 129 desc->SetElementName(12,0,"vz"); 130 output=new cvmatrix(this,desc,floatType,"state"); 131 132 self->AddDataToLog(output); 133 } 134 135 Model_impl::~Model_impl() 136 { 137 SafeStop(); 138 Join(); 139 #ifdef GL 140 remove();//remove ISceneNode 62 this->self = self; 63 64 #ifdef GL 65 // for sync with gui 66 cond = new ConditionVariable(this, name); 67 sync_count = 0; 68 69 // collisions 70 collision_mutex = new Mutex(this); 71 collision_occured = false; 72 73 // selector for collisions 74 selector = getSceneManager()->createTriangleSelectorFromBoundingBox(this); 75 setTriangleSelector(selector); 76 meta_selector = getSceneManager()->createMetaTriangleSelector(); 77 78 anim = getSceneManager()->createCollisionResponseAnimator( 79 meta_selector, this, vector3df(1, 1, 1), vector3df(0, 0, 0), 80 vector3df(0, 0, 0)); 81 addAnimator(anim); 82 83 // camera 84 camera = getSceneManager()->addCameraSceneNode(); 85 camera->setAspectRatio( 86 getGui()->getAspectRatio()); // on force a cause du view port 87 camera->setUpVector(vector3df(0, 0, 1)); 88 89 animator = new AnimPoursuite(this); 90 camera->addAnimator(animator); 91 camera->setFarValue(8000); 92 93 position_init = false; 94 #endif 95 96 // init user interface 97 Tab *tab = new Tab(getSimulator()->GetTabWidget(), ObjectName()); 98 tabwidget = new TabWidget(tab->NewRow(), "tabs"); 99 Tab *sampl = new Tab(tabwidget, "sampling"); 100 dT = new DoubleSpinBox(sampl->NewRow(), "Tech (s):", 0.001, 1, 0.001, 3); 101 Tab *layout = new Tab(tabwidget, "optitrack"); 102 enable_opti = new CheckBox(layout->NewRow(), "enabled"); 103 Tab *init = new Tab(tabwidget, "init"); 104 pos_init = new Vector3DSpinBox(init->NewRow(), "position", -50, 50, 1); 105 yaw_init = new SpinBox(init->NewRow(), "yaw (deg):", -180, 180, 10); 106 107 // modele 108 states_mutex = new Mutex(this); 109 self->state[0].Pos = pos_init->Value(); 110 self->state[0].Vel.x = 0; 111 self->state[0].Vel.y = 0; 112 self->state[0].Vel.z = 0; 113 self->state[0].Quat = ComputeInitRotation(Quaternion(1, 0, 0, 0)); 114 self->state[0].W.x = 0; 115 self->state[0].W.y = 0; 116 self->state[0].W.z = 0; 117 118 self->state[-1] = self->state[0]; 119 self->state[-2] = self->state[0]; 120 121 cvmatrix_descriptor *desc = new cvmatrix_descriptor(13, 1); 122 desc->SetElementName(0, 0, "q0"); 123 desc->SetElementName(1, 0, "q1"); 124 desc->SetElementName(2, 0, "q2"); 125 desc->SetElementName(3, 0, "q3"); 126 desc->SetElementName(4, 0, "x"); 127 desc->SetElementName(5, 0, "y"); 128 desc->SetElementName(6, 0, "z"); 129 desc->SetElementName(7, 0, "wx"); 130 desc->SetElementName(8, 0, "wy"); 131 desc->SetElementName(9, 0, "wz"); 132 desc->SetElementName(10, 0, "vx"); 133 desc->SetElementName(11, 0, "vy"); 134 desc->SetElementName(12, 0, "vz"); 135 output = new cvmatrix(this, desc, floatType, "state"); 136 137 self->AddDataToLog(output); 138 } 139 140 Model_impl::~Model_impl() { 141 SafeStop(); 142 Join(); 143 #ifdef GL 144 remove(); // remove ISceneNode 141 145 #endif 142 146 } 143 147 144 148 Quaternion Model_impl::ComputeInitRotation(Quaternion quat_in) { 145 Quaternion yaw_rot_quat; 146 Euler yaw_rot_euler(0,0,Euler::ToRadian(yaw_init->Value())); 147 yaw_rot_euler.ToQuaternion(yaw_rot_quat); 148 return yaw_rot_quat*quat_in; 149 } 150 151 void Model_impl::mainloop(void) 152 { 153 if(enable_opti->Value()==false) return; 154 vrpn_gettimeofday(&_timestamp, NULL); 155 vrpn_Tracker::timestamp = _timestamp; 156 157 //change to vrpn reference 149 Quaternion yaw_rot_quat; 150 Euler yaw_rot_euler(0, 0, Euler::ToRadian(yaw_init->Value())); 151 yaw_rot_euler.ToQuaternion(yaw_rot_quat); 152 return yaw_rot_quat * quat_in; 153 } 154 155 void Model_impl::mainloop(void) { 156 if (enable_opti->Value() == false) 157 return; 158 vrpn_gettimeofday(&_timestamp, NULL); 159 vrpn_Tracker::timestamp = _timestamp; 160 161 // change to vrpn reference 162 states_mutex->GetMutex(); 163 Quaternion quat = getSimulator()->ToVRPNReference(self->state[0].Quat); 164 Vector3D position = getSimulator()->ToVRPNReference(self->state[0].Pos); 165 states_mutex->ReleaseMutex(); 166 167 pos[0] = position.x; 168 pos[1] = position.y; 169 pos[2] = position.z; 170 // warning: d_quat is defined as (qx,qy,qz,qw), which is different from 171 // flair::core::Quaternion 172 d_quat[0] = quat.q1; 173 d_quat[1] = quat.q2; 174 d_quat[2] = quat.q3; 175 d_quat[3] = quat.q0; 176 177 char msgbuf[1000]; 178 179 d_sensor = 0; 180 181 int len = vrpn_Tracker::encode_to(msgbuf); 182 183 if (d_connection->pack_message(len, _timestamp, position_m_id, d_sender_id, 184 msgbuf, vrpn_CONNECTION_LOW_LATENCY)) { 185 fprintf(stderr, "can't write message: tossing\n"); 186 } 187 188 server_mainloop(); 189 } 190 191 #ifdef GL 192 ITriangleSelector *Model_impl::TriangleSelector(void) { return selector; } 193 194 IMetaTriangleSelector *Model_impl::MetaTriangleSelector(void) { 195 return meta_selector; 196 } 197 198 void Model_impl::UpdatePos(void) { 199 vector3df nodePosition; 200 Quaternion nodeOrientation; 201 Euler euler; 202 203 states_mutex->GetMutex(); 204 nodePosition = ToIrrlichtCoordinates(self->state[0].Pos); 205 nodeOrientation = ToIrrlichtOrientation(self->state[0].Quat); 206 states_mutex->ReleaseMutex(); 207 208 setPosition(nodePosition); 209 210 nodeOrientation.ToEuler(euler); 211 ISceneNode::setRotation(Euler::ToDegree(1) * 212 vector3df(euler.roll, euler.pitch, euler.yaw)); 213 214 if (position_init == false) { 215 anim->setTargetNode(this); // a faire pour se teleporter sans les collisions 216 position_init = true; 217 } 218 219 self->AnimateModel(); 220 } 221 222 void Model_impl::CheckCollision(void) { 223 // TODO: setEllipsoidRadius should be called in Model::setScale 224 // but we need to call recalculateBoundingBox 225 anim->setEllipsoidRadius(getTransformedBoundingBox().getExtent()); 226 227 if (anim->collisionOccurred() == true) { 228 vector3df pos; 229 vector3df pos_rel; 230 vector3df nodePosition; 231 pos = anim->getCollisionPoint(); 232 nodePosition = getPosition(); 233 pos_rel = pos - nodePosition; 234 // printf("collision %f %f %f\n",pos.X,pos.Y,pos.Z); 235 // printf("drone %f %f %f\n",nodePosition.X,nodePosition.Y,nodePosition.Z); 236 // printf("rel %f %f %f\n",pos_rel.X,pos_rel.Z,pos_rel.Y); 237 238 collision_mutex->GetMutex(); 239 collision_occured = true; 240 collision_point = ToSimulatorCoordinates(nodePosition); 241 collision_mutex->ReleaseMutex(); 242 } 243 } 244 245 void Model_impl::CollisionHandler(void) { 246 collision_mutex->GetMutex(); 247 if (collision_occured == true) { 248 collision_occured = false; 158 249 states_mutex->GetMutex(); 159 Quaternion quat=getSimulator()->ToVRPNReference(self->state[0].Quat); 160 Vector3D position=getSimulator()->ToVRPNReference(self->state[0].Pos); 250 self->state[0].Pos = collision_point; 251 self->state[-1].Pos = self->state[0].Pos; 252 self->state[-2].Pos = self->state[0].Pos; 161 253 states_mutex->ReleaseMutex(); 162 163 pos[0]=position.x; 164 pos[1]=position.y; 165 pos[2]=position.z; 166 //warning: d_quat is defined as (qx,qy,qz,qw), which is different from flair::core::Quaternion 167 d_quat[0] = quat.q1; 168 d_quat[1] = quat.q2; 169 d_quat[2] = quat.q3; 170 d_quat[3] = quat.q0; 171 172 char msgbuf[1000]; 173 174 d_sensor = 0; 175 176 int len = vrpn_Tracker::encode_to(msgbuf); 177 178 if (d_connection->pack_message(len, _timestamp, position_m_id, d_sender_id, msgbuf, vrpn_CONNECTION_LOW_LATENCY)) 179 { 180 fprintf(stderr,"can't write message: tossing\n"); 254 } 255 collision_mutex->ReleaseMutex(); 256 } 257 258 void Model_impl::OnRegisterSceneNode(void) { 259 if (IsVisible) 260 SceneManager->registerNodeForRendering(this); 261 262 ISceneNode::OnRegisterSceneNode(); 263 } 264 265 void Model_impl::render(void) { 266 IVideoDriver *driver = SceneManager->getVideoDriver(); 267 driver->setTransform(ETS_WORLD, AbsoluteTransformation); 268 } 269 270 // le premier arrive attend l'autre 271 void Model_impl::SynchronizationPoint() { 272 cond->GetMutex(); 273 sync_count++; 274 275 if (sync_count < 2) { 276 cond->CondWait(); 277 } else { 278 cond->CondSignal(); 279 } 280 281 cond->ReleaseMutex(); 282 } 283 #endif // GL 284 285 void Model_impl::Run(void) { 286 // Ask Xenomai to warn us upon switches to secondary mode. 287 WarnUponSwitches(true); 288 289 #ifdef GL 290 // synchronize with gui 291 SynchronizationPoint(); 292 #endif 293 294 SetPeriodMS(dT->Value() * 1000.); 295 296 while (!ToBeStopped()) { 297 if (dT->ValueChanged()) 298 SetPeriodMS(dT->Value() * 1000.); 299 WaitPeriod(); 300 301 #ifdef GL 302 CollisionHandler(); 303 #endif 304 states_mutex->GetMutex(); 305 self->CalcModel(); 306 307 output->GetMutex(); 308 output->SetValueNoMutex(0, 0, self->state[0].Quat.q0); 309 output->SetValueNoMutex(1, 0, self->state[0].Quat.q1); 310 output->SetValueNoMutex(2, 0, self->state[0].Quat.q2); 311 output->SetValueNoMutex(3, 0, self->state[0].Quat.q3); 312 output->SetValueNoMutex(4, 0, self->state[0].Pos.x); 313 output->SetValueNoMutex(5, 0, self->state[0].Pos.y); 314 output->SetValueNoMutex(6, 0, self->state[0].Pos.z); 315 output->SetValueNoMutex(7, 0, self->state[0].W.x); 316 output->SetValueNoMutex(8, 0, self->state[0].W.y); 317 output->SetValueNoMutex(9, 0, self->state[0].W.z); 318 output->SetValueNoMutex(10, 0, self->state[0].Vel.x); 319 output->SetValueNoMutex(11, 0, self->state[0].Vel.y); 320 output->SetValueNoMutex(12, 0, self->state[0].Vel.z); 321 output->ReleaseMutex(); 322 output->SetDataTime(GetTime()); 323 324 self->state.Update(); 325 326 if (pos_init->ValueChanged() || yaw_init->ValueChanged()) { 327 self->state[-1].Quat = ComputeInitRotation(Quaternion(1, 0, 0, 0)); 328 self->state[-2].Quat = ComputeInitRotation(Quaternion(1, 0, 0, 0)); 329 self->state[-1].Pos = pos_init->Value(); 330 self->state[-2].Pos = self->state[-1].Pos; 331 #ifdef GL 332 position_init = false; 333 #endif 181 334 } 182 335 183 server_mainloop();184 }185 186 #ifdef GL187 ITriangleSelector* Model_impl::TriangleSelector(void)188 {189 return selector;190 }191 192 IMetaTriangleSelector* Model_impl::MetaTriangleSelector(void)193 {194 return meta_selector;195 }196 197 void Model_impl::UpdatePos(void)198 {199 vector3df nodePosition;200 Quaternion nodeOrientation;201 Euler euler;202 203 states_mutex->GetMutex();204 nodePosition=ToIrrlichtCoordinates(self->state[0].Pos);205 nodeOrientation=ToIrrlichtOrientation(self->state[0].Quat);206 336 states_mutex->ReleaseMutex(); 207 337 208 setPosition(nodePosition); 209 210 nodeOrientation.ToEuler(euler); 211 ISceneNode::setRotation(Euler::ToDegree(1)*vector3df(euler.roll,euler.pitch,euler.yaw)); 212 213 if(position_init==false) 214 { 215 anim->setTargetNode(this); // a faire pour se teleporter sans les collisions 216 position_init=true; 217 } 218 219 self->AnimateModel(); 220 } 221 222 void Model_impl::CheckCollision(void) 223 { 224 //TODO: setEllipsoidRadius should be called in Model::setScale 225 //but we need to call recalculateBoundingBox 226 anim->setEllipsoidRadius(getTransformedBoundingBox().getExtent()); 227 228 if(anim->collisionOccurred()==true) 229 { 230 vector3df pos; 231 vector3df pos_rel; 232 vector3df nodePosition; 233 pos= anim->getCollisionPoint(); 234 nodePosition=getPosition(); 235 pos_rel=pos-nodePosition; 236 //printf("collision %f %f %f\n",pos.X,pos.Y,pos.Z); 237 //printf("drone %f %f %f\n",nodePosition.X,nodePosition.Y,nodePosition.Z); 238 //printf("rel %f %f %f\n",pos_rel.X,pos_rel.Z,pos_rel.Y); 239 240 collision_mutex->GetMutex(); 241 collision_occured=true; 242 collision_point=ToSimulatorCoordinates(nodePosition); 243 collision_mutex->ReleaseMutex(); 244 } 245 } 246 247 void Model_impl::CollisionHandler(void) 248 { 249 collision_mutex->GetMutex(); 250 if(collision_occured==true) 251 { 252 collision_occured=false; 253 states_mutex->GetMutex(); 254 self->state[0].Pos=collision_point; 255 self->state[-1].Pos=self->state[0].Pos; 256 self->state[-2].Pos=self->state[0].Pos; 257 states_mutex->ReleaseMutex(); 258 } 259 collision_mutex->ReleaseMutex(); 260 } 261 262 void Model_impl::OnRegisterSceneNode(void) 263 { 264 if (IsVisible) 265 SceneManager->registerNodeForRendering(this); 266 267 ISceneNode::OnRegisterSceneNode(); 268 } 269 270 void Model_impl::render(void) 271 { 272 IVideoDriver* driver = SceneManager->getVideoDriver(); 273 driver->setTransform(ETS_WORLD, AbsoluteTransformation); 274 } 275 276 //le premier arrive attend l'autre 277 void Model_impl::SynchronizationPoint() 278 { 279 cond->GetMutex(); 280 sync_count++; 281 282 if (sync_count < 2) 283 { 284 cond->CondWait(); 285 } 286 else 287 { 288 cond->CondSignal(); 289 } 290 291 cond->ReleaseMutex(); 292 } 293 #endif //GL 294 295 void Model_impl::Run(void) 296 { 297 // Ask Xenomai to warn us upon switches to secondary mode. 298 WarnUponSwitches(true); 299 300 #ifdef GL 301 //synchronize with gui 302 SynchronizationPoint(); 303 #endif 304 305 SetPeriodMS(dT->Value()*1000.); 306 307 while(!ToBeStopped()) 308 { 309 if(dT->ValueChanged()) SetPeriodMS(dT->Value()*1000.); 310 WaitPeriod(); 311 312 #ifdef GL 313 CollisionHandler(); 314 #endif 315 states_mutex->GetMutex(); 316 self->CalcModel(); 317 318 output->GetMutex(); 319 output->SetValueNoMutex(0,0,self->state[0].Quat.q0); 320 output->SetValueNoMutex(1,0,self->state[0].Quat.q1); 321 output->SetValueNoMutex(2,0,self->state[0].Quat.q2); 322 output->SetValueNoMutex(3,0,self->state[0].Quat.q3); 323 output->SetValueNoMutex(4,0,self->state[0].Pos.x); 324 output->SetValueNoMutex(5,0,self->state[0].Pos.y); 325 output->SetValueNoMutex(6,0,self->state[0].Pos.z); 326 output->SetValueNoMutex(7,0,self->state[0].W.x); 327 output->SetValueNoMutex(8,0,self->state[0].W.y); 328 output->SetValueNoMutex(9,0,self->state[0].W.z); 329 output->SetValueNoMutex(10,0,self->state[0].Vel.x); 330 output->SetValueNoMutex(11,0,self->state[0].Vel.y); 331 output->SetValueNoMutex(12,0,self->state[0].Vel.z); 332 output->ReleaseMutex(); 333 output->SetDataTime(GetTime()); 334 335 self->state.Update(); 336 337 if(pos_init->ValueChanged() || yaw_init->ValueChanged()) 338 { 339 self->state[-1].Quat=ComputeInitRotation(Quaternion(1,0,0,0)); 340 self->state[-2].Quat=ComputeInitRotation(Quaternion(1,0,0,0)); 341 self->state[-1].Pos=pos_init->Value(); 342 self->state[-2].Pos=self->state[-1].Pos; 343 #ifdef GL 344 position_init=false; 345 #endif 346 } 347 348 states_mutex->ReleaseMutex(); 349 350 self->ProcessUpdate(output); 351 352 } 353 354 WarnUponSwitches(false); 355 } 338 self->ProcessUpdate(output); 339 } 340 341 WarnUponSwitches(false); 342 }
Note:
See TracChangeset
for help on using the changeset viewer.