source: flair-src/trunk/lib/FlairSimulator/src/Model_impl.cpp@ 153

Last change on this file since 153 was 151, checked in by Sanahuja Guillaume, 7 years ago

add timestamp to simucamera producer

File size: 9.3 KB
RevLine 
[10]1// %flair:license{
[15]2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
[10]4// %flair:license}
[8]5// created: 2013/03/25
6// filename: Model_impl.cpp
7//
8// author: Guillaume Sanahuja
9// Copyright Heudiasyc UMR UTC/CNRS 7253
10//
11// version: $Id: $
12//
13// purpose: classe definissant un modele a simuler
14//
15/*********************************************************************/
16
17#include "Model.h"
18#include "Model_impl.h"
19#include "Simulator.h"
20#include "TabWidget.h"
21#include "Tab.h"
22#include "DoubleSpinBox.h"
23#include "Vector3DSpinBox.h"
24#include "SpinBox.h"
25#include "CheckBox.h"
26#include "cvmatrix.h"
27#include "Euler.h"
28#include <math.h>
29
30#ifdef GL
31#include "ConditionVariable.h"
32#include "Gui.h"
33#include "Gui_impl.h"
34#include <ISceneManager.h>
35#include <ISceneNodeAnimatorCollisionResponse.h>
36#include <IMetaTriangleSelector.h>
37#include <IVideoDriver.h>
38#include <ICameraSceneNode.h>
[69]39#include "FollowMeCamera.h"
40
[8]41using namespace irr;
42using namespace video;
43using namespace scene;
44using namespace core;
45using namespace io;
46#endif
47
48using namespace flair::core;
49using namespace flair::gui;
50using namespace flair::simulator;
51
[15]52#ifdef GL
53Model_impl::Model_impl(Model *self, std::string name,
54 ISceneManager *scenemanager, vrpn_Connection_IP *vrpn)
55 : ISceneNode(scenemanager->getRootSceneNode(), scenemanager, -1),
56 Thread(self, name, 50), vrpn_Tracker(name.c_str(), vrpn)
[8]57
58#else
[15]59Model_impl::Model_impl(Model *self, std::string name, vrpn_Connection_IP *vrpn)
60 : Thread(self, name, 50), vrpn_Tracker(name.c_str(), vrpn)
61#endif
[8]62{
[15]63 this->self = self;
[8]64
65#ifdef GL
[15]66 // for sync with gui
67 cond = new ConditionVariable(this, name);
68 sync_count = 0;
[8]69
[15]70 // collisions
71 collision_mutex = new Mutex(this);
72 collision_occured = false;
[8]73
[15]74 // selector for collisions
75 selector = getSceneManager()->createTriangleSelectorFromBoundingBox(this);
76 setTriangleSelector(selector);
77 meta_selector = getSceneManager()->createMetaTriangleSelector();
[8]78
[15]79 anim = getSceneManager()->createCollisionResponseAnimator(
80 meta_selector, this, vector3df(1, 1, 1), vector3df(0, 0, 0),
81 vector3df(0, 0, 0));
82 addAnimator(anim);
[8]83
[15]84 // camera
[70]85 camera = new FollowMeCamera(this,name);
[8]86
[15]87 position_init = false;
[8]88#endif
89
[15]90 // init user interface
91 Tab *tab = new Tab(getSimulator()->GetTabWidget(), ObjectName());
92 tabwidget = new TabWidget(tab->NewRow(), "tabs");
93 Tab *sampl = new Tab(tabwidget, "sampling");
94 dT = new DoubleSpinBox(sampl->NewRow(), "Tech (s):", 0.001, 1, 0.001, 3);
95 Tab *layout = new Tab(tabwidget, "optitrack");
96 enable_opti = new CheckBox(layout->NewRow(), "enabled");
97 Tab *init = new Tab(tabwidget, "init");
98 pos_init = new Vector3DSpinBox(init->NewRow(), "position", -50, 50, 1);
99 yaw_init = new SpinBox(init->NewRow(), "yaw (deg):", -180, 180, 10);
[8]100
[15]101 // modele
102 states_mutex = new Mutex(this);
103 self->state[0].Pos = pos_init->Value();
104 self->state[0].Vel.x = 0;
105 self->state[0].Vel.y = 0;
106 self->state[0].Vel.z = 0;
107 self->state[0].Quat = ComputeInitRotation(Quaternion(1, 0, 0, 0));
108 self->state[0].W.x = 0;
109 self->state[0].W.y = 0;
110 self->state[0].W.z = 0;
[8]111
[15]112 self->state[-1] = self->state[0];
113 self->state[-2] = self->state[0];
[8]114
[15]115 cvmatrix_descriptor *desc = new cvmatrix_descriptor(13, 1);
116 desc->SetElementName(0, 0, "q0");
117 desc->SetElementName(1, 0, "q1");
118 desc->SetElementName(2, 0, "q2");
119 desc->SetElementName(3, 0, "q3");
120 desc->SetElementName(4, 0, "x");
121 desc->SetElementName(5, 0, "y");
122 desc->SetElementName(6, 0, "z");
123 desc->SetElementName(7, 0, "wx");
124 desc->SetElementName(8, 0, "wy");
125 desc->SetElementName(9, 0, "wz");
126 desc->SetElementName(10, 0, "vx");
127 desc->SetElementName(11, 0, "vy");
128 desc->SetElementName(12, 0, "vz");
129 output = new cvmatrix(this, desc, floatType, "state");
[148]130 delete desc;
[8]131
[15]132 self->AddDataToLog(output);
[8]133}
134
[15]135Model_impl::~Model_impl() {
136 SafeStop();
137 Join();
[8]138#ifdef GL
[15]139 remove(); // remove ISceneNode
[8]140#endif
141}
142
143Quaternion Model_impl::ComputeInitRotation(Quaternion quat_in) {
[15]144 Quaternion yaw_rot_quat;
145 Euler yaw_rot_euler(0, 0, Euler::ToRadian(yaw_init->Value()));
146 yaw_rot_euler.ToQuaternion(yaw_rot_quat);
147 return yaw_rot_quat * quat_in;
[8]148}
149
[15]150void Model_impl::mainloop(void) {
151 if (enable_opti->Value() == false)
152 return;
153 vrpn_gettimeofday(&_timestamp, NULL);
154 vrpn_Tracker::timestamp = _timestamp;
[8]155
[15]156 // change to vrpn reference
157 states_mutex->GetMutex();
158 Quaternion quat = getSimulator()->ToVRPNReference(self->state[0].Quat);
159 Vector3D position = getSimulator()->ToVRPNReference(self->state[0].Pos);
160 states_mutex->ReleaseMutex();
[8]161
[15]162 pos[0] = position.x;
163 pos[1] = position.y;
164 pos[2] = position.z;
165 // warning: d_quat is defined as (qx,qy,qz,qw), which is different from
166 // 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;
[8]171
[15]172 char msgbuf[1000];
[8]173
[15]174 d_sensor = 0;
[8]175
[15]176 int len = vrpn_Tracker::encode_to(msgbuf);
[8]177
[15]178 if (d_connection->pack_message(len, _timestamp, position_m_id, d_sender_id,
179 msgbuf, vrpn_CONNECTION_LOW_LATENCY)) {
180 fprintf(stderr, "can't write message: tossing\n");
181 }
[8]182
[15]183 server_mainloop();
[8]184}
185
186#ifdef GL
[15]187ITriangleSelector *Model_impl::TriangleSelector(void) { return selector; }
[8]188
[15]189IMetaTriangleSelector *Model_impl::MetaTriangleSelector(void) {
190 return meta_selector;
[8]191}
192
[15]193void Model_impl::UpdatePos(void) {
194 vector3df nodePosition;
195 Quaternion nodeOrientation;
196 Euler euler;
[8]197
[15]198 states_mutex->GetMutex();
199 nodePosition = ToIrrlichtCoordinates(self->state[0].Pos);
200 nodeOrientation = ToIrrlichtOrientation(self->state[0].Quat);
201 states_mutex->ReleaseMutex();
[8]202
[15]203 setPosition(nodePosition);
[8]204
[15]205 nodeOrientation.ToEuler(euler);
[151]206 ISceneNode::setRotation(Euler::ToDegree(1) * vector3df(euler.roll,euler.pitch, euler.yaw));
[8]207
[15]208 if (position_init == false) {
209 anim->setTargetNode(this); // a faire pour se teleporter sans les collisions
210 position_init = true;
211 }
[8]212
[15]213 self->AnimateModel();
[8]214}
215
[15]216void Model_impl::CheckCollision(void) {
217 // TODO: setEllipsoidRadius should be called in Model::setScale
218 // but we need to call recalculateBoundingBox
219 anim->setEllipsoidRadius(getTransformedBoundingBox().getExtent());
[8]220
[15]221 if (anim->collisionOccurred() == true) {
222 vector3df pos;
223 vector3df pos_rel;
224 vector3df nodePosition;
225 pos = anim->getCollisionPoint();
226 nodePosition = getPosition();
227 pos_rel = pos - nodePosition;
228 // printf("collision %f %f %f\n",pos.X,pos.Y,pos.Z);
229 // printf("drone %f %f %f\n",nodePosition.X,nodePosition.Y,nodePosition.Z);
230 // printf("rel %f %f %f\n",pos_rel.X,pos_rel.Z,pos_rel.Y);
[8]231
232 collision_mutex->GetMutex();
[15]233 collision_occured = true;
234 collision_point = ToSimulatorCoordinates(nodePosition);
[8]235 collision_mutex->ReleaseMutex();
[15]236 }
[8]237}
[15]238
239void Model_impl::CollisionHandler(void) {
240 collision_mutex->GetMutex();
241 if (collision_occured == true) {
242 collision_occured = false;
243 states_mutex->GetMutex();
244 self->state[0].Pos = collision_point;
245 self->state[-1].Pos = self->state[0].Pos;
246 self->state[-2].Pos = self->state[0].Pos;
247 states_mutex->ReleaseMutex();
248 }
249 collision_mutex->ReleaseMutex();
[8]250}
251
[15]252void Model_impl::OnRegisterSceneNode(void) {
253 if (IsVisible)
254 SceneManager->registerNodeForRendering(this);
[8]255
[15]256 ISceneNode::OnRegisterSceneNode();
257}
[8]258
[15]259void Model_impl::render(void) {
260 IVideoDriver *driver = SceneManager->getVideoDriver();
261 driver->setTransform(ETS_WORLD, AbsoluteTransformation);
[8]262}
263
[15]264// le premier arrive attend l'autre
265void Model_impl::SynchronizationPoint() {
266 cond->GetMutex();
267 sync_count++;
[8]268
[15]269 if (sync_count < 2) {
270 cond->CondWait();
271 } else {
272 cond->CondSignal();
273 }
274
275 cond->ReleaseMutex();
276}
277#endif // GL
278
279void Model_impl::Run(void) {
280 // Ask Xenomai to warn us upon switches to secondary mode.
281 WarnUponSwitches(true);
282
[8]283#ifdef GL
[15]284 // synchronize with gui
285 SynchronizationPoint();
[8]286#endif
287
[15]288 SetPeriodMS(dT->Value() * 1000.);
[8]289
[15]290 while (!ToBeStopped()) {
291 if (dT->ValueChanged())
292 SetPeriodMS(dT->Value() * 1000.);
293 WaitPeriod();
[8]294
295#ifdef GL
[15]296 CollisionHandler();
[8]297#endif
[15]298 states_mutex->GetMutex();
299 self->CalcModel();
[8]300
[15]301 output->GetMutex();
302 output->SetValueNoMutex(0, 0, self->state[0].Quat.q0);
303 output->SetValueNoMutex(1, 0, self->state[0].Quat.q1);
304 output->SetValueNoMutex(2, 0, self->state[0].Quat.q2);
305 output->SetValueNoMutex(3, 0, self->state[0].Quat.q3);
306 output->SetValueNoMutex(4, 0, self->state[0].Pos.x);
307 output->SetValueNoMutex(5, 0, self->state[0].Pos.y);
308 output->SetValueNoMutex(6, 0, self->state[0].Pos.z);
309 output->SetValueNoMutex(7, 0, self->state[0].W.x);
310 output->SetValueNoMutex(8, 0, self->state[0].W.y);
311 output->SetValueNoMutex(9, 0, self->state[0].W.z);
312 output->SetValueNoMutex(10, 0, self->state[0].Vel.x);
313 output->SetValueNoMutex(11, 0, self->state[0].Vel.y);
314 output->SetValueNoMutex(12, 0, self->state[0].Vel.z);
315 output->ReleaseMutex();
316 output->SetDataTime(GetTime());
[8]317
[15]318 self->state.Update();
[8]319
[15]320 if (pos_init->ValueChanged() || yaw_init->ValueChanged()) {
321 self->state[-1].Quat = ComputeInitRotation(Quaternion(1, 0, 0, 0));
322 self->state[-2].Quat = ComputeInitRotation(Quaternion(1, 0, 0, 0));
323 self->state[-1].Pos = pos_init->Value();
324 self->state[-2].Pos = self->state[-1].Pos;
[8]325#ifdef GL
[15]326 position_init = false;
[8]327#endif
[15]328 }
[8]329
[15]330 states_mutex->ReleaseMutex();
[8]331
[15]332 self->ProcessUpdate(output);
333 }
[8]334
[15]335 WarnUponSwitches(false);
[8]336}
Note: See TracBrowser for help on using the repository browser.