// %flair:license{ // This file is part of the Flair framework distributed under the // CECILL-C License, Version 1.0. // %flair:license} // created: 2013/04/03 // filename: VrpnObject.cpp // // author: César Richard, Guillaume Sanahuja // Copyright Heudiasyc UMR UTC/CNRS 7253 // // version: $Id: $ // // purpose: objet vrpn // // /*********************************************************************/ #include "VrpnObject_impl.h" #include "VrpnObject.h" #include "VrpnClient.h" #include "VrpnClient_impl.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using std::string; using namespace flair::core; using namespace flair::gui; using namespace flair::sensor; VrpnObject_impl::VrpnObject_impl(VrpnObject *self, string name, int id, const TabWidget *tab) { parent = GetVrpnClient(); this->self = self; if(parent==NULL) { self->Err("VrpnClient must be instanced before creating VrpnObject\n"); return; } if (id == -1 && parent->UseXbee()) { self->Err("erreur aucun identifiant specifie pour la connexion Xbee\n"); } if (id != -1 && !parent->UseXbee()) { self->Warn( "identifiant pour la connexion Xbee ignore car pas en mode Xbee\n"); } // state cvmatrix_descriptor *desc = new cvmatrix_descriptor(7, 1); desc->SetElementName(0, 0, "q0"); desc->SetElementName(1, 0, "q1"); desc->SetElementName(2, 0, "q2"); desc->SetElementName(3, 0, "q3"); desc->SetElementName(4, 0, "x"); desc->SetElementName(5, 0, "y"); desc->SetElementName(6, 0, "z"); output = new Matrix(self, desc, floatType); delete desc; desc = new cvmatrix_descriptor(3, 1); desc->SetElementName(0, 0, "roll"); desc->SetElementName(1, 0, "pitch"); desc->SetElementName(2, 0, "yaw"); state = new Matrix(self, desc, floatType); delete desc; // ui plot_tab = new Tab(tab, "Mesures " + name); x_plot = new DataPlot1D(plot_tab->NewRow(), "x", -10, 10); x_plot->AddCurve(output->Element(4)); y_plot = new DataPlot1D(plot_tab->LastRowLastCol(), "y", -10, 10); y_plot->AddCurve(output->Element(5)); z_plot = new DataPlot1D(plot_tab->LastRowLastCol(), "z", -2, 0); z_plot->AddCurve(output->Element(6)); if (parent->UseXbee()) { tracker = NULL; parent->pimpl_->AddTrackable(this, id); } else { tracker = new vrpn_Tracker_Remote(name.c_str(), parent->pimpl_->connection); tracker->register_change_handler(this, handle_pos); tracker->shutup = true; parent->pimpl_->AddTrackable(this); } } VrpnObject_impl::~VrpnObject_impl(void) { parent->pimpl_->RemoveTrackable(this); if (tracker != NULL) {// normal tracker->unregister_change_handler(this, handle_pos); delete tracker; } delete plot_tab; } bool VrpnObject_impl::IsTracked(unsigned int timeout_ms) { output->GetMutex(); Time a = GetTime(); Time dt = a - output->DataTime(); output->ReleaseMutex(); if (dt > (Time)(timeout_ms * 1000000)) { // self->Printf("%lld %lld %lld // %lld\n",a,output->DataTime(),dt,(Time)(timeout_ms*1000000)); return false; } else { return true; } } void VrpnObject_impl::GetQuaternion(Quaternion &quaternion) { output->GetMutex(); quaternion.q0 = output->ValueNoMutex(0, 0); quaternion.q1 = output->ValueNoMutex(1, 0); quaternion.q2 = output->ValueNoMutex(2, 0); quaternion.q3 = output->ValueNoMutex(3, 0); output->ReleaseMutex(); } void VrpnObject_impl::GetPosition(Vector3Df &point) { output->GetMutex(); point.x = output->ValueNoMutex(4, 0); point.y = output->ValueNoMutex(5, 0); point.z = output->ValueNoMutex(6, 0); output->ReleaseMutex(); } void VRPN_CALLBACK VrpnObject_impl::handle_pos(void *userdata, const vrpn_TRACKERCB t) { bool is_nan = false; VrpnObject_impl *caller = reinterpret_cast(userdata); Time time = GetTime(); // check if something is nan for (int i = 0; i < 3; i++) { if (isnan(t.pos[i]) == true) is_nan = true; } for (int i = 0; i < 4; i++) { if (isnan(t.quat[i]) == true) is_nan = true; } if (is_nan == true) { caller->self->Warn("data is nan, skipping it (time %lld)\n", time); return; } // on prend une fois pour toute le mutex et on fait des accès directs caller->output->GetMutex(); // warning: t.quat is defined as (qx,qy,qz,qw), which is different from // flair::core::Quaternion Quaternion quaternion(t.quat[3],t.quat[0],t.quat[1],t.quat[2]); Vector3Df pos((float)t.pos[0], (float)t.pos[1], (float)t.pos[2]); // on effectue les rotation caller->parent->pimpl_->ComputeRotations(pos); caller->parent->pimpl_->ComputeRotations(quaternion); caller->output->SetValueNoMutex(0, 0, quaternion.q0); caller->output->SetValueNoMutex(1, 0, quaternion.q1); caller->output->SetValueNoMutex(2, 0, quaternion.q2); caller->output->SetValueNoMutex(3, 0, quaternion.q3); caller->output->SetValueNoMutex(4, 0, pos.x); caller->output->SetValueNoMutex(5, 0, pos.y); caller->output->SetValueNoMutex(6, 0, pos.z); caller->output->SetDataTime(time); caller->output->ReleaseMutex(); Euler euler=quaternion.ToEuler(); caller->state->GetMutex(); caller->state->SetValueNoMutex(0, 0, Euler::ToDegree(euler.roll)); caller->state->SetValueNoMutex(1, 0, Euler::ToDegree(euler.pitch)); caller->state->SetValueNoMutex(2, 0, Euler::ToDegree(euler.yaw)); caller->state->ReleaseMutex(); caller->self->ProcessUpdate(caller->output); }