dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
modeluavoproxy.cpp
Go to the documentation of this file.
1 
12 /*
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful, but
19  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  * for more details.
22  *
23  * You should have received a copy of the GNU General Public License along
24  * with this program; if not, see <http://www.gnu.org/licenses/>
25  */
26 
27 #include <QDebug>
28 #include <QEventLoop>
29 #include <QTimer>
30 #include "modeluavoproxy.h"
32 #include <math.h>
33 
35 #include "homelocation.h"
36 
39  : QObject(parent)
40  , myModel(model)
41 {
42  ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
43  Q_ASSERT(pm != NULL);
44  objManager = pm->getObject<UAVObjectManager>();
45  Q_ASSERT(objManager != NULL);
46  waypointObj = Waypoint::GetInstance(objManager);
47  Q_ASSERT(waypointObj != NULL);
48 }
49 
56 {
57  Waypoint *wp = Waypoint::GetInstance(objManager, 0);
58  Q_ASSERT(wp);
59  if (wp == NULL)
60  return false;
61 
62  // Make sure the object is acked
63  UAVObject::Metadata initialMeta = wp->getMetadata();
64  UAVObject::Metadata meta = initialMeta;
66  wp->setMetadata(meta);
67 
68  double homeLLA[3];
69  double NED[3];
70  double LLA[3];
71  getHomeLocation(homeLLA);
72  bool newInstance;
73 
74  // Get the number of existing waypoints
75  int instances = Waypoint::getNumInstances(objManager);
76  int x;
77 
78  // Figure out the total amount of work to do.
79  int progressMax = myModel->rowCount();
80 
81  if (instances > progressMax) {
82  progressMax = instances;
83  }
84 
85  for (x = 0; x < myModel->rowCount(); x++) {
86  newInstance = false;
87  Waypoint *wp = NULL; // Shadows above wp
88 
89  // Create new instances of waypoints if this is more than exist
90  if (x >= instances) {
91  newInstance = true;
92  wp = new Waypoint;
93  wp->initialize(x, wp->getMetaObject());
94  objManager->registerObject(wp);
95  } else {
96  wp = Waypoint::GetInstance(objManager, x);
97  }
98 
99  Q_ASSERT(wp);
100  Waypoint::DataFields waypoint = wp->getData();
101 
102  // Convert from LLA to NED for sending to the model
103  LLA[0] = myModel->data(myModel->index(x, FlightDataModel::LATPOSITION)).toDouble();
104  LLA[1] = myModel->data(myModel->index(x, FlightDataModel::LNGPOSITION)).toDouble();
105  LLA[2] = myModel->data(myModel->index(x, FlightDataModel::ALTITUDE)).toDouble();
106  Utils::CoordinateConversions().LLA2NED_HomeLLA(LLA, homeLLA, NED);
107 
108  // Fetch the data from the internal model
109  waypoint.Velocity = myModel->data(myModel->index(x, FlightDataModel::VELOCITY)).toFloat();
110  waypoint.Position[Waypoint::POSITION_NORTH] = NED[0];
111  waypoint.Position[Waypoint::POSITION_EAST] = NED[1];
112  waypoint.Position[Waypoint::POSITION_DOWN] = NED[2];
113  waypoint.Mode =
114  myModel->data(myModel->index(x, FlightDataModel::MODE), Qt::UserRole).toInt();
115  waypoint.ModeParameters =
116  myModel->data(myModel->index(x, FlightDataModel::MODE_PARAMS)).toFloat();
117 
118  if (robustUpdate(waypoint, x)) {
119  qDebug() << "Successfully updated";
120  emit sendPathPlanToUavProgress(100 * (x + 1) / progressMax);
121  } else {
122  qDebug() << "Upload failed";
123  emit sendPathPlanToUavProgress(100 * (x + 1) / progressMax);
124  return false;
125  }
126  if (newInstance) {
127  QEventLoop m_eventloop;
128  QTimer::singleShot(800, &m_eventloop, &QEventLoop::quit);
129  m_eventloop.exec();
130  }
131  }
132 
133  /* Continue iterating over any instance indices that aren't needed to
134  * represent our model, and mark them invalid. */
135  for (; x < instances; x++) {
136  Waypoint *wp = Waypoint::GetInstance(objManager, x);
137  // shadows wp above
138 
139  Waypoint::DataFields waypoint = wp->getData();
140 
141  waypoint.Mode = Waypoint::MODE_INVALID;
142  if (robustUpdate(waypoint, x)) {
143  qDebug() << "Successfully updated";
144  emit sendPathPlanToUavProgress(100 * (x + 1) / progressMax);
145  } else {
146  qDebug() << "Upload failed";
147  emit sendPathPlanToUavProgress(100 * (x + 1) / progressMax);
148  return false;
149  }
150  }
151 
152  wp->setMetadata(initialMeta);
153  return true;
154 }
155 
162 bool ModelUavoProxy::robustUpdate(Waypoint::DataFields data, int instance)
163 {
164  Waypoint *wp = Waypoint::GetInstance(objManager, instance);
165  connect(wp, QOverload<UAVObject *, bool>::of(&Waypoint::transactionCompleted), this,
167 
168  for (int i = 0; i < 10; i++) {
169  QEventLoop m_eventloop;
170  QTimer::singleShot(1000, &m_eventloop, &QEventLoop::quit);
171  connect(this, &ModelUavoProxy::waypointTransactionSucceeded, &m_eventloop,
172  &QEventLoop::quit);
173  connect(this, &ModelUavoProxy::waypointTransactionFailed, &m_eventloop, &QEventLoop::quit);
174  waypointTransactionResult.insert(instance, false);
175  wp->setData(data);
176  wp->updated();
177  m_eventloop.exec();
178  if (waypointTransactionResult.value(instance)) {
179  disconnect(wp, QOverload<UAVObject *, bool>::of(&Waypoint::transactionCompleted), this,
181  return true;
182  }
183 
184  // Wait a second for next attempt
185  QTimer::singleShot(500, &m_eventloop, &QEventLoop::quit);
186  m_eventloop.exec();
187  }
188 
189  disconnect(wp, QOverload<UAVObject *, bool>::of(&Waypoint::transactionCompleted), this,
191 
192  // None of the attempt got an ack
193  return false;
194 }
195 
201 {
202  Q_ASSERT(obj->getObjID() == Waypoint::OBJID);
203  waypointTransactionResult.insert(obj->getInstID(), success);
204  if (success) {
205  qDebug() << "Success " << obj->getInstID();
207  } else {
208  qDebug() << "Failed transaction " << obj->getInstID();
210  }
211 }
212 
218 {
219  double homeLLA[3];
220  getHomeLocation(homeLLA);
221  double LLA[3];
222 
223  myModel->pauseValidation(true);
224 
225  myModel->removeRows(0, myModel->rowCount());
226  for (int x = 0; x < Waypoint::getNumInstances(objManager); ++x) {
227  Waypoint *wp;
228  Waypoint::DataFields wpfields;
229 
230  wp = Waypoint::GetInstance(objManager, x);
231  Q_ASSERT(wp);
232 
233  if (!wp)
234  continue;
235 
236  // Get the waypoint data from the object manager and prepare a row in the internal model
237  wpfields = wp->getData();
238 
239  if (wpfields.Mode == Waypoint::MODE_INVALID)
240  break;
241 
242  myModel->insertRow(x);
243 
244  // Compute the coordinates in LLA
245  double NED[3] = { wpfields.Position[Waypoint::POSITION_NORTH],
246  wpfields.Position[Waypoint::POSITION_EAST],
247  wpfields.Position[Waypoint::POSITION_DOWN] };
248  Utils::CoordinateConversions().NED2LLA_HomeLLA(homeLLA, NED, LLA);
249 
250  // Store the data
251  myModel->setData(myModel->index(x, FlightDataModel::LATPOSITION), LLA[0]);
252  myModel->setData(myModel->index(x, FlightDataModel::LNGPOSITION), LLA[1]);
253  myModel->setData(myModel->index(x, FlightDataModel::ALTITUDE), LLA[2]);
254  myModel->setData(myModel->index(x, FlightDataModel::VELOCITY), wpfields.Velocity);
255  myModel->setData(myModel->index(x, FlightDataModel::MODE), wpfields.Mode);
256  myModel->setData(myModel->index(x, FlightDataModel::MODE_PARAMS), wpfields.ModeParameters);
257  }
258 
259  myModel->pauseValidation(false);
260 }
261 
268 bool ModelUavoProxy::getHomeLocation(double *homeLLA)
269 {
270  // Compute the coordinates in LLA
271  HomeLocation *home = HomeLocation::GetInstance(objManager);
272  if (home == NULL)
273  return false;
274 
275  HomeLocation::DataFields homeLocation = home->getData();
276  homeLLA[0] = homeLocation.Latitude / 1e7;
277  homeLLA[1] = homeLocation.Longitude / 1e7;
278  homeLLA[2] = homeLocation.Altitude;
279 
280  return true;
281 }
static void SetFlightTelemetryAcked(Metadata &meta, quint8 val)
Definition: uavobject.cpp:427
void waypointTransactionSucceeded()
bool registerObject(UAVDataObject *obj)
Core plugin system that manages the plugins, their life cycle and their registered objects...
Definition: pluginmanager.h:53
axis equal end function NED
Definition: OPPlots.m:63
void LLA2NED_HomeLLA(double LLA[3], double homeLLA[3], double NED[3])
void sendPathPlanToUavProgress(int percent)
for i
Definition: OPPlots.m:140
int rowCount(const QModelIndex &parent=QModelIndex()) const
Return the number of waypoints.
quint32 getInstID()
Definition: uavobject.cpp:115
DataFields data
bool modelToObjects()
Cast from the internal representation to the UAVOs.
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex())
FlightDataModel::removeRows Remove waypoints from the model.
int NED2LLA_HomeLLA(double homeLLA[3], double NED[3], double LLA[3])
quint32 getObjID()
Definition: uavobject.cpp:107
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
FlightDataModel::setData Set the data at a given location.
ModelUavoProxy(QObject *parent, FlightDataModel *model)
Initialize the model uavo proxy.
void pauseValidation(bool pausing)
Prevent validation/correction of data.
LLA
Definition: OPPlots.m:34
void waypointTransactionFailed()
x
Definition: OPPlots.m:100
void objectsToModel()
Cast from the UAVOs to the internal representation.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
FlightDataModel::data Fetch the data from the model.
void waypointTransactionCompleted(UAVObject *, bool)
Whenever a waypoint transaction is completed.