// created: 2019/01/09 // filename: App.cpp // // author: Guillaume Sanahuja // Copyright Heudiasyc UMR UTC/CNRS 7253 // // version: $Id: $ // // purpose: mixed reality demo, virtual uav side // // /*********************************************************************/ #include "App.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace flair::core; using namespace flair::gui; using namespace flair::sensor; using namespace flair::filter; using namespace flair::meta; App::App(TargetController *controller): UavStateMachine(controller), behaviourMode(BehaviourMode_t::Default), vrpnLost(false) { Uav* uav=GetUav(); VrpnClient* vrpnclient=new VrpnClient("vrpn", "127.0.0.1:3884",80);//local ip, and specific port for simulator_simu's vrpn uavVrpn = new MetaVrpnObject(uav->ObjectName()); getFrameworkManager()->AddDeviceToLog(uavVrpn); uav->GetAhrs()->YawPlot()->AddCurve(uavVrpn->State()->Element(2),DataPlot::Green); positionHold=new PushButton(GetButtonsLayout()->LastRowLastCol(),"position hold"); vrpnclient->Start(); uX=new Pid(setupLawTab->At(1,0),"u_x"); uX->UseDefaultPlot(graphLawTab->NewRow()); uY=new Pid(setupLawTab->At(1,1),"u_y"); uY->UseDefaultPlot(graphLawTab->LastRowLastCol()); customReferenceOrientation= new AhrsData(this,"reference"); uav->GetAhrs()->AddPlot(customReferenceOrientation,DataPlot::Yellow); AddDataToControlLawLog(customReferenceOrientation); customOrientation=new AhrsData(this,"orientation"); } App::~App() { } const AhrsData *App::GetOrientation(void) const { //get yaw from vrpn Quaternion vrpnQuaternion; uavVrpn->GetQuaternion(vrpnQuaternion); //get roll, pitch and w from imu Quaternion ahrsQuaternion; Vector3Df ahrsAngularSpeed; GetDefaultOrientation()->GetQuaternionAndAngularRates(ahrsQuaternion, ahrsAngularSpeed); Euler ahrsEuler=ahrsQuaternion.ToEuler(); ahrsEuler.yaw=vrpnQuaternion.ToEuler().yaw; Quaternion mixQuaternion=ahrsEuler.ToQuaternion(); customOrientation->SetQuaternionAndAngularRates(mixQuaternion,ahrsAngularSpeed); return customOrientation; } void App::AltitudeValues(float &z,float &dz) const{ Vector3Df uav_pos,uav_vel; uavVrpn->GetPosition(uav_pos); uavVrpn->GetSpeed(uav_vel); //z and dz must be in uav's frame z=-uav_pos.z; dz=-uav_vel.z; } AhrsData *App::GetReferenceOrientation(void) { Vector2Df pos_err, vel_err; // in Uav coordinate system float yaw_ref; Euler refAngles; PositionValues(pos_err, vel_err, yaw_ref); refAngles.yaw=yaw_ref; uX->SetValues(pos_err.x, vel_err.x); uX->Update(GetTime()); refAngles.pitch=uX->Output(); uY->SetValues(pos_err.y, vel_err.y); uY->Update(GetTime()); refAngles.roll=-uY->Output(); customReferenceOrientation->SetQuaternionAndAngularRates(refAngles.ToQuaternion(),Vector3Df(0,0,0)); return customReferenceOrientation; } void App::PositionValues(Vector2Df &pos_error,Vector2Df &vel_error,float &yaw_ref) { Vector3Df uav_pos,uav_vel; // in VRPN coordinate system Vector2Df uav_2Dpos,uav_2Dvel; // in VRPN coordinate system uavVrpn->GetPosition(uav_pos); uavVrpn->GetSpeed(uav_vel); uav_pos.To2Dxy(uav_2Dpos); uav_vel.To2Dxy(uav_2Dvel); pos_error=uav_2Dpos-posHold; vel_error=uav_2Dvel; yaw_ref=yawHold; //error in uav frame Quaternion currentQuaternion=GetCurrentQuaternion(); Euler currentAngles;//in vrpn frame currentQuaternion.ToEuler(currentAngles); pos_error.Rotate(-currentAngles.yaw); vel_error.Rotate(-currentAngles.yaw); } void App::SignalEvent(Event_t event) { UavStateMachine::SignalEvent(event); switch(event) { case Event_t::TakingOff: behaviourMode=BehaviourMode_t::Default; vrpnLost=false; break; case Event_t::EnteringControlLoop: break; case Event_t::EnteringFailSafeMode: behaviourMode=BehaviourMode_t::Default; break; } } void App::ExtraSecurityCheck(void) { if ((!vrpnLost) && (behaviourMode==BehaviourMode_t::PositionHold)) { if (!uavVrpn->IsTracked(500)) { Thread::Err("VRPN, uav lost\n"); vrpnLost=true; EnterFailSafeMode(); Land(); } } } void App::ExtraCheckPushButton(void) { if(positionHold->Clicked() && (behaviourMode==BehaviourMode_t::Default)) { VrpnPositionHold(); } } void App::ExtraCheckJoystick(void) { //R1 and Square if(GetTargetController()->IsButtonPressed(9) && GetTargetController()->IsButtonPressed(2) && (behaviourMode==BehaviourMode_t::Default)) { VrpnPositionHold(); } } void App::VrpnPositionHold(void) { Quaternion vrpnQuaternion; uavVrpn->GetQuaternion(vrpnQuaternion); yawHold=vrpnQuaternion.ToEuler().yaw; Vector3Df vrpnPosition; uavVrpn->GetPosition(vrpnPosition); vrpnPosition.To2Dxy(posHold); uX->Reset(); uY->Reset(); behaviourMode=BehaviourMode_t::PositionHold; SetOrientationMode(OrientationMode_t::Custom); Thread::Info("App: holding position\n"); }