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

Last change on this file since 167 was 167, checked in by Sanahuja Guillaume, 5 years ago

modifs pour template vectors

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