PageRenderTime 127ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/src/ui/ApmToolBar.cc

https://gitlab.com/fsgdez/apm_planner
C++ | 441 lines | 338 code | 57 blank | 46 comment | 33 complexity | 72a207d50a6790408a620881459e4a49 MD5 | raw file
  1. /*===================================================================
  2. APM_PLANNER Open Source Ground Control Station
  3. (c) 2013 APM_PLANNER PROJECT <http://www.diydrones.com>
  4. This file is part of the APM_PLANNER project
  5. APM_PLANNER is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. APM_PLANNER is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with APM_PLANNER. If not, see <http://www.gnu.org/licenses/>.
  15. ======================================================================*/
  16. /**
  17. * @file
  18. * @brief APM Tool Bar
  19. *
  20. * @author Bill Bonney <billbonney@communistech.com>
  21. *
  22. */
  23. #include "ApmToolBar.h"
  24. #include "QsLog.h"
  25. #include "LinkManager.h"
  26. #include "MainWindow.h"
  27. #include "ArduPilotMegaMAV.h"
  28. #include <QQmlContext>
  29. #include <QGraphicsObject>
  30. #include <QTimer>
  31. #include <QQuickItem>
  32. #include <QQmlEngine>
  33. APMToolBar::APMToolBar(QWindow *parent):
  34. QQuickView(parent), m_uas(NULL), m_disableOverride(false)
  35. {
  36. // Configure our QML object
  37. QLOG_DEBUG() << "qmlBaseDir" << QGC::shareDirectory();
  38. QUrl url = QUrl::fromLocalFile(QGC::shareDirectory() + "/qml/ApmToolBar.qml");
  39. QLOG_DEBUG() << url;
  40. if (!QFile::exists(QGC::shareDirectory() + "/qml/ApmToolBar.qml"))
  41. {
  42. QMessageBox::information(0,"Error", "" + QGC::shareDirectory() + "/qml/ApmToolBar.qml" + " not found. Please reinstall the application and try again");
  43. exit(-1);
  44. }
  45. engine()->addImportPath("qml/"); //For local or win32 builds
  46. engine()->addImportPath(QGC::shareDirectory() +"/qml"); //For installed linux builds
  47. setSource(url);
  48. QLOG_DEBUG() << "QML Status:" << status();
  49. setResizeMode(QQuickView::SizeRootObjectToView);
  50. this->rootContext()->setContextProperty("globalObj", this);
  51. // set the size of the device box and row spacing for icons
  52. #ifdef Q_OS_MAC
  53. rootObject()->setProperty("rowSpacerSize", QVariant(3));
  54. rootObject()->setProperty("linkDeviceSize", QVariant(105));
  55. #elif defined(Q_OS_UNIX)
  56. rootObject()->setProperty("rowSpacerSize", QVariant(3));
  57. rootObject()->setProperty("linkDeviceSize", QVariant(100));
  58. #else
  59. rootObject()->setProperty("rowSpacerSize", QVariant(3));
  60. rootObject()->setProperty("linkDeviceSize", QVariant(80));
  61. #endif
  62. connect(UASManager::instance(),SIGNAL(activeUASSet(UASInterface*)),this,SLOT(activeUasSet(UASInterface*)));
  63. connect(LinkManager::instance(),SIGNAL(newLink(int)),
  64. this,SLOT(newLinkCreated(int)));
  65. for (int i=0;i<LinkManager::instance()->getLinks().size();i++)
  66. {
  67. newLinkCreated(LinkManager::instance()->getLinks().at(i));
  68. }
  69. connect(&m_heartbeatTimer, SIGNAL(timeout()), this, SLOT(stopHeartbeat()));
  70. QSettings settings;
  71. settings.beginGroup("QGC_MAINWINDOW");
  72. if (settings.contains("ADVANCED_MODE"))
  73. {
  74. QMetaObject::invokeMethod(rootObject(),"setAdvancedMode", Q_ARG(QVariant, settings.value("ADVANCED_MODE").toBool()));
  75. }
  76. connect(LinkManager::instance(),SIGNAL(linkChanged(int)),this,SLOT(updateLinkDisplay(int)));
  77. }
  78. void APMToolBar::checkAdvancedMode(bool checked)
  79. {
  80. QMetaObject::invokeMethod(rootObject(),"setAdvancedMode", Q_ARG(QVariant, checked));
  81. }
  82. void APMToolBar::activeUasSet(UASInterface *uas)
  83. {
  84. QLOG_DEBUG() << "APMToolBar::ActiveUASSet " << uas;
  85. if (!uas)
  86. {
  87. return;
  88. }
  89. if (m_uas)
  90. {
  91. disconnect(m_uas,SIGNAL(armingChanged(bool)),
  92. this,SLOT(armingChanged(bool)));
  93. disconnect(m_uas,SIGNAL(armingChanged(int, QString)),
  94. this,SLOT(armingChanged(int, QString)));
  95. disconnect(m_uas, SIGNAL(navModeChanged(int,int,QString)),
  96. this, SLOT(navModeChanged(int,int,QString)));
  97. disconnect(m_uas, SIGNAL(heartbeat(UASInterface*)),
  98. this, SLOT(heartbeat(UASInterface*)));
  99. disconnect(m_uas,SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)),
  100. this,SLOT(parameterChanged(int,int,int,int,QString,QVariant)));
  101. }
  102. QLOG_DEBUG() << "APMToolBar::ActiveUASSet " << uas;
  103. // [TODO} Add active MAV to diplay here
  104. m_uas = uas;
  105. connect(m_uas,SIGNAL(armingChanged(bool)),
  106. this,SLOT(armingChanged(bool)));
  107. connect(m_uas,SIGNAL(armingChanged(int, QString)),
  108. this,SLOT(armingChanged(int, QString)));
  109. connect(m_uas, SIGNAL(navModeChanged(int,int,QString)),
  110. this, SLOT(navModeChanged(int,int,QString)));
  111. connect(m_uas, SIGNAL(heartbeat(UASInterface*)),
  112. this, SLOT(heartbeat(UASInterface*)));
  113. connect(m_uas,SIGNAL(parameterChanged(int,int,int,int,QString,QVariant)),
  114. this,SLOT(parameterChanged(int,int,int,int,QString,QVariant)));
  115. if (m_uas->isFixedWing()||m_uas->isGroundRover()) {
  116. rootObject()->setProperty("enableStatusDisplay", QVariant(false));
  117. } else {
  118. rootObject()->setProperty("enableStatusDisplay", QVariant(true));
  119. rootObject()->setProperty("armed", QVariant(m_uas->isArmed()));
  120. }
  121. rootObject()->setProperty("uasNameLabel",m_uas->getUASName());
  122. // Connect the signals from active links
  123. // disconnect signals from the active serial links
  124. QList<int> linkidlist = uas->getLinkIdList();
  125. bool currentlinkfound = false;
  126. for (int i=0;i<linkidlist.size();i++)
  127. {
  128. if (m_currentLinkId == linkidlist.at(i))
  129. {
  130. currentlinkfound = true;
  131. }
  132. }
  133. if (!currentlinkfound)
  134. {
  135. //We did not find the current link in the list of connected links.
  136. //Change the current link to match the first connected link in this UAS
  137. for (int i=0;i<linkidlist.size();i++)
  138. {
  139. if (LinkManager::instance()->getLinkConnected(linkidlist.at(i)))
  140. {
  141. //This link is connected
  142. if (LinkManager::instance()->getLinkType(linkidlist.at(i)) == LinkInterface::SERIAL_LINK)
  143. {
  144. //We only want to attach the toolbar to a serial link.
  145. m_currentLinkId = linkidlist.at(i);
  146. updateLinkDisplay(m_currentLinkId);
  147. break;
  148. }
  149. }
  150. }
  151. }
  152. }
  153. void APMToolBar::armingChanged(bool armed)
  154. {
  155. this->rootObject()->setProperty("armed",armed);
  156. }
  157. void APMToolBar::armingChanged(int sysId, QString armingState)
  158. {
  159. QLOG_DEBUG() << "APMToolBar: sysid " << sysId << " armState" << armingState;
  160. }
  161. void APMToolBar::setFlightViewAction(QAction *action)
  162. {
  163. connect(this, SIGNAL(triggerFlightView()), action, SIGNAL(triggered()));
  164. }
  165. void APMToolBar::setFlightPlanViewAction(QAction *action)
  166. {
  167. connect(this, SIGNAL(triggerFlightPlanView()), action, SIGNAL(triggered()));
  168. }
  169. void APMToolBar::setInitialSetupViewAction(QAction *action)
  170. {
  171. connect(this, SIGNAL(triggerInitialSetupView()), action, SIGNAL(triggered()));
  172. }
  173. void APMToolBar::setConfigTuningViewAction(QAction *action)
  174. {
  175. connect(this, SIGNAL(triggerConfigTuningView()), action, SIGNAL(triggered()));
  176. }
  177. void APMToolBar::setPlotViewAction(QAction *action)
  178. {
  179. connect(this, SIGNAL(triggerPlotView()), action, SIGNAL(triggered()));
  180. }
  181. void APMToolBar::setSimulationViewAction(QAction *action)
  182. {
  183. connect(this, SIGNAL(triggerSimulationView()), action, SIGNAL(triggered()));
  184. }
  185. void APMToolBar::setConnectMAVAction(QAction *action)
  186. {
  187. connect(this, SIGNAL(connectMAV()), action, SIGNAL(triggered()));
  188. }
  189. void APMToolBar::selectFlightView()
  190. {
  191. QLOG_DEBUG() << "APMToolBar: SelectFlightView";
  192. emit triggerFlightView();
  193. }
  194. void APMToolBar::selectFlightPlanView()
  195. {
  196. QLOG_DEBUG() << "APMToolBar: SelectFlightPlanView";
  197. emit triggerFlightPlanView();
  198. }
  199. void APMToolBar::selectInitialSetupView()
  200. {
  201. QLOG_DEBUG() << "APMToolBar: selectInitialSetupView";
  202. emit triggerInitialSetupView();
  203. }
  204. void APMToolBar::selectConfigTuningView()
  205. {
  206. QLOG_DEBUG() << "APMToolBar: selectConfigTuningView";
  207. emit triggerConfigTuningView();
  208. }
  209. void APMToolBar::selectSimulationView()
  210. {
  211. QLOG_DEBUG() << "APMToolBar: selectSimulationView";
  212. }
  213. void APMToolBar::selectPlotView()
  214. {
  215. QLOG_DEBUG() << "APMToolBar: selectPlotView";
  216. }
  217. void APMToolBar::connectMAV()
  218. {
  219. QLOG_DEBUG() << "APMToolBar: connectMAV " << m_uas << "with sLink" << m_currentLinkId;
  220. if (LinkManager::instance()->getLinkConnected(m_currentLinkId))
  221. {
  222. LinkManager::instance()->disconnectLink(m_currentLinkId);
  223. }
  224. else
  225. {
  226. LinkManager::instance()->connectLink(m_currentLinkId);
  227. }
  228. }
  229. void APMToolBar::setConnection(bool connection)
  230. {
  231. QLOG_DEBUG() << "APMToolBar setConnection:" << connection;
  232. // Change the image to represent the state
  233. QObject *object = rootObject();
  234. object->setProperty("connected", connection);
  235. if ((m_uas)&&(connection==true)) {
  236. QLOG_DEBUG() << "APMToolBar: CustomMode" << m_uas->getCustomMode();
  237. setModeText(m_uas->getCustomModeText());
  238. } else {
  239. // disconnected
  240. rootObject()->setProperty("modeText", "mode");
  241. }
  242. }
  243. APMToolBar::~APMToolBar()
  244. {
  245. QLOG_DEBUG() << "Destory APM Toolbar";
  246. }
  247. void APMToolBar::showConnectionDialog()
  248. {
  249. // Displays a UI where the user can select a MAV Link.
  250. QLOG_DEBUG() << "APMToolBar: showConnectionDialog for current serial link " << m_currentLinkId;
  251. MainWindow::instance()->configLink(m_currentLinkId);
  252. }
  253. void APMToolBar::updateLinkDisplay(int linkid)
  254. {
  255. if (m_currentLinkId != linkid)
  256. {
  257. //We only care about our current link
  258. QLOG_TRACE() << "APMToolBar::updateLinkDisplay called with non current link. Current:" << m_currentLinkId << "called:" << linkid;
  259. return;
  260. }
  261. QString port = LinkManager::instance()->getSerialLinkPort(linkid);
  262. int baud = LinkManager::instance()->getSerialLinkBaud(linkid);
  263. bool connected = LinkManager::instance()->getLinkConnected(linkid);
  264. QObject *object = rootObject();
  265. if (!object)
  266. {
  267. QLOG_FATAL() << "APMToolBar::updateLinkDisplay, null QML root object. FIXME";
  268. return;
  269. }
  270. object->setProperty("baudrateLabel", QString::number(baud));
  271. object->setProperty("linkNameLabel", port);
  272. setConnection(connected);
  273. QLOG_DEBUG() << "APMToolBar: updateLinkDisplay" << port << baud << connected;
  274. }
  275. void APMToolBar::newLinkCreated(int linkid)
  276. {
  277. if (LinkManager::instance()->getLinkType(linkid) == LinkInterface::SERIAL_LINK)
  278. {
  279. //We want to use this one.
  280. QLOG_DEBUG() << "APMToolBar: new Serial Link Created" << linkid;
  281. m_currentLinkId = linkid;
  282. updateLinkDisplay(m_currentLinkId);
  283. }
  284. }
  285. void APMToolBar::setModeText(const QString &text)
  286. {
  287. QObject *object = rootObject();
  288. object->setProperty("modeText", text.toUpper());
  289. // [ToDo] ptentially factor the code below into the APMToolBar
  290. int customMode = m_uas->getCustomMode();
  291. bool inRTL;
  292. switch (m_uas->getSystemType()){
  293. case MAV_TYPE_FIXED_WING:
  294. inRTL = (customMode == ApmPlane::RTL);
  295. break;
  296. case MAV_TYPE_QUADROTOR:
  297. case MAV_TYPE_HEXAROTOR:
  298. case MAV_TYPE_OCTOROTOR:
  299. case MAV_TYPE_TRICOPTER:
  300. case MAV_TYPE_HELICOPTER:
  301. inRTL = (customMode == ApmCopter::RTL);
  302. break;
  303. case MAV_TYPE_GROUND_ROVER:
  304. inRTL = (customMode == ApmRover::RTL);
  305. break;
  306. default:
  307. inRTL = false;
  308. }
  309. if (inRTL) {
  310. object->setProperty("modeTextColor", QColor("red"));
  311. object->setProperty("modeBkgColor", QColor(0x88, 0x00, 0x00, 0x80));
  312. object->setProperty("modeBorderColor", QColor("red"));
  313. } else {
  314. object->setProperty("modeTextColor", QColor("white"));
  315. object->setProperty("modeBkgColor", QColor(0x00, 0x88, 0x00, 0x80));
  316. object->setProperty("modeBorderColor", QColor("white"));
  317. }
  318. }
  319. void APMToolBar::navModeChanged(int uasid, int mode, const QString &text)
  320. {
  321. QLOG_DEBUG() << "APMToolBar::mode:" << text;
  322. Q_UNUSED(uasid);
  323. Q_UNUSED(mode);
  324. setModeText(text);
  325. }
  326. void APMToolBar::heartbeat(UASInterface* uas)
  327. {
  328. QLOG_TRACE() << "APMToolBar::Heartbeat " << uas;
  329. if (uas != m_uas)
  330. return; // Only deal with the Active UAS
  331. QObject *object = rootObject();
  332. object->setProperty("heartbeat",QVariant(true));
  333. // Start a timer to turn the heartbeat animation off
  334. // if the timer is started again, the call is not made
  335. m_heartbeatTimer.setSingleShot(true);
  336. m_heartbeatTimer.start(1500);
  337. }
  338. void APMToolBar::stopHeartbeat()
  339. {
  340. QLOG_TRACE() << "APMToolBar::stopHeartBeatDisplay";
  341. QObject *object = rootObject();
  342. object->setProperty("heartbeat",QVariant(false));
  343. m_heartbeatTimer.stop();
  344. }
  345. void APMToolBar::startAnimation()
  346. {
  347. rootObject()->setProperty("stopAnimation",QVariant(false));
  348. }
  349. void APMToolBar::stopAnimation()
  350. {
  351. rootObject()->setProperty("stopAnimation",QVariant(true));
  352. }
  353. void APMToolBar::overrideDisableConnectWidget(bool disable)
  354. {
  355. m_disableOverride = disable;
  356. }
  357. void APMToolBar::disableConnectWidget(bool disable)
  358. {
  359. if (!m_disableOverride)
  360. {
  361. rootObject()->setProperty("disableConnectWidget",QVariant(disable));
  362. }
  363. }
  364. void APMToolBar::parameterChanged(int uas, int component, int parameterCount,
  365. int parameterId, QString parameterName, QVariant value)
  366. {
  367. Q_UNUSED(uas);
  368. Q_UNUSED(component);
  369. Q_UNUSED(parameterCount);
  370. Q_UNUSED(parameterId);
  371. if (parameterName.contains("ARMING_REQUIRE")){
  372. // Shows Display of ARM status, if enabled
  373. int arming_required = value.toBool();
  374. rootObject()->setProperty("armed", QVariant(m_uas->isArmed()));
  375. rootObject()->setProperty("enableStatusDisplay",
  376. QVariant(arming_required));
  377. }
  378. }