source: flair-src/trunk/lib/FlairSensorActuator/src/VrpnObject_impl.cpp @ 122

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

modifs uav vrpn i686

File size: 5.9 KB
Line 
1// %flair:license{
2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
4// %flair:license}
5//  created:    2013/04/03
6//  filename:   VrpnObject.cpp
7//
8//  author:     César Richard, Guillaume Sanahuja
9//              Copyright Heudiasyc UMR UTC/CNRS 7253
10//
11//  version:    $Id: $
12//
13//  purpose:    objet vrpn
14//
15//
16/*********************************************************************/
17#include "VrpnObject_impl.h"
18#include "VrpnObject.h"
19#include "VrpnClient.h"
20#include "VrpnClient_impl.h"
21#include <vrpn_Tracker.h>
22#include <fcntl.h>
23#include <errno.h>
24#include <string.h>
25#include <unistd.h>
26#include <vrpn_Connection.h>
27#include <cvmatrix.h>
28#include <Tab.h>
29#include <TabWidget.h>
30#include <DataPlot1D.h>
31#include <OneAxisRotation.h>
32#include <Vector3D.h>
33#include <Euler.h>
34#include <math.h>
35
36using std::string;
37using namespace flair::core;
38using namespace flair::gui;
39using namespace flair::sensor;
40
41VrpnObject_impl::VrpnObject_impl(VrpnObject *self,
42                                 string name, int id, const TabWidget *tab) {
43  parent = GetVrpnClient();
44  this->self = self;
45
46        if(parent==NULL) {
47                self->Err("VrpnClient must be instanced before creating VrpnObject\n");
48                return;
49        }
50  if (id == -1 && parent->UseXbee()) {
51    self->Err("erreur aucun identifiant specifie pour la connexion Xbee\n");
52  }
53  if (id != -1 && !parent->UseXbee()) {
54    self->Warn(
55        "identifiant pour la connexion Xbee ignore car pas en mode Xbee\n");
56  }
57
58  if (parent->UseXbee()) {
59    parent->pimpl_->AddTrackable(this, id);
60    tracker = NULL;
61  } else {
62    parent->pimpl_->AddTrackable(self);
63    tracker = new vrpn_Tracker_Remote(name.c_str(), parent->pimpl_->connection);
64    tracker->register_change_handler(this, handle_pos);
65    tracker->shutup = true;
66  }
67
68  // state
69  cvmatrix_descriptor *desc = new cvmatrix_descriptor(6, 1);
70  desc->SetElementName(0, 0, "roll");
71  desc->SetElementName(1, 0, "pitch");
72  desc->SetElementName(2, 0, "yaw");
73  desc->SetElementName(3, 0, "x");
74  desc->SetElementName(4, 0, "y");
75  desc->SetElementName(5, 0, "z");
76  output = new cvmatrix(self, desc, floatType);
77
78  desc = new cvmatrix_descriptor(3, 1);
79  desc->SetElementName(0, 0, "roll");
80  desc->SetElementName(1, 0, "pitch");
81  desc->SetElementName(2, 0, "yaw");
82  state = new cvmatrix(self, desc, floatType);
83
84  // ui
85  plot_tab = new Tab(tab, "Mesures " + name);
86  x_plot = new DataPlot1D(plot_tab->NewRow(), "x", -10, 10);
87  x_plot->AddCurve(output->Element(3));
88  y_plot = new DataPlot1D(plot_tab->LastRowLastCol(), "y", -10, 10);
89  y_plot->AddCurve(output->Element(4));
90  z_plot = new DataPlot1D(plot_tab->LastRowLastCol(), "z", -2, 0);
91  z_plot->AddCurve(output->Element(5));
92}
93
94VrpnObject_impl::~VrpnObject_impl(void) {
95  if (tracker != NULL) // normal
96  {
97    parent->pimpl_->RemoveTrackable(self);
98    tracker->unregister_change_handler(this, handle_pos);
99    delete tracker;
100  } else // xbee
101  {
102    parent->pimpl_->RemoveTrackable(this);
103  }
104  delete plot_tab;
105}
106
107void VrpnObject_impl::mainloop(void) { tracker->mainloop(); }
108
109bool VrpnObject_impl::IsTracked(unsigned int timeout_ms) {
110  output->GetMutex();
111  Time a = GetTime();
112  Time dt = a - output->DataTime();
113  output->ReleaseMutex();
114
115  if (dt > (Time)(timeout_ms * 1000000)) {
116    // self->Printf("%lld %lld %lld
117    // %lld\n",a,output->DataTime(),dt,(Time)(timeout_ms*1000000));
118    return false;
119  } else {
120    return true;
121  }
122}
123
124void VrpnObject_impl::GetEuler(Euler &euler) {
125  output->GetMutex();
126  euler.roll = output->ValueNoMutex(0, 0);
127  euler.pitch = output->ValueNoMutex(1, 0);
128  euler.yaw = output->ValueNoMutex(2, 0);
129  output->ReleaseMutex();
130}
131
132void VrpnObject_impl::GetQuaternion(Quaternion &quaternion) {
133  output->GetMutex();
134  quaternion.q0 = this->quaternion.q0;
135  quaternion.q1 = this->quaternion.q1;
136  quaternion.q2 = this->quaternion.q2;
137  quaternion.q3 = this->quaternion.q3;
138  output->ReleaseMutex();
139}
140
141void VrpnObject_impl::GetPosition(Vector3D &point) {
142  output->GetMutex();
143  point.x = output->ValueNoMutex(3, 0);
144  point.y = output->ValueNoMutex(4, 0);
145  point.z = output->ValueNoMutex(5, 0);
146  output->ReleaseMutex();
147}
148
149void VRPN_CALLBACK
150VrpnObject_impl::handle_pos(void *userdata, const vrpn_TRACKERCB t) {
151  bool is_nan = false;
152  VrpnObject_impl *caller = reinterpret_cast<VrpnObject_impl *>(userdata);
153  Time time = GetTime();
154
155  // check if something is nan
156  for (int i = 0; i < 3; i++) {
157    if (isnan(t.pos[i]) == true)
158      is_nan = true;
159  }
160  for (int i = 0; i < 4; i++) {
161    if (isnan(t.quat[i]) == true)
162      is_nan = true;
163  }
164  if (is_nan == true) {
165    caller->self->Warn("data is nan, skipping it (time %lld)\n", time);
166    return;
167  }
168
169  // on prend une fois pour toute le mutex et on fait des accès directs
170  caller->output->GetMutex();
171
172  // warning: t.quat is defined as (qx,qy,qz,qw), which is different from
173  // flair::core::Quaternion
174  caller->quaternion.q0 = t.quat[3];
175  caller->quaternion.q1 = t.quat[0];
176  caller->quaternion.q2 = t.quat[1];
177  caller->quaternion.q3 = t.quat[2];
178  Vector3D pos((float)t.pos[0], (float)t.pos[1], (float)t.pos[2]);
179
180  // on effectue les rotation
181  caller->parent->pimpl_->ComputeRotations(pos);
182  caller->parent->pimpl_->ComputeRotations(caller->quaternion);
183
184  Euler euler;
185  caller->quaternion.ToEuler(euler);
186  caller->output->SetValueNoMutex(0, 0, euler.roll);
187  caller->output->SetValueNoMutex(1, 0, euler.pitch);
188  caller->output->SetValueNoMutex(2, 0, euler.yaw);
189  caller->output->SetValueNoMutex(3, 0, pos.x);
190  caller->output->SetValueNoMutex(4, 0, pos.y);
191  caller->output->SetValueNoMutex(5, 0, pos.z);
192
193  caller->output->SetDataTime(time);
194  caller->output->ReleaseMutex();
195
196  caller->state->GetMutex();
197  caller->state->SetValueNoMutex(0, 0, Euler::ToDegree(euler.roll));
198  caller->state->SetValueNoMutex(1, 0, Euler::ToDegree(euler.pitch));
199  caller->state->SetValueNoMutex(2, 0, Euler::ToDegree(euler.yaw));
200  caller->state->ReleaseMutex();
201
202  caller->self->ProcessUpdate(caller->output);
203}
Note: See TracBrowser for help on using the repository browser.