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

Last change on this file since 218 was 218, checked in by Sanahuja Guillaume, 6 years ago

reduce delay between server and client for simulated vrpn

File size: 5.7 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 <Matrix.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 // state
59 cvmatrix_descriptor *desc = new cvmatrix_descriptor(7, 1);
60 desc->SetElementName(0, 0, "q0");
61 desc->SetElementName(1, 0, "q1");
62 desc->SetElementName(2, 0, "q2");
63 desc->SetElementName(3, 0, "q3");
64 desc->SetElementName(4, 0, "x");
65 desc->SetElementName(5, 0, "y");
66 desc->SetElementName(6, 0, "z");
67 output = new Matrix(self, desc, floatType);
68 delete desc;
69
70 desc = new cvmatrix_descriptor(3, 1);
71 desc->SetElementName(0, 0, "roll");
72 desc->SetElementName(1, 0, "pitch");
73 desc->SetElementName(2, 0, "yaw");
74 state = new Matrix(self, desc, floatType);
75 delete desc;
76
77 // ui
78 plot_tab = new Tab(tab, "Mesures " + name);
79 x_plot = new DataPlot1D(plot_tab->NewRow(), "x", -10, 10);
80 x_plot->AddCurve(output->Element(4));
81 y_plot = new DataPlot1D(plot_tab->LastRowLastCol(), "y", -10, 10);
82 y_plot->AddCurve(output->Element(5));
83 z_plot = new DataPlot1D(plot_tab->LastRowLastCol(), "z", -2, 0);
84 z_plot->AddCurve(output->Element(6));
85
86 if (parent->UseXbee()) {
87 tracker = NULL;
88 parent->pimpl_->AddTrackable(this, id);
89 } else {
90 tracker = new vrpn_Tracker_Remote(name.c_str(), parent->pimpl_->connection);
91 tracker->register_change_handler(this, handle_pos);
92 tracker->shutup = true;
93 parent->pimpl_->AddTrackable(this);
94 }
95
96}
97
98VrpnObject_impl::~VrpnObject_impl(void) {
99 parent->pimpl_->RemoveTrackable(this);
100 if (tracker != NULL) {// normal
101 tracker->unregister_change_handler(this, handle_pos);
102 delete tracker;
103 }
104 delete plot_tab;
105}
106
107bool VrpnObject_impl::IsTracked(unsigned int timeout_ms) {
108 output->GetMutex();
109 Time a = GetTime();
110 Time dt = a - output->DataTime();
111 output->ReleaseMutex();
112
113 if (dt > (Time)(timeout_ms * 1000000)) {
114 // self->Printf("%lld %lld %lld
115 // %lld\n",a,output->DataTime(),dt,(Time)(timeout_ms*1000000));
116 return false;
117 } else {
118 return true;
119 }
120}
121
122void VrpnObject_impl::GetQuaternion(Quaternion &quaternion) {
123 output->GetMutex();
124 quaternion.q0 = output->ValueNoMutex(0, 0);
125 quaternion.q1 = output->ValueNoMutex(1, 0);
126 quaternion.q2 = output->ValueNoMutex(2, 0);
127 quaternion.q3 = output->ValueNoMutex(3, 0);
128 output->ReleaseMutex();
129}
130
131void VrpnObject_impl::GetPosition(Vector3Df &point) {
132 output->GetMutex();
133 point.x = output->ValueNoMutex(4, 0);
134 point.y = output->ValueNoMutex(5, 0);
135 point.z = output->ValueNoMutex(6, 0);
136 output->ReleaseMutex();
137}
138
139void VRPN_CALLBACK
140VrpnObject_impl::handle_pos(void *userdata, const vrpn_TRACKERCB t) {
141 bool is_nan = false;
142 VrpnObject_impl *caller = reinterpret_cast<VrpnObject_impl *>(userdata);
143 Time time = GetTime();
144 //Printf("%s %lld %lld\n",caller->self->ObjectName().c_str(),time,t.msg_time.tv_sec*1000000+t.msg_time.tv_usec);
145
146 // check if something is nan
147 for (int i = 0; i < 3; i++) {
148 if (isnan(t.pos[i]) == true)
149 is_nan = true;
150 }
151 for (int i = 0; i < 4; i++) {
152 if (isnan(t.quat[i]) == true)
153 is_nan = true;
154 }
155 if (is_nan == true) {
156 caller->self->Warn("data is nan, skipping it (time %lld)\n", time);
157 return;
158 }
159
160 // on prend une fois pour toute le mutex et on fait des accès directs
161 caller->output->GetMutex();
162
163 // warning: t.quat is defined as (qx,qy,qz,qw), which is different from
164 // flair::core::Quaternion
165 Quaternion quaternion(t.quat[3],t.quat[0],t.quat[1],t.quat[2]);
166 Vector3Df pos((float)t.pos[0], (float)t.pos[1], (float)t.pos[2]);
167
168 // on effectue les rotation
169 caller->parent->pimpl_->ComputeRotations(pos);
170 caller->parent->pimpl_->ComputeRotations(quaternion);
171
172 caller->output->SetValueNoMutex(0, 0, quaternion.q0);
173 caller->output->SetValueNoMutex(1, 0, quaternion.q1);
174 caller->output->SetValueNoMutex(2, 0, quaternion.q2);
175 caller->output->SetValueNoMutex(3, 0, quaternion.q3);
176 caller->output->SetValueNoMutex(4, 0, pos.x);
177 caller->output->SetValueNoMutex(5, 0, pos.y);
178 caller->output->SetValueNoMutex(6, 0, pos.z);
179
180 caller->output->SetDataTime(time);
181 caller->output->ReleaseMutex();
182
183 Euler euler=quaternion.ToEuler();
184 caller->state->GetMutex();
185 caller->state->SetValueNoMutex(0, 0, Euler::ToDegree(euler.roll));
186 caller->state->SetValueNoMutex(1, 0, Euler::ToDegree(euler.pitch));
187 caller->state->SetValueNoMutex(2, 0, Euler::ToDegree(euler.yaw));
188 caller->state->ReleaseMutex();
189
190 caller->self->ProcessUpdate(caller->output);
191}
Note: See TracBrowser for help on using the repository browser.