value();
- channel->setValue(newSwashLvlConfiguration.Min[i],newSwashLvlConfiguration.ServoChannels[i]);
- }
- obj->updated();
- break;
- case 4: //levelling verification
- break;
- case 5: //levelling complete
- break;
- default:
- break;
+
+ actuatorCommandData.Channel[newSwashLvlConfiguration.ServoChannels[i]] = value;
}
+
+
+ actuatorCommand->setData(actuatorCommandData);
+ actuatorCommand->updated();
+
return;
}
-
-
-void ConfigccpmWidget::FocusChanged(QWidget *oldFocus, QWidget *newFocus)
-{
- if (SwashLvlConfigurationInProgress!=1) return;
- QMessageBox msgBox;
- int ret;
- msgBox.setText("Warning!!!
");
-
- if ((this->isAncestorOf(oldFocus))&&(!this->isAncestorOf(newFocus)))
- {
- msgBox.setInformativeText("You are in the middle of the levelling routine
Changing focus will cancel all levelling and return the OP hardware to the state it was in before levelling began.Do you want to continue the levelling routine?");
- msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- msgBox.setDefaultButton(QMessageBox::Yes);
- msgBox.setIcon(QMessageBox::Information);
- ret = msgBox.exec();
-
- if (ret == QMessageBox::Yes)
- {
-
- //m_ccpm->TabObject->setCurrentIndex(1);
- //m_ccpm->SwashPlateLevel->setFocus(Qt::MouseFocusReason);
- //m_ccpm->SwashLvlInstructionsBox->setFocus(Qt::MouseFocusReason);
- oldFocus->setFocus(Qt::MouseFocusReason);
- }
- if (ret == QMessageBox::No)
- {
- SwashLvlCancelButtonPressed();
- }
- }
-}
diff --git a/ground/openpilotgcs/src/plugins/config/configccpmwidget.h b/ground/openpilotgcs/src/plugins/config/configccpmwidget.h
index d07da53c8..c6bc1b27b 100644
--- a/ground/openpilotgcs/src/plugins/config/configccpmwidget.h
+++ b/ground/openpilotgcs/src/plugins/config/configccpmwidget.h
@@ -57,7 +57,6 @@ typedef struct {
uint ccpmCollectivePassthroughState:1;
uint ccpmLinkCyclicState:1;
uint ccpmLinkRollState:1;
- uint CollectiveChannel:3;//20bits
uint SliderValue0:7;
uint SliderValue1:7;
uint SliderValue2:7;//41bits
@@ -82,6 +81,8 @@ public:
ConfigccpmWidget(QWidget *parent = 0);
~ConfigccpmWidget();
+ friend class ConfigAirframeWidget;
+
private:
Ui_ccpmWidget *m_ccpm;
QGraphicsSvgItem *SwashplateImg;
@@ -134,8 +135,8 @@ private:
void SwashLvlCancelButtonPressed();
void SwashLvlFinishButtonPressed();
- void UpdatCCPMOptionsFromUI();
- void UpdatCCPMUIFromOptions();
+ void UpdateCCPMOptionsFromUI();
+ void UpdateCCPMUIFromOptions();
void SetUIComponentVisibilities();
void ccpmChannelCheck();
@@ -143,8 +144,6 @@ private:
void enableSwashplateLevellingControl(bool state);
void setSwashplateLevel(int percent);
void SwashLvlSpinBoxChanged(int value);
- void FocusChanged(QWidget *oldFocus, QWidget *newFocus);
-
virtual void refreshValues() {}; // Not used
public slots:
diff --git a/ground/openpilotgcs/src/plugins/config/configgadget.qrc b/ground/openpilotgcs/src/plugins/config/configgadget.qrc
index 5f982053b..f24cb68b8 100644
--- a/ground/openpilotgcs/src/plugins/config/configgadget.qrc
+++ b/ground/openpilotgcs/src/plugins/config/configgadget.qrc
@@ -15,5 +15,7 @@
images/coptercontrol.svg
images/hw_config.png
images/gyroscope.png
+ images/TX.svg
+ images/camera.png
diff --git a/ground/openpilotgcs/src/plugins/config/configgadgetwidget.cpp b/ground/openpilotgcs/src/plugins/config/configgadgetwidget.cpp
index 39acb5adf..d40db122f 100644
--- a/ground/openpilotgcs/src/plugins/config/configgadgetwidget.cpp
+++ b/ground/openpilotgcs/src/plugins/config/configgadgetwidget.cpp
@@ -33,6 +33,7 @@
#include "configinputwidget.h"
#include "configoutputwidget.h"
#include "configstabilizationwidget.h"
+#include "configcamerastabilizationwidget.h"
#include "config_pro_hw_widget.h"
#include "config_cc_hw_widget.h"
#include "defaultattitudewidget.h"
@@ -81,6 +82,8 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
qwd = new ConfigStabilizationWidget(this);
ftw->insertTab(ConfigGadgetWidget::stabilization, qwd, QIcon(":/configgadget/images/gyroscope.png"), QString("Stabilization"));
+ qwd = new ConfigCameraStabilizationWidget(this);
+ ftw->insertTab(ConfigGadgetWidget::camerastabilization, qwd, QIcon(":/configgadget/images/camera.png"), QString("Camera Stab"));
// qwd = new ConfigPipXtremeWidget(this);
@@ -99,6 +102,8 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
onAutopilotConnect();
help = 0;
+ connect(ftw,SIGNAL(currentAboutToShow(int,bool*)),this,SLOT(tabAboutToChange(int,bool*)));//,Qt::BlockingQueuedConnection);
+
}
ConfigGadgetWidget::~ConfigGadgetWidget()
@@ -115,11 +120,21 @@ void ConfigGadgetWidget::resizeEvent(QResizeEvent *event)
}
void ConfigGadgetWidget::onAutopilotDisconnect() {
+ ftw->setCurrentIndex(ConfigGadgetWidget::hardware);
+ ftw->removeTab(ConfigGadgetWidget::ins);
+ QWidget *qwd = new DefaultAttitudeWidget(this);
+ ftw->insertTab(ConfigGadgetWidget::ins, qwd, QIcon(":/configgadget/images/AHRS-v1.3.png"), QString("INS"));
+ ftw->removeTab(ConfigGadgetWidget::hardware);
+ qwd = new DefaultHwSettingsWidget(this);
+ ftw->insertTab(ConfigGadgetWidget::hardware, qwd, QIcon(":/configgadget/images/hw_config.png"), QString("HW Settings"));
+ ftw->setCurrentIndex(ConfigGadgetWidget::hardware);
+
emit autopilotDisconnected();
}
void ConfigGadgetWidget::onAutopilotConnect() {
+ qDebug()<<"ConfigGadgetWidget onAutopilotConnect";
// First of all, check what Board type we are talking to, and
// if necessary, remove/add tabs in the config gadget:
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
@@ -153,5 +168,24 @@ void ConfigGadgetWidget::onAutopilotConnect() {
emit autopilotConnected();
}
+void ConfigGadgetWidget::tabAboutToChange(int i,bool * proceed)
+{
+ Q_UNUSED(i);
+ *proceed=true;
+ ConfigTaskWidget * wid=qobject_cast(ftw->currentWidget());
+ if(!wid)
+ return;
+ if(wid->isDirty())
+ {
+ int ans=QMessageBox::warning(this,tr("Unsaved changes"),tr("The tab you are leaving has unsaved changes,"
+ "if you proceed they will be lost."
+ "Do you still want to proceed?"),QMessageBox::Yes,QMessageBox::No);
+ if(ans==QMessageBox::No)
+ *proceed=false;
+ else
+ wid->setDirty(false);
+ }
+}
+
diff --git a/ground/openpilotgcs/src/plugins/config/configgadgetwidget.h b/ground/openpilotgcs/src/plugins/config/configgadgetwidget.h
index df2f553a3..633253507 100644
--- a/ground/openpilotgcs/src/plugins/config/configgadgetwidget.h
+++ b/ground/openpilotgcs/src/plugins/config/configgadgetwidget.h
@@ -37,10 +37,10 @@
//#include
#include
#include "utils/pathutils.h"
-
+#include
//#include "fancytabwidget.h"
#include "utils/mytabbedstackwidget.h"
-
+#include "configtaskwidget.h"
class ConfigGadgetWidget: public QWidget
{
@@ -50,11 +50,12 @@ class ConfigGadgetWidget: public QWidget
public:
ConfigGadgetWidget(QWidget *parent = 0);
~ConfigGadgetWidget();
- enum widgetTabs {hardware=0, aircraft, input, output, ins, stabilization};
+ enum widgetTabs {hardware=0, aircraft, input, output, ins, stabilization, camerastabilization};
public slots:
void onAutopilotConnect();
void onAutopilotDisconnect();
+ void tabAboutToChange(int i,bool *);
signals:
void autopilotConnected();
diff --git a/ground/openpilotgcs/src/plugins/config/configinputwidget.cpp b/ground/openpilotgcs/src/plugins/config/configinputwidget.cpp
index 83e1a02ac..128f9885b 100644
--- a/ground/openpilotgcs/src/plugins/config/configinputwidget.cpp
+++ b/ground/openpilotgcs/src/plugins/config/configinputwidget.cpp
@@ -1,8 +1,8 @@
/**
******************************************************************************
*
- * @file configservowidget.cpp
- * @author E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
+ * @file configinputwidget.cpp
+ * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@@ -38,614 +38,233 @@
#include
#include
#include
+#include
+#include
-#include "manualcontrolsettings.h"
+#define ACCESS_MIN_MOVE -6
+#define ACCESS_MAX_MOVE 6
+#define STICK_MIN_MOVE -8
+#define STICK_MAX_MOVE 8
-ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent)
+ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent),wizardStep(wizardNone),loop(NULL),skipflag(false),transmitterType(heli)
{
+ manualCommandObj = ManualControlCommand::GetInstance(getObjectManager());
+ manualSettingsObj = ManualControlSettings::GetInstance(getObjectManager());
+ receiverActivityObj=ReceiverActivity::GetInstance(getObjectManager());
m_config = new Ui_InputWidget();
m_config->setupUi(this);
- ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
- UAVObjectManager *objManager = pm->getObject();
+ setupButtons(m_config->saveRCInputToRAM,m_config->saveRCInputToSD);
- // First of all, put all the channel widgets into lists, so that we can
- // manipulate those:
-
-
- inMaxLabels << m_config->ch0Max
- << m_config->ch1Max
- << m_config->ch2Max
- << m_config->ch3Max
- << m_config->ch4Max
- << m_config->ch5Max
- << m_config->ch6Max
- << m_config->ch7Max;
-
- inMinLabels << m_config->ch0Min
- << m_config->ch1Min
- << m_config->ch2Min
- << m_config->ch3Min
- << m_config->ch4Min
- << m_config->ch5Min
- << m_config->ch6Min
- << m_config->ch7Min;
-
- inSliders << m_config->inSlider0
- << m_config->inSlider1
- << m_config->inSlider2
- << m_config->inSlider3
- << m_config->inSlider4
- << m_config->inSlider5
- << m_config->inSlider6
- << m_config->inSlider7;
-
- inRevCheckboxes << m_config->ch0Rev
- << m_config->ch1Rev
- << m_config->ch2Rev
- << m_config->ch3Rev
- << m_config->ch4Rev
- << m_config->ch5Rev
- << m_config->ch6Rev
- << m_config->ch7Rev;
-
- inChannelAssign << m_config->ch0Assign
- << m_config->ch1Assign
- << m_config->ch2Assign
- << m_config->ch3Assign
- << m_config->ch4Assign
- << m_config->ch5Assign
- << m_config->ch6Assign
- << m_config->ch7Assign;
-
- // Now connect the widget to the ManualControlCommand / Channel UAVObject
- UAVDataObject* obj = dynamic_cast(objManager->getObject(QString("ManualControlCommand")));
- connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateChannels(UAVObject*)));
-
- // Register for ManualControlSettings changes:
- obj = dynamic_cast(objManager->getObject(QString("ManualControlSettings")));
- connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
-
-
- // Get the receiver types supported by OpenPilot and fill the corresponding
- // dropdown menu:
- obj = dynamic_cast(objManager->getObject(QString("ManualControlSettings")));
- UAVObjectField * field;
- // Fill in the dropdown menus for the channel RC Input assignement.
- QStringList channelsList;
- channelsList << "None";
- QList fieldList = obj->getFields();
- foreach (UAVObjectField* field, fieldList) {
- if (field->getUnits().contains("channel")) {
- channelsList.append(field->getName());
- }
+ unsigned int index=0;
+ foreach(QString name,manualSettingsObj->getFields().at(0)->getElementNames())
+ {
+ Q_ASSERT(index < ManualControlSettings::CHANNELGROUPS_NUMELEM);
+ inputChannelForm * inp=new inputChannelForm(this,index==0);
+ m_config->channelSettings->layout()->addWidget(inp);
+ inp->ui->channelName->setText(name);
+ addUAVObjectToWidgetRelation("ManualControlSettings","ChannelGroups",inp->ui->channelGroup,index);
+ addUAVObjectToWidgetRelation("ManualControlSettings","ChannelNumber",inp->ui->channelNumber,index);
+ addUAVObjectToWidgetRelation("ManualControlSettings","ChannelMin",inp->ui->channelMin,index);
+ addUAVObjectToWidgetRelation("ManualControlSettings","ChannelNeutral",inp->ui->channelNeutral,index);
+ addUAVObjectToWidgetRelation("ManualControlSettings","ChannelMax",inp->ui->channelMax,index);
+ ++index;
}
- m_config->ch0Assign->addItems(channelsList);
- m_config->ch1Assign->addItems(channelsList);
- m_config->ch2Assign->addItems(channelsList);
- m_config->ch3Assign->addItems(channelsList);
- m_config->ch4Assign->addItems(channelsList);
- m_config->ch5Assign->addItems(channelsList);
- m_config->ch6Assign->addItems(channelsList);
- m_config->ch7Assign->addItems(channelsList);
+ connect(m_config->configurationWizard,SIGNAL(clicked()),this,SLOT(goToWizard()));
+ connect(m_config->runCalibration,SIGNAL(toggled(bool)),this, SLOT(simpleCalibration(bool)));
- // And the flight mode settings:
- field = obj->getField(QString("FlightModePosition"));
- m_config->fmsModePos1->addItems(field->getOptions());
- m_config->fmsModePos2->addItems(field->getOptions());
- m_config->fmsModePos3->addItems(field->getOptions());
- field = obj->getField(QString("Stabilization1Settings"));
- channelsList.clear();
- channelsList.append(field->getOptions());
- m_config->fmsSsPos1Roll->addItems(channelsList);
- m_config->fmsSsPos1Pitch->addItems(channelsList);
- m_config->fmsSsPos1Yaw->addItems(channelsList);
- m_config->fmsSsPos2Roll->addItems(channelsList);
- m_config->fmsSsPos2Pitch->addItems(channelsList);
- m_config->fmsSsPos2Yaw->addItems(channelsList);
- m_config->fmsSsPos3Roll->addItems(channelsList);
- m_config->fmsSsPos3Pitch->addItems(channelsList);
- m_config->fmsSsPos3Yaw->addItems(channelsList);
+ connect(m_config->wzNext,SIGNAL(clicked()),this,SLOT(wzNext()));
+ connect(m_config->wzCancel,SIGNAL(clicked()),this,SLOT(wzCancel()));
+ connect(m_config->wzBack,SIGNAL(clicked()),this,SLOT(wzBack()));
- // And the Armin configurations:
- field = obj->getField(QString("Arming"));
- m_config->armControl->clear();
- m_config->armControl->addItems(field->getOptions());
+ m_config->stackedWidget->setCurrentIndex(0);
+ addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos1,0);
+ addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos2,1);
+ addUAVObjectToWidgetRelation("ManualControlSettings","FlightModePosition",m_config->fmsModePos3,2);
+ addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization1Settings",m_config->fmsSsPos1Roll,"Roll");
+ addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization2Settings",m_config->fmsSsPos2Roll,"Roll");
+ addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization3Settings",m_config->fmsSsPos3Roll,"Roll");
+ addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization1Settings",m_config->fmsSsPos1Pitch,"Pitch");
+ addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization2Settings",m_config->fmsSsPos2Pitch,"Pitch");
+ addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization3Settings",m_config->fmsSsPos3Pitch,"Pitch");
+ addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization1Settings",m_config->fmsSsPos1Yaw,"Yaw");
+ addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization2Settings",m_config->fmsSsPos2Yaw,"Yaw");
+ addUAVObjectToWidgetRelation("ManualControlSettings","Stabilization3Settings",m_config->fmsSsPos3Yaw,"Yaw");
- connect(m_config->saveRCInputToSD, SIGNAL(clicked()), this, SLOT(saveRCInputObject()));
- connect(m_config->saveRCInputToRAM, SIGNAL(clicked()), this, SLOT(sendRCInputUpdate()));
-
+ addUAVObjectToWidgetRelation("ManualControlSettings","Arming",m_config->armControl);
+ addUAVObjectToWidgetRelation("ManualControlSettings","ArmedTimeout",m_config->armTimeout,0,1000);
+ connect( ManualControlCommand::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(moveFMSlider()));
enableControls(false);
- refreshValues();
- connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
- connect(parent, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()));
-
- connect(m_config->ch0Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool)));
- connect(m_config->ch1Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool)));
- connect(m_config->ch2Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool)));
- connect(m_config->ch3Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool)));
- connect(m_config->ch4Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool)));
- connect(m_config->ch5Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool)));
- connect(m_config->ch6Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool)));
- connect(m_config->ch7Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool)));
- connect(m_config->doRCInputCalibration,SIGNAL(stateChanged(int)),this,SLOT(updateTips(int)));
- firstUpdate = true;
+ populateWidgets();
+ refreshWidgetsValues();
// Connect the help button
connect(m_config->inputHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
- updateTips(Qt::Unchecked);
+ m_config->graphicsView->setScene(new QGraphicsScene(this));
+ m_config->graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
+ m_renderer = new QSvgRenderer();
+ QGraphicsScene *l_scene = m_config->graphicsView->scene();
+ m_config->graphicsView->setBackgroundBrush(QBrush(Utils::StyleHelper::baseColor()));
+ if (QFile::exists(":/configgadget/images/TX.svg") && m_renderer->load(QString(":/configgadget/images/TX.svg")) && m_renderer->isValid())
+ {
+ l_scene->clear(); // Deletes all items contained in the scene as well.
+
+ m_txBackground = new QGraphicsSvgItem();
+ // All other items will be clipped to the shape of the background
+ m_txBackground->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
+ QGraphicsItem::ItemClipsToShape);
+ m_txBackground->setSharedRenderer(m_renderer);
+ m_txBackground->setElementId("background");
+ l_scene->addItem(m_txBackground);
+
+ m_txMainBody = new QGraphicsSvgItem();
+ m_txMainBody->setParentItem(m_txBackground);
+ m_txMainBody->setSharedRenderer(m_renderer);
+ m_txMainBody->setElementId("body");
+ l_scene->addItem(m_txMainBody);
+
+ m_txLeftStick = new QGraphicsSvgItem();
+ m_txLeftStick->setParentItem(m_txBackground);
+ m_txLeftStick->setSharedRenderer(m_renderer);
+ m_txLeftStick->setElementId("ljoy");
+
+ m_txRightStick = new QGraphicsSvgItem();
+ m_txRightStick->setParentItem(m_txBackground);
+ m_txRightStick->setSharedRenderer(m_renderer);
+ m_txRightStick->setElementId("rjoy");
+
+ m_txAccess0 = new QGraphicsSvgItem();
+ m_txAccess0->setParentItem(m_txBackground);
+ m_txAccess0->setSharedRenderer(m_renderer);
+ m_txAccess0->setElementId("access0");
+
+ m_txAccess1 = new QGraphicsSvgItem();
+ m_txAccess1->setParentItem(m_txBackground);
+ m_txAccess1->setSharedRenderer(m_renderer);
+ m_txAccess1->setElementId("access1");
+
+ m_txAccess2 = new QGraphicsSvgItem();
+ m_txAccess2->setParentItem(m_txBackground);
+ m_txAccess2->setSharedRenderer(m_renderer);
+ m_txAccess2->setElementId("access2");
+
+ m_txFlightMode = new QGraphicsSvgItem();
+ m_txFlightMode->setParentItem(m_txBackground);
+ m_txFlightMode->setSharedRenderer(m_renderer);
+ m_txFlightMode->setElementId("flightModeCenter");
+ m_txFlightMode->setZValue(-10);
+
+ m_txArrows = new QGraphicsSvgItem();
+ m_txArrows->setParentItem(m_txBackground);
+ m_txArrows->setSharedRenderer(m_renderer);
+ m_txArrows->setElementId("arrows");
+ m_txArrows->setVisible(false);
+
+ QRectF orig=m_renderer->boundsOnElement("ljoy");
+ QMatrix Matrix = m_renderer->matrixForElement("ljoy");
+ orig=Matrix.mapRect(orig);
+ m_txLeftStickOrig.translate(orig.x(),orig.y());
+ m_txLeftStick->setTransform(m_txLeftStickOrig,false);
+
+ orig=m_renderer->boundsOnElement("arrows");
+ Matrix = m_renderer->matrixForElement("arrows");
+ orig=Matrix.mapRect(orig);
+ m_txArrowsOrig.translate(orig.x(),orig.y());
+ m_txArrows->setTransform(m_txArrowsOrig,false);
+
+ orig=m_renderer->boundsOnElement("body");
+ Matrix = m_renderer->matrixForElement("body");
+ orig=Matrix.mapRect(orig);
+ m_txMainBodyOrig.translate(orig.x(),orig.y());
+ m_txMainBody->setTransform(m_txMainBodyOrig,false);
+
+ orig=m_renderer->boundsOnElement("flightModeCenter");
+ Matrix = m_renderer->matrixForElement("flightModeCenter");
+ orig=Matrix.mapRect(orig);
+ m_txFlightModeCOrig.translate(orig.x(),orig.y());
+ m_txFlightMode->setTransform(m_txFlightModeCOrig,false);
+
+ orig=m_renderer->boundsOnElement("flightModeLeft");
+ Matrix = m_renderer->matrixForElement("flightModeLeft");
+ orig=Matrix.mapRect(orig);
+ m_txFlightModeLOrig.translate(orig.x(),orig.y());
+ orig=m_renderer->boundsOnElement("flightModeRight");
+ Matrix = m_renderer->matrixForElement("flightModeRight");
+ orig=Matrix.mapRect(orig);
+ m_txFlightModeROrig.translate(orig.x(),orig.y());
+
+ orig=m_renderer->boundsOnElement("rjoy");
+ Matrix = m_renderer->matrixForElement("rjoy");
+ orig=Matrix.mapRect(orig);
+ m_txRightStickOrig.translate(orig.x(),orig.y());
+ m_txRightStick->setTransform(m_txRightStickOrig,false);
+
+ orig=m_renderer->boundsOnElement("access0");
+ Matrix = m_renderer->matrixForElement("access0");
+ orig=Matrix.mapRect(orig);
+ m_txAccess0Orig.translate(orig.x(),orig.y());
+ m_txAccess0->setTransform(m_txAccess0Orig,false);
+
+ orig=m_renderer->boundsOnElement("access1");
+ Matrix = m_renderer->matrixForElement("access1");
+ orig=Matrix.mapRect(orig);
+ m_txAccess1Orig.translate(orig.x(),orig.y());
+ m_txAccess1->setTransform(m_txAccess1Orig,false);
+
+ orig=m_renderer->boundsOnElement("access2");
+ Matrix = m_renderer->matrixForElement("access2");
+ orig=Matrix.mapRect(orig);
+ m_txAccess2Orig.translate(orig.x(),orig.y());
+ m_txAccess2->setTransform(m_txAccess2Orig,true);
+ }
+ m_config->graphicsView->fitInView(m_txMainBody, Qt::KeepAspectRatio );
+ animate=new QTimer(this);
+ connect(animate,SIGNAL(timeout()),this,SLOT(moveTxControls()));
+
+ heliChannelOrder << ManualControlSettings::CHANNELGROUPS_COLLECTIVE <<
+ ManualControlSettings::CHANNELGROUPS_THROTTLE <<
+ ManualControlSettings::CHANNELGROUPS_ROLL <<
+ ManualControlSettings::CHANNELGROUPS_PITCH <<
+ ManualControlSettings::CHANNELGROUPS_YAW <<
+ ManualControlSettings::CHANNELGROUPS_FLIGHTMODE <<
+ ManualControlSettings::CHANNELGROUPS_ACCESSORY0 <<
+ ManualControlSettings::CHANNELGROUPS_ACCESSORY1 <<
+ ManualControlSettings::CHANNELGROUPS_ACCESSORY2;
+
+ acroChannelOrder << ManualControlSettings::CHANNELGROUPS_THROTTLE <<
+ ManualControlSettings::CHANNELGROUPS_ROLL <<
+ ManualControlSettings::CHANNELGROUPS_PITCH <<
+ ManualControlSettings::CHANNELGROUPS_YAW <<
+ ManualControlSettings::CHANNELGROUPS_FLIGHTMODE <<
+ ManualControlSettings::CHANNELGROUPS_ACCESSORY0 <<
+ ManualControlSettings::CHANNELGROUPS_ACCESSORY1 <<
+ ManualControlSettings::CHANNELGROUPS_ACCESSORY2;
+}
+void ConfigInputWidget::resetTxControls()
+{
+
+ m_txLeftStick->setTransform(m_txLeftStickOrig,false);
+ m_txRightStick->setTransform(m_txRightStickOrig,false);
+ m_txAccess0->setTransform(m_txAccess0Orig,false);
+ m_txAccess1->setTransform(m_txAccess1Orig,false);
+ m_txAccess2->setTransform(m_txAccess2Orig,false);
+ m_txFlightMode->setElementId("flightModeCenter");
+ m_txFlightMode->setTransform(m_txFlightModeCOrig,false);
+ m_txArrows->setVisible(false);
}
ConfigInputWidget::~ConfigInputWidget()
{
- // Do nothing
-}
-
-/**
- Slot called whenever we revert a signal
- */
-void ConfigInputWidget::reverseCheckboxClicked(bool state)
-{
- QObject* obj = sender();
- int i = inRevCheckboxes.indexOf((QCheckBox*)obj);
-
- inSliders[i]->setInvertedAppearance(state);
- int max = inMaxLabels[i]->text().toInt();
- int min = inMinLabels[i]->text().toInt();
- if ((state && (max>min)) ||
- (!state && (max < min))) {
- inMaxLabels[i]->setText(QString::number(min));
- inMinLabels[i]->setText(QString::number(max));
- }
-}
-
-
-// ************************************
-
-/*
- Enable or disable some controls depending on whether we are connected
- or not to the board. Actually, this i mostly useless IMHO, I don't
- know who added this into the code (Ed's note)
- */
-void ConfigInputWidget::enableControls(bool enable)
-{
- //m_config->saveRCInputToRAM->setEnabled(enable);
- m_config->saveRCInputToSD->setEnabled(enable);
- m_config->doRCInputCalibration->setEnabled(enable);
-}
-
-
-/********************************
- * Input settings
- *******************************/
-
-/**
- Request the current config from the board
- */
-void ConfigInputWidget::refreshValues()
-{
- UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ManualControlSettings")));
- Q_ASSERT(obj);
- //obj->requestUpdate();
- UAVObjectField *field;
-
- // Now update all the slider values:
-
- UAVObjectField *field_max = obj->getField(QString("ChannelMax"));
- UAVObjectField *field_min = obj->getField(QString("ChannelMin"));
- UAVObjectField *field_neu = obj->getField(QString("ChannelNeutral"));
- Q_ASSERT(field_max);
- Q_ASSERT(field_min);
- Q_ASSERT(field_neu);
- for (int i = 0; i < 8; i++) {
- QVariant max = field_max->getValue(i);
- QVariant min = field_min->getValue(i);
- QVariant neutral = field_neu->getValue(i);
- inMaxLabels[i]->setText(max.toString());
- inMinLabels[i]->setText(min.toString());
- if (max.toInt()> min.toInt()) {
- inRevCheckboxes[i]->setChecked(false);
- inSliders[i]->setMaximum(max.toInt());
- inSliders[i]->setMinimum(min.toInt());
- } else {
- inRevCheckboxes[i]->setChecked(true);
- inSliders[i]->setMaximum(min.toInt());
- inSliders[i]->setMinimum(max.toInt());
- }
- inSliders[i]->setValue(neutral.toInt());
- }
-
- // Update receiver type
- field = obj->getField(QString("InputMode"));
- m_config->receiverType->setText(field->getValue().toString());
-
- // Reset all channel assignement dropdowns:
- foreach (QComboBox *combo, inChannelAssign) {
- combo->setCurrentIndex(0);
- }
-
- // Update all channels assignements
- QList fieldList = obj->getFields();
- foreach (UAVObjectField *field, fieldList) {
- if (field->getUnits().contains("channel"))
- assignChannel(obj, field->getName());
- }
-
- // Update all the flight mode settingsin the relevant tab
- field = obj->getField(QString("FlightModePosition"));
- m_config->fmsModePos1->setCurrentIndex((m_config->fmsModePos1->findText(field->getValue(0).toString())));
- m_config->fmsModePos2->setCurrentIndex((m_config->fmsModePos2->findText(field->getValue(1).toString())));
- m_config->fmsModePos3->setCurrentIndex((m_config->fmsModePos3->findText(field->getValue(2).toString())));
-
- field = obj->getField(QString("Stabilization1Settings"));
- m_config->fmsSsPos1Roll->setCurrentIndex(m_config->fmsSsPos1Roll->findText(field->getValue(field->getElementNames().indexOf("Roll")).toString()));
- m_config->fmsSsPos1Pitch->setCurrentIndex(m_config->fmsSsPos1Pitch->findText(field->getValue(field->getElementNames().indexOf("Pitch")).toString()));
- m_config->fmsSsPos1Yaw->setCurrentIndex(m_config->fmsSsPos1Yaw->findText(field->getValue(field->getElementNames().indexOf("Yaw")).toString()));
- field = obj->getField(QString("Stabilization2Settings"));
- m_config->fmsSsPos2Roll->setCurrentIndex(m_config->fmsSsPos2Roll->findText(field->getValue(field->getElementNames().indexOf("Roll")).toString()));
- m_config->fmsSsPos2Pitch->setCurrentIndex(m_config->fmsSsPos2Pitch->findText(field->getValue(field->getElementNames().indexOf("Pitch")).toString()));
- m_config->fmsSsPos2Yaw->setCurrentIndex(m_config->fmsSsPos2Yaw->findText(field->getValue(field->getElementNames().indexOf("Yaw")).toString()));
- field = obj->getField(QString("Stabilization3Settings"));
- m_config->fmsSsPos3Roll->setCurrentIndex(m_config->fmsSsPos3Roll->findText(field->getValue(field->getElementNames().indexOf("Roll")).toString()));
- m_config->fmsSsPos3Pitch->setCurrentIndex(m_config->fmsSsPos3Pitch->findText(field->getValue(field->getElementNames().indexOf("Pitch")).toString()));
- m_config->fmsSsPos3Yaw->setCurrentIndex(m_config->fmsSsPos3Yaw->findText(field->getValue(field->getElementNames().indexOf("Yaw")).toString()));
-
- // Load the arming settings
- field = obj->getField(QString("Arming"));
- m_config->armControl->setCurrentIndex(m_config->armControl->findText(field->getValue().toString()));
- field = obj->getField(QString("ArmedTimeout"));
- m_config->armTimeout->setValue(field->getValue().toInt()/1000);
-}
-
-
-/**
- * Sends the config to the board, without saving to the SD card
- */
-void ConfigInputWidget::sendRCInputUpdate()
-{
- ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
- UAVObjectManager *objManager = pm->getObject();
- UAVDataObject* obj = dynamic_cast(objManager->getObject(QString("ManualControlSettings")));
- Q_ASSERT(obj);
- // Now update all fields from the sliders:
- QString fieldName = QString("ChannelMax");
- UAVObjectField * field = obj->getField(fieldName);
- for (int i = 0; i < 8; i++) {
- field->setValue(inMaxLabels[i]->text().toInt(), i);
- }
-
- fieldName = QString("ChannelMin");
- field = obj->getField(fieldName);
- for (int i = 0; i < 8; i++) {
- field->setValue(inMinLabels[i]->text().toInt(), i);
- }
-
- fieldName = QString("ChannelNeutral");
- field = obj->getField(fieldName);
- for (int i = 0; i < 8; i++)
- field->setValue(inSliders[i]->value(), i);
-
- // Set Roll/Pitch/Yaw/Etc assignement:
- // Rule: if two channels have the same setting (which is wrong!) the higher channel
- // will get the setting.
-
- // First, reset all channel assignements:
- QList fieldList = obj->getFields();
- foreach (UAVObjectField* field, fieldList) {
- if (field->getUnits().contains("channel")) {
- field->setValue(field->getOptions().last());
- }
- }
-
- // Then assign according to current GUI state:
- if (m_config->ch0Assign->currentIndex() != 0) {
- field = obj->getField(m_config->ch0Assign->currentText());
- field->setValue(field->getOptions().at(0)); // -> This way we don't depend on channel naming convention
- }
- if (m_config->ch1Assign->currentIndex() != 0) {
- field = obj->getField(m_config->ch1Assign->currentText());
- field->setValue(field->getOptions().at(1));
- }
- if (m_config->ch2Assign->currentIndex() != 0) {
- field = obj->getField(m_config->ch2Assign->currentText());
- field->setValue(field->getOptions().at(2));
- }
- if (m_config->ch3Assign->currentIndex() != 0) {
- field = obj->getField(m_config->ch3Assign->currentText());
- field->setValue(field->getOptions().at(3));
- }
- if (m_config->ch4Assign->currentIndex() != 0) {
- field = obj->getField(m_config->ch4Assign->currentText());
- field->setValue(field->getOptions().at(4));
- }
- if (m_config->ch5Assign->currentIndex() != 0) {
- field = obj->getField(m_config->ch5Assign->currentText());
- field->setValue(field->getOptions().at(5));
- }
- if (m_config->ch6Assign->currentIndex() != 0) {
- field = obj->getField(m_config->ch6Assign->currentText());
- field->setValue(field->getOptions().at(6));
- }
- if (m_config->ch7Assign->currentIndex() != 0) {
- field = obj->getField(m_config->ch7Assign->currentText());
- field->setValue(field->getOptions().at(7));
- }
-
- // Send all the flight mode settings
- field = obj->getField(QString("FlightModePosition"));
- field->setValue(m_config->fmsModePos1->currentText(),0);
- field->setValue(m_config->fmsModePos2->currentText(),1);
- field->setValue(m_config->fmsModePos3->currentText(),2);
-
- field = obj->getField(QString("Stabilization1Settings"));
- field->setValue(m_config->fmsSsPos1Roll->currentText(), field->getElementNames().indexOf("Roll"));
- field->setValue(m_config->fmsSsPos1Pitch->currentText(), field->getElementNames().indexOf("Pitch"));
- field->setValue(m_config->fmsSsPos1Yaw->currentText(), field->getElementNames().indexOf("Yaw"));
- field = obj->getField(QString("Stabilization2Settings"));
- field->setValue(m_config->fmsSsPos2Roll->currentText(), field->getElementNames().indexOf("Roll"));
- field->setValue(m_config->fmsSsPos2Pitch->currentText(), field->getElementNames().indexOf("Pitch"));
- field->setValue(m_config->fmsSsPos2Yaw->currentText(), field->getElementNames().indexOf("Yaw"));
- field = obj->getField(QString("Stabilization3Settings"));
- field->setValue(m_config->fmsSsPos3Roll->currentText(), field->getElementNames().indexOf("Roll"));
- field->setValue(m_config->fmsSsPos3Pitch->currentText(), field->getElementNames().indexOf("Pitch"));
- field->setValue(m_config->fmsSsPos3Yaw->currentText(), field->getElementNames().indexOf("Yaw"));
-
- // Save the arming settings
- field = obj->getField(QString("Arming"));
- field->setValue(m_config->armControl->currentText());
- field = obj->getField(QString("ArmedTimeout"));
- field->setValue(m_config->armTimeout->value()*1000);
-
- // ... and send to the OP Board
- obj->updated();
}
-/**
- Sends the config to the board and request saving into the SD card
- */
-void ConfigInputWidget::saveRCInputObject()
+void ConfigInputWidget::resizeEvent(QResizeEvent *event)
{
- // Send update so that the latest value is saved
- sendRCInputUpdate();
- UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ManualControlSettings")));
- Q_ASSERT(obj);
- saveObjectToSD(obj);
-}
-
-
-/**
- * Set the dropdown option for a channel Input assignement
- */
-void ConfigInputWidget::assignChannel(UAVDataObject *obj, QString str)
-{
- UAVObjectField* field = obj->getField(str);
- QStringList options = field->getOptions();
- switch (options.indexOf(field->getValue().toString())) {
- case 0:
- m_config->ch0Assign->setCurrentIndex(m_config->ch0Assign->findText(str));
- break;
- case 1:
- m_config->ch1Assign->setCurrentIndex(m_config->ch0Assign->findText(str));
- break;
- case 2:
- m_config->ch2Assign->setCurrentIndex(m_config->ch0Assign->findText(str));
- break;
- case 3:
- m_config->ch3Assign->setCurrentIndex(m_config->ch0Assign->findText(str));
- break;
- case 4:
- m_config->ch4Assign->setCurrentIndex(m_config->ch0Assign->findText(str));
- break;
- case 5:
- m_config->ch5Assign->setCurrentIndex(m_config->ch0Assign->findText(str));
- break;
- case 6:
- m_config->ch6Assign->setCurrentIndex(m_config->ch0Assign->findText(str));
- break;
- case 7:
- m_config->ch7Assign->setCurrentIndex(m_config->ch0Assign->findText(str));
- break;
- }
-}
-
-/**
- * Updates the slider positions and min/max values
- *
- */
-void ConfigInputWidget::updateChannels(UAVObject* controlCommand)
-{
-
- QString fieldName = QString("Connected");
- UAVObjectField *field = controlCommand->getField(fieldName);
- if (field->getValue().toBool())
- {
- m_config->RCInputConnected->setText("RC Receiver connected");
- m_config->lblMissingInputs->setText("");
- }
- else
- {
- m_config->RCInputConnected->setText("RC Receiver not connected or invalid input configuration (missing channels)");
- receiverHelp();
- }
- if (m_config->doRCInputCalibration->isChecked()) {
- if (firstUpdate) {
- // Increase the data rate from the board so that the sliders
- // move faster
- UAVObject::Metadata mdata = controlCommand->getMetadata();
- mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
- mccDataRate = mdata.flightTelemetryUpdatePeriod;
- mdata.flightTelemetryUpdatePeriod = 150;
- controlCommand->setMetadata(mdata);
-
- // Also protect the user by setting all values to zero
- // and making the ActuatorCommand object readonly
- UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorCommand")));
- mdata = obj->getMetadata();
- mdata.flightAccess = UAVObject::ACCESS_READONLY;
- obj->setMetadata(mdata);
- UAVObjectField *field = obj->getField("Channel");
- for (uint i=0; i< field->getNumElements(); i++) {
- field->setValue(0,i);
- }
- obj->updated();
-
- // OP-534: make sure the airframe can NEVER arm
- obj = dynamic_cast(getObjectManager()->getObject(QString("ManualControlSettings")));
- field = obj->getField("Arming");
- field->setValue("Always Disarmed");
- obj->updated();
-
- // Last, make sure the user won't apply/save during calibration
- m_config->saveRCInputToRAM->setEnabled(false);
- m_config->saveRCInputToSD->setEnabled(false);
-
- // Reset all slider values to zero
- field = controlCommand->getField(QString("Channel"));
- for (int i = 0; i < 8; i++)
- updateChannelInSlider(inSliders[i], inMinLabels[i], inMaxLabels[i], field->getValue(i).toInt(),inRevCheckboxes[i]->isChecked());
- firstUpdate = false;
- // Tell a few things to the user:
- QMessageBox msgBox;
- msgBox.setText(tr("Arming Settings are now set to Always Disarmed for your safety."));
- msgBox.setDetailedText(tr("You will have to reconfigure arming settings yourself afterwards."));
- msgBox.setStandardButtons(QMessageBox::Ok);
- msgBox.setDefaultButton(QMessageBox::Ok);
- msgBox.exec();
-
- }
-
- field = controlCommand->getField(QString("Channel"));
- for (int i = 0; i < 8; i++)
- updateChannelInSlider(inSliders[i], inMinLabels[i], inMaxLabels[i], field->getValue(i).toInt(),inRevCheckboxes[i]->isChecked());
- }
- else {
- if (!firstUpdate) {
- // Restore original data rate from the board:
- UAVObject::Metadata mdata = controlCommand->getMetadata();
- mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
- mdata.flightTelemetryUpdatePeriod = mccDataRate;
- controlCommand->setMetadata(mdata);
-
- UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorCommand")));
- mdata = obj->getMetadata();
- mdata.flightAccess = UAVObject::ACCESS_READWRITE;
- obj->setMetadata(mdata);
-
- // Set some slider values to better defaults
- // Find some channels first
- int throttleChannel = -1;
- int fmChannel = -1;
- for (int i=0; i < inChannelAssign.length(); i++) {
- if (inChannelAssign.at(i)->currentText() == "Throttle") {
- // TODO: this is very ugly, because this relies on the name of the
- // channel input, everywhere else in the gadget we don't rely on the
- // naming...
- throttleChannel = i;
- }
- if (inChannelAssign.at(i)->currentText() == "FlightMode") {
- // TODO: this is very ugly, because this relies on the name of the
- // channel input, everywhere else in the gadget we don't rely on the
- // naming...
- fmChannel = i;
- }
- }
-
- // Throttle neutral defaults to 2% of range
- if (throttleChannel > -1) {
- inSliders.at(throttleChannel)->setValue(
- inSliders.at(throttleChannel)->minimum() +
- (inSliders.at(throttleChannel)->maximum()-
- inSliders.at(throttleChannel)->minimum())*0.02);
- }
-
- // Flight mode at 50% of range:
- if (fmChannel > -1) {
- inSliders.at(fmChannel)->setValue(
- inSliders.at(fmChannel)->minimum()+
- (inSliders.at(fmChannel)->maximum()-
- inSliders.at(fmChannel)->minimum())*0.5);
- }
-
- m_config->saveRCInputToRAM->setEnabled(true);
- m_config->saveRCInputToSD->setEnabled(true);
- }
- firstUpdate = true;
- }
-
- //Update the Flight mode channel slider
- ManualControlSettings * manualSettings = ManualControlSettings::GetInstance(getObjectManager());
- ManualControlSettings::DataFields manualSettingsData = manualSettings->getData();
- uint chIndex = manualSettingsData.FlightMode;
- if (chIndex < manualSettings->FLIGHTMODE_NONE) {
- float valueScaled;
-
- int chMin = manualSettingsData.ChannelMin[chIndex];
- int chMax = manualSettingsData.ChannelMax[chIndex];
- int chNeutral = manualSettingsData.ChannelNeutral[chIndex];
-
- int value = controlCommand->getField("Channel")->getValue(chIndex).toInt();
- if ((chMax > chMin && value >= chNeutral) || (chMin > chMax && value <= chNeutral))
- {
- if (chMax != chNeutral)
- valueScaled = (float)(value - chNeutral) / (float)(chMax - chNeutral);
- else
- valueScaled = 0;
- }
- else
- {
- if (chMin != chNeutral)
- valueScaled = (float)(value - chNeutral) / (float)(chNeutral - chMin);
- else
- valueScaled = 0;
- }
-
- if(valueScaled < -(1.0 / 3.0))
- m_config->fmsSlider->setValue(-100);
- else if (valueScaled > (1.0/3.0))
- m_config->fmsSlider->setValue(100);
- else
- m_config->fmsSlider->setValue(0);
-
- }
-}
-
-void ConfigInputWidget::updateChannelInSlider(QSlider *slider, QLabel *min, QLabel *max, int value, bool reversed)
-{
- if (!slider || !min || !max)
- return;
-
- if (firstUpdate) {
- // Reset all the min/max values of the progress bar since we are starting the calibration.
- slider->setMaximum(value);
- slider->setMinimum(value);
- slider->setValue(value);
- max->setText(QString::number(value));
- min->setText(QString::number(value));
- return;
- }
-
- if (value > 0) {
- // avoids glitches...
- if (value > slider->maximum()) {
- slider->setMaximum(value);
- if (reversed)
- min->setText(QString::number(value));
- else
- max->setText(QString::number(value));
- }
- if (value < slider->minimum()) {
- slider->setMinimum(value);
- if (reversed)
- max->setText(QString::number(value));
- else
- min->setText(QString::number(value));
- }
- slider->setValue(value);
- }
+ QWidget::resizeEvent(event);
+ m_config->graphicsView->fitInView(m_txBackground, Qt::KeepAspectRatio );
}
void ConfigInputWidget::openHelp()
@@ -653,77 +272,945 @@ void ConfigInputWidget::openHelp()
QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/display/Doc/Input+Configuration", QUrl::StrictMode) );
}
-void ConfigInputWidget::receiverHelp()
+void ConfigInputWidget::goToWizard()
{
- QString unassigned;
- ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
- UAVObjectManager *objManager = pm->getObject();
- UAVDataObject* controlCommand = dynamic_cast(objManager->getObject(QString("ManualControlSettings")));
-
- UAVObjectField *field;
-
- field= controlCommand->getField("Roll");
- if(field->getValue().toString()=="None")
- unassigned.append("Roll");
-
- field =controlCommand->getField("Pitch");
- if(field->getValue().toString()=="None")
- {
- if(unassigned.length()>0)
- unassigned.append(", ");
- unassigned.append("Pitch");
- }
-
- field =controlCommand->getField("Yaw");
- if(field->getValue().toString()=="None")
- {
- if(unassigned.length()>0)
- unassigned.append(", ");
- unassigned.append("Yaw");
- }
-
- field =controlCommand->getField("Throttle");
- if(field->getValue().toString()=="None")
- {
- if(unassigned.length()>0)
- unassigned.append(", ");
- unassigned.append("Throttle");
- }
-
- field =controlCommand->getField("FlightMode");
- if(field->getValue().toString()=="None")
- {
- if(unassigned.length()>0)
- unassigned.append(", ");
- unassigned.append("FlightMode");
- }
- if(unassigned.length()>0)
- m_config->lblMissingInputs->setText(QString("Channels left to assign: ")+unassigned);
- else
- m_config->lblMissingInputs->setText("");
+ QMessageBox msgBox;
+ msgBox.setText(tr("Arming Settings are now set to Always Disarmed for your safety."));
+ msgBox.setDetailedText(tr("You will have to reconfigure arming settings yourself afterwards."));
+ msgBox.setStandardButtons(QMessageBox::Ok);
+ msgBox.setDefaultButton(QMessageBox::Ok);
+ msgBox.exec();
+ wizardSetUpStep(wizardWelcome);
+ m_config->graphicsView->fitInView(m_txBackground, Qt::KeepAspectRatio );
}
-void ConfigInputWidget::updateTips(int value)
+
+void ConfigInputWidget::wzCancel()
{
- if(value==Qt::Checked)
+ dimOtherControls(false);
+ manualCommandObj->setMetadata(manualCommandObj->getDefaultMetadata());
+ m_config->stackedWidget->setCurrentIndex(0);
+
+ if(wizardStep != wizardNone)
+ wizardTearDownStep(wizardStep);
+ wizardStep=wizardNone;
+ m_config->stackedWidget->setCurrentIndex(0);
+
+ // Load settings back from beginning of wizard
+ manualSettingsObj->setData(previousManualSettingsData);
+}
+
+void ConfigInputWidget::wzNext()
+{
+ // In identify sticks mode the next button can indicate
+ // channel advance
+ if(wizardStep != wizardNone &&
+ wizardStep != wizardIdentifySticks)
+ wizardTearDownStep(wizardStep);
+
+ // State transitions for next button
+ switch(wizardStep) {
+ case wizardWelcome:
+ wizardSetUpStep(wizardChooseMode);
+ break;
+ case wizardChooseMode:
+ wizardSetUpStep(wizardChooseType);
+ break;
+ case wizardChooseType:
+ wizardSetUpStep(wizardIdentifySticks);
+ break;
+ case wizardIdentifySticks:
+ nextChannel();
+ if(currentChannelNum==-1) { // Gone through all channels
+ wizardTearDownStep(wizardIdentifySticks);
+ wizardSetUpStep(wizardIdentifyCenter);
+ }
+ break;
+ case wizardIdentifyCenter:
+ wizardSetUpStep(wizardIdentifyLimits);
+ break;
+ case wizardIdentifyLimits:
+ wizardSetUpStep(wizardIdentifyInverted);
+ break;
+ case wizardIdentifyInverted:
+ wizardSetUpStep(wizardFinish);
+ break;
+ case wizardFinish:
+ wizardStep=wizardNone;
+ m_config->stackedWidget->setCurrentIndex(0);
+ break;
+ default:
+ Q_ASSERT(0);
+ }
+}
+
+void ConfigInputWidget::wzBack()
+{
+ if(wizardStep != wizardNone &&
+ wizardStep != wizardIdentifySticks)
+ wizardTearDownStep(wizardStep);
+
+ // State transitions for next button
+ switch(wizardStep) {
+ case wizardChooseMode:
+ wizardSetUpStep(wizardWelcome);
+ break;
+ case wizardChooseType:
+ wizardSetUpStep(wizardChooseMode);
+ break;
+ case wizardIdentifySticks:
+ prevChannel();
+ if(currentChannelNum == -1) {
+ wizardTearDownStep(wizardIdentifySticks);
+ wizardSetUpStep(wizardChooseType);
+ }
+ break;
+ case wizardIdentifyCenter:
+ wizardSetUpStep(wizardIdentifySticks);
+ break;
+ case wizardIdentifyLimits:
+ wizardSetUpStep(wizardIdentifyCenter);
+ break;
+ case wizardIdentifyInverted:
+ wizardSetUpStep(wizardIdentifyLimits);
+ break;
+ case wizardFinish:
+ wizardSetUpStep(wizardIdentifyInverted);
+ break;
+ default:
+ Q_ASSERT(0);
+ }
+}
+
+void ConfigInputWidget::wizardSetUpStep(enum wizardSteps step)
+{
+ switch(step) {
+ case wizardWelcome:
+ m_config->graphicsView->setVisible(false);
+ setTxMovement(nothing);
+ manualSettingsData=manualSettingsObj->getData();
+ manualSettingsData.Arming=ManualControlSettings::ARMING_ALWAYSDISARMED;
+ previousManualSettingsData = manualSettingsData;
+ manualSettingsObj->setData(manualSettingsData);
+ m_config->wzText->setText(tr("Welcome to the inputs configuration wizard.\n"
+ "Please follow the instructions on the screen and only move your controls when asked to.\n"
+ "Make sure you already configured your hardware settings on the proper tab and restarted your board.\n"
+ "At any time you can press 'back' to return to the previous screeen or 'Cancel' to cancel the wizard.\n"));
+ m_config->stackedWidget->setCurrentIndex(1);
+ m_config->wzBack->setEnabled(false);
+ break;
+ case wizardChooseMode:
{
- m_config->ch0Cur->setToolTip("Current channel value");
- m_config->ch1Cur->setToolTip("Current channel value");
- m_config->ch2Cur->setToolTip("Current channel value");
- m_config->ch3Cur->setToolTip("Current channel value");
- m_config->ch4Cur->setToolTip("Current channel value");
- m_config->ch5Cur->setToolTip("Current channel value");
- m_config->ch6Cur->setToolTip("Current channel value");
- m_config->ch7Cur->setToolTip("Current channel value");
+ m_config->graphicsView->setVisible(true);
+ setTxMovement(nothing);
+ m_config->wzText->setText(tr("Please choose your transmiter type.\n"
+ "Mode 1 means your throttle stick is on the right\n"
+ "Mode 2 means your throttle stick is on the left\n"));
+ m_config->wzBack->setEnabled(true);
+ QRadioButton * mode1=new QRadioButton(tr("Mode 1"),this);
+ QRadioButton * mode2=new QRadioButton(tr("Mode 2"),this);
+ mode2->setChecked(true);
+ extraWidgets.clear();
+ extraWidgets.append(mode1);
+ extraWidgets.append(mode2);
+ m_config->checkBoxesLayout->layout()->addWidget(mode1);
+ m_config->checkBoxesLayout->layout()->addWidget(mode2);
+ }
+ break;
+ case wizardChooseType:
+ {
+ m_config->wzText->setText(tr("Please choose your transmiter mode.\n"
+ "Acro means normal transmitter\n"
+ "Heli means there is a collective pitch and throttle input\n"
+ "If you are using a heli transmitter please engage throttle hold now please.\n"));
+ m_config->wzBack->setEnabled(true);
+ QRadioButton * typeAcro=new QRadioButton(tr("Acro"),this);
+ QRadioButton * typeHeli=new QRadioButton(tr("Heli"),this);
+ typeAcro->setChecked(true);
+ typeHeli->setChecked(false);
+ extraWidgets.clear();
+ extraWidgets.append(typeAcro);
+ extraWidgets.append(typeHeli);
+ m_config->checkBoxesLayout->layout()->addWidget(typeAcro);
+ m_config->checkBoxesLayout->layout()->addWidget(typeHeli);
+ wizardStep=wizardChooseType;
+ }
+ break;
+ case wizardIdentifySticks:
+ usedChannels.clear();
+ currentChannelNum=-1;
+ nextChannel();
+ manualSettingsData=manualSettingsObj->getData();
+ connect(receiverActivityObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(identifyControls()));
+ m_config->wzNext->setEnabled(false);
+ break;
+ case wizardIdentifyCenter:
+ setTxMovement(centerAll);
+ m_config->wzText->setText(QString(tr("Please center all control controls and press next when ready (if your FlightMode switch has only two positions, leave it on either position)")));
+ break;
+ case wizardIdentifyLimits:
+ {
+ setTxMovement(nothing);
+ m_config->wzText->setText(QString(tr("Please move all controls to their maximum extents on both directions and press next when ready")));
+ fastMdata();
+ manualSettingsData=manualSettingsObj->getData();
+ for(uint i=0;igetField("ChannelMax")->getElementNames().length(); index++)
+ {
+ QString name = manualSettingsObj->getField("ChannelMax")->getElementNames().at(index);
+ if(!name.contains("Access") && !name.contains("Flight"))
+ {
+ QCheckBox * cb=new QCheckBox(name,this);
+ // Make sure checked status matches current one
+ cb->setChecked(manualSettingsData.ChannelMax[index] < manualSettingsData.ChannelMin[index]);
+
+ extraWidgets.append(cb);
+ m_config->checkBoxesLayout->layout()->addWidget(cb);
+
+ connect(cb,SIGNAL(toggled(bool)),this,SLOT(invertControls()));
+ }
+ }
+ connect(manualCommandObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(moveSticks()));
+ m_config->wzText->setText(QString(tr("Please check the picture below and check all the sticks which show an inverted movement and press next when ready")));
+ fastMdata();
+ break;
+ case wizardFinish:
+ dimOtherControls(true);
+ connect(manualCommandObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(moveSticks()));
+ m_config->wzText->setText(QString(tr("You have completed this wizard, please check below if the picture below mimics your sticks movement.\n"
+ "This new settings aren't saved to the board yet, after pressing next you will go to the initial screen where you can do that.")));
+ fastMdata();
+
+ manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_THROTTLE]=
+ manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_THROTTLE]+
+ ((manualSettingsData.ChannelMax[ManualControlSettings::CHANNELMAX_THROTTLE]-
+ manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_THROTTLE])*0.02);
+ if((abs(manualSettingsData.ChannelMax[ManualControlSettings::CHANNELMAX_FLIGHTMODE]-manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_FLIGHTMODE])<100) ||
+ (abs(manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_FLIGHTMODE]-manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_FLIGHTMODE])<100))
+ {
+ manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_FLIGHTMODE]=manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_FLIGHTMODE]+
+ (manualSettingsData.ChannelMax[ManualControlSettings::CHANNELMAX_FLIGHTMODE]-manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_FLIGHTMODE])/2;
+ }
+ manualSettingsObj->setData(manualSettingsData);
+ break;
+ default:
+ Q_ASSERT(0);
+ }
+ wizardStep = step;
+}
+
+void ConfigInputWidget::wizardTearDownStep(enum wizardSteps step)
+{
+ QRadioButton * mode, * type;
+ Q_ASSERT(step == wizardStep);
+ switch(step) {
+ case wizardWelcome:
+ break;
+ case wizardChooseMode:
+ mode=qobject_cast(extraWidgets.at(0));
+ if(mode->isChecked())
+ transmitterMode=mode1;
+ else
+ transmitterMode=mode2;
+ delete extraWidgets.at(0);
+ delete extraWidgets.at(1);
+ extraWidgets.clear();
+ break;
+ case wizardChooseType:
+ type=qobject_cast(extraWidgets.at(0));
+ if(type->isChecked())
+ transmitterType=acro;
+ else
+ transmitterType=heli;
+ delete extraWidgets.at(0);
+ delete extraWidgets.at(1);
+ extraWidgets.clear();
+ break;
+ case wizardIdentifySticks:
+ disconnect(receiverActivityObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(identifyControls()));
+ m_config->wzNext->setEnabled(true);
+ setTxMovement(nothing);
+ break;
+ case wizardIdentifyCenter:
+ manualCommandData=manualCommandObj->getData();
+ manualSettingsData=manualSettingsObj->getData();
+ for(unsigned int i=0;isetData(manualSettingsData);
+ setTxMovement(nothing);
+ break;
+ case wizardIdentifyLimits:
+ disconnect(manualCommandObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(identifyLimits()));
+ disconnect(manualCommandObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(moveSticks()));
+ manualSettingsObj->setData(manualSettingsData);
+ restoreMdata();
+ setTxMovement(nothing);
+ break;
+ case wizardIdentifyInverted:
+ dimOtherControls(false);
+ foreach(QWidget * wd,extraWidgets)
+ {
+ QCheckBox * cb=qobject_cast(wd);
+ if(cb)
+ {
+ disconnect(cb,SIGNAL(toggled(bool)),this,SLOT(invertControls()));
+ delete cb;
+ }
+ }
+ extraWidgets.clear();
+ disconnect(manualCommandObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(moveSticks()));
+ restoreMdata();
+ break;
+ case wizardFinish:
+ dimOtherControls(false);
+ setTxMovement(nothing);
+ disconnect(manualCommandObj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(moveSticks()));
+ restoreMdata();
+ break;
+ default:
+ Q_ASSERT(0);
+ }
+}
+
+/**
+ * Set manual control command to fast updates
+ */
+void ConfigInputWidget::fastMdata()
+{
+ manualControlMdata = manualCommandObj->getMetadata();
+ UAVObject::Metadata mdata = manualControlMdata;
+ mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
+ mdata.flightTelemetryUpdatePeriod = 150;
+ manualCommandObj->setMetadata(mdata);
+}
+
+/**
+ * Restore previous update settings for manual control data
+ */
+void ConfigInputWidget::restoreMdata()
+{
+ manualCommandObj->setMetadata(manualControlMdata);
+}
+
+/**
+ * Set the display to indicate which channel the person should move
+ */
+void ConfigInputWidget::setChannel(int newChan)
+{
+ if(newChan == ManualControlSettings::CHANNELGROUPS_COLLECTIVE)
+ m_config->wzText->setText(QString(tr("Please enable throttle hold mode and move the collective pitch stick")));
+ else if (newChan == ManualControlSettings::CHANNELGROUPS_FLIGHTMODE)
+ m_config->wzText->setText(QString(tr("Please flick the flight mode switch. For switches you may have to repeat this rapidly.")));
+ else
+ m_config->wzText->setText(QString(tr("Please move each control once at a time according to the instructions and picture below.\n\n"
+ "Move the %1 stick")).arg(manualSettingsObj->getField("ChannelGroups")->getElementNames().at(newChan)));
+
+ if(manualSettingsObj->getField("ChannelGroups")->getElementNames().at(newChan).contains("Accessory")) {
+ m_config->wzNext->setEnabled(true);
+ m_config->wzText->setText(m_config->wzText->text() + tr(" or click next to skip this channel."));
+ } else
+ m_config->wzNext->setEnabled(false);
+
+ setMoveFromCommand(newChan);
+
+ currentChannelNum = newChan;
+ channelDetected = false;
+}
+
+/**
+ * Unfortunately order of channel should be different in different conditions. Selects
+ * next channel based on heli or acro mode
+ */
+void ConfigInputWidget::nextChannel()
+{
+ QList order = (transmitterType == heli) ? heliChannelOrder : acroChannelOrder;
+
+ if(currentChannelNum == -1) {
+ setChannel(order[0]);
+ return;
+ }
+ for (int i = 0; i < order.length() - 1; i++) {
+ if(order[i] == currentChannelNum) {
+ setChannel(order[i+1]);
+ return;
+ }
+ }
+ currentChannelNum = -1; // hit end of list
+}
+
+/**
+ * Unfortunately order of channel should be different in different conditions. Selects
+ * previous channel based on heli or acro mode
+ */
+void ConfigInputWidget::prevChannel()
+{
+ QList order = transmitterType == heli ? heliChannelOrder : acroChannelOrder;
+
+ // No previous from unset channel or next state
+ if(currentChannelNum == -1)
+ return;
+
+ for (int i = 1; i < order.length(); i++) {
+ if(order[i] == currentChannelNum) {
+ setChannel(order[i-1]);
+ usedChannels.removeLast();
+ return;
+ }
+ }
+ currentChannelNum = -1; // hit end of list
+}
+
+void ConfigInputWidget::identifyControls()
+{
+ static int debounce=0;
+
+ receiverActivityData=receiverActivityObj->getData();
+ if(receiverActivityData.ActiveChannel==255)
+ return;
+ if(channelDetected)
+ return;
+ else
+ {
+ receiverActivityData=receiverActivityObj->getData();
+ currentChannel.group=receiverActivityData.ActiveGroup;
+ currentChannel.number=receiverActivityData.ActiveChannel;
+ if(currentChannel==lastChannel)
+ ++debounce;
+ lastChannel.group= currentChannel.group;
+ lastChannel.number=currentChannel.number;
+ if(!usedChannels.contains(lastChannel) && debounce>1)
+ {
+ channelDetected = true;
+ debounce=0;
+ usedChannels.append(lastChannel);
+ manualSettingsData=manualSettingsObj->getData();
+ manualSettingsData.ChannelGroups[currentChannelNum]=currentChannel.group;
+ manualSettingsData.ChannelNumber[currentChannelNum]=currentChannel.number;
+ manualSettingsObj->setData(manualSettingsData);
+ }
+ else
+ return;
+ }
+
+ m_config->wzText->clear();
+ setTxMovement(nothing);
+
+ QTimer::singleShot(500, this, SLOT(wzNext()));
+}
+
+void ConfigInputWidget::identifyLimits()
+{
+ manualCommandData=manualCommandObj->getData();
+ for(uint i=0;imanualCommandData.Channel[i])
+ manualSettingsData.ChannelMin[i]=manualCommandData.Channel[i];
+ if(manualSettingsData.ChannelMax[i]manualCommandData.Channel[i])
+ manualSettingsData.ChannelMax[i]=manualCommandData.Channel[i];
+ if(manualSettingsData.ChannelMin[i]setData(manualSettingsData);
+}
+void ConfigInputWidget::setMoveFromCommand(int command)
+{
+ //CHANNELNUMBER_ROLL=0, CHANNELNUMBER_PITCH=1, CHANNELNUMBER_YAW=2, CHANNELNUMBER_THROTTLE=3, CHANNELNUMBER_FLIGHTMODE=4, CHANNELNUMBER_ACCESSORY0=5, CHANNELNUMBER_ACCESSORY1=6, CHANNELNUMBER_ACCESSORY2=7 } ChannelNumberElem;
+ if(command==ManualControlSettings::CHANNELNUMBER_ROLL)
+ {
+ setTxMovement(moveRightHorizontalStick);
+ }
+ else if(command==ManualControlSettings::CHANNELNUMBER_PITCH)
+ {
+ if(transmitterMode==mode2)
+ setTxMovement(moveRightVerticalStick);
+ else
+ setTxMovement(moveLeftVerticalStick);
+ }
+ else if(command==ManualControlSettings::CHANNELNUMBER_YAW)
+ {
+ setTxMovement(moveLeftHorizontalStick);
+ }
+ else if(command==ManualControlSettings::CHANNELNUMBER_THROTTLE)
+ {
+ if(transmitterMode==mode2)
+ setTxMovement(moveLeftVerticalStick);
+ else
+ setTxMovement(moveRightVerticalStick);
+ }
+ else if(command==ManualControlSettings::CHANNELNUMBER_COLLECTIVE)
+ {
+ if(transmitterMode==mode2)
+ setTxMovement(moveLeftVerticalStick);
+ else
+ setTxMovement(moveRightVerticalStick);
+ }
+ else if(command==ManualControlSettings::CHANNELNUMBER_FLIGHTMODE)
+ {
+ setTxMovement(moveFlightMode);
+ }
+ else if(command==ManualControlSettings::CHANNELNUMBER_ACCESSORY0)
+ {
+ setTxMovement(moveAccess0);
+ }
+ else if(command==ManualControlSettings::CHANNELNUMBER_ACCESSORY1)
+ {
+ setTxMovement(moveAccess1);
+ }
+ else if(command==ManualControlSettings::CHANNELNUMBER_ACCESSORY2)
+ {
+ setTxMovement(moveAccess2);
+ }
+
+}
+
+void ConfigInputWidget::setTxMovement(txMovements movement)
+{
+ resetTxControls();
+ switch(movement)
+ {
+ case moveLeftVerticalStick:
+ movePos=0;
+ growing=true;
+ currentMovement=moveLeftVerticalStick;
+ animate->start(100);
+ break;
+ case moveRightVerticalStick:
+ movePos=0;
+ growing=true;
+ currentMovement=moveRightVerticalStick;
+ animate->start(100);
+ break;
+ case moveLeftHorizontalStick:
+ movePos=0;
+ growing=true;
+ currentMovement=moveLeftHorizontalStick;
+ animate->start(100);
+ break;
+ case moveRightHorizontalStick:
+ movePos=0;
+ growing=true;
+ currentMovement=moveRightHorizontalStick;
+ animate->start(100);
+ break;
+ case moveAccess0:
+ movePos=0;
+ growing=true;
+ currentMovement=moveAccess0;
+ animate->start(100);
+ break;
+ case moveAccess1:
+ movePos=0;
+ growing=true;
+ currentMovement=moveAccess1;
+ animate->start(100);
+ break;
+ case moveAccess2:
+ movePos=0;
+ growing=true;
+ currentMovement=moveAccess2;
+ animate->start(100);
+ break;
+ case moveFlightMode:
+ movePos=0;
+ growing=true;
+ currentMovement=moveFlightMode;
+ animate->start(1000);
+ break;
+ case centerAll:
+ movePos=0;
+ currentMovement=centerAll;
+ animate->start(1000);
+ break;
+ case moveAll:
+ movePos=0;
+ growing=true;
+ currentMovement=moveAll;
+ animate->start(50);
+ break;
+ case nothing:
+ movePos=0;
+ animate->stop();
+ break;
+ default:
+ break;
+ }
+}
+
+void ConfigInputWidget::moveTxControls()
+{
+ QTransform trans;
+ QGraphicsItem * item;
+ txMovementType move;
+ int limitMax;
+ int limitMin;
+ static bool auxFlag=false;
+ switch(currentMovement)
+ {
+ case moveLeftVerticalStick:
+ item=m_txLeftStick;
+ trans=m_txLeftStickOrig;
+ limitMax=STICK_MAX_MOVE;
+ limitMin=STICK_MIN_MOVE;
+ move=vertical;
+ break;
+ case moveRightVerticalStick:
+ item=m_txRightStick;
+ trans=m_txRightStickOrig;
+ limitMax=STICK_MAX_MOVE;
+ limitMin=STICK_MIN_MOVE;
+ move=vertical;
+ break;
+ case moveLeftHorizontalStick:
+ item=m_txLeftStick;
+ trans=m_txLeftStickOrig;
+ limitMax=STICK_MAX_MOVE;
+ limitMin=STICK_MIN_MOVE;
+ move=horizontal;
+ break;
+ case moveRightHorizontalStick:
+ item=m_txRightStick;
+ trans=m_txRightStickOrig;
+ limitMax=STICK_MAX_MOVE;
+ limitMin=STICK_MIN_MOVE;
+ move=horizontal;
+ break;
+ case moveAccess0:
+ item=m_txAccess0;
+ trans=m_txAccess0Orig;
+ limitMax=ACCESS_MAX_MOVE;
+ limitMin=ACCESS_MIN_MOVE;
+ move=horizontal;
+ break;
+ case moveAccess1:
+ item=m_txAccess1;
+ trans=m_txAccess1Orig;
+ limitMax=ACCESS_MAX_MOVE;
+ limitMin=ACCESS_MIN_MOVE;
+ move=horizontal;
+ break;
+ case moveAccess2:
+ item=m_txAccess2;
+ trans=m_txAccess2Orig;
+ limitMax=ACCESS_MAX_MOVE;
+ limitMin=ACCESS_MIN_MOVE;
+ move=horizontal;
+ break;
+ case moveFlightMode:
+ item=m_txFlightMode;
+ move=jump;
+ break;
+ case centerAll:
+ item=m_txArrows;
+ move=jump;
+ break;
+ case moveAll:
+ limitMax=STICK_MAX_MOVE;
+ limitMin=STICK_MIN_MOVE;
+ move=mix;
+ break;
+ default:
+ break;
+ }
+ if(move==vertical)
+ item->setTransform(trans.translate(0,movePos*10),false);
+ else if(move==horizontal)
+ item->setTransform(trans.translate(movePos*10,0),false);
+ else if(move==jump)
+ {
+ if(item==m_txArrows)
+ {
+ m_txArrows->setVisible(!m_txArrows->isVisible());
+ }
+ else if(item==m_txFlightMode)
+ {
+ QGraphicsSvgItem * svg;
+ svg=(QGraphicsSvgItem *)item;
+ if (svg)
+ {
+ if(svg->elementId()=="flightModeCenter")
+ {
+ if(growing)
+ {
+ svg->setElementId("flightModeRight");
+ m_txFlightMode->setTransform(m_txFlightModeROrig,false);
+ }
+ else
+ {
+ svg->setElementId("flightModeLeft");
+ m_txFlightMode->setTransform(m_txFlightModeLOrig,false);
+ }
+ }
+ else if(svg->elementId()=="flightModeRight")
+ {
+ growing=false;
+ svg->setElementId("flightModeCenter");
+ m_txFlightMode->setTransform(m_txFlightModeCOrig,false);
+ }
+ else if(svg->elementId()=="flightModeLeft")
+ {
+ growing=true;
+ svg->setElementId("flightModeCenter");
+ m_txFlightMode->setTransform(m_txFlightModeCOrig,false);
+ }
+ }
+ }
+ }
+ else if(move==mix)
+ {
+ trans=m_txAccess0Orig;
+ m_txAccess0->setTransform(trans.translate(movePos*10*ACCESS_MAX_MOVE/STICK_MAX_MOVE,0),false);
+ trans=m_txAccess1Orig;
+ m_txAccess1->setTransform(trans.translate(movePos*10*ACCESS_MAX_MOVE/STICK_MAX_MOVE,0),false);
+ trans=m_txAccess2Orig;
+ m_txAccess2->setTransform(trans.translate(movePos*10*ACCESS_MAX_MOVE/STICK_MAX_MOVE,0),false);
+
+ if(auxFlag)
+ {
+ trans=m_txLeftStickOrig;
+ m_txLeftStick->setTransform(trans.translate(0,movePos*10),false);
+ trans=m_txRightStickOrig;
+ m_txRightStick->setTransform(trans.translate(0,movePos*10),false);
+ }
+ else
+ {
+ trans=m_txLeftStickOrig;
+ m_txLeftStick->setTransform(trans.translate(movePos*10,0),false);
+ trans=m_txRightStickOrig;
+ m_txRightStick->setTransform(trans.translate(movePos*10,0),false);
+ }
+
+ if(movePos==0)
+ {
+ m_txFlightMode->setElementId("flightModeCenter");
+ m_txFlightMode->setTransform(m_txFlightModeCOrig,false);
+ }
+ else if(movePos==ACCESS_MAX_MOVE/2)
+ {
+ m_txFlightMode->setElementId("flightModeRight");
+ m_txFlightMode->setTransform(m_txFlightModeROrig,false);
+ }
+ else if(movePos==ACCESS_MIN_MOVE/2)
+ {
+ m_txFlightMode->setElementId("flightModeLeft");
+ m_txFlightMode->setTransform(m_txFlightModeLOrig,false);
+ }
+ }
+ if(move==horizontal || move==vertical ||move==mix)
+ {
+ if(movePos==0 && growing)
+ auxFlag=!auxFlag;
+ if(growing)
+ ++movePos;
+ else
+ --movePos;
+ if(movePos>limitMax)
+ {
+ movePos=movePos-2;
+ growing=false;
+ }
+ if(movePosgetData();
+ if(transmitterMode==mode2)
+ {
+ trans=m_txLeftStickOrig;
+ m_txLeftStick->setTransform(trans.translate(manualCommandData.Yaw*STICK_MAX_MOVE*10,-manualCommandData.Throttle*STICK_MAX_MOVE*10),false);
+ trans=m_txRightStickOrig;
+ m_txRightStick->setTransform(trans.translate(manualCommandData.Roll*STICK_MAX_MOVE*10,manualCommandData.Pitch*STICK_MAX_MOVE*10),false);
}
else
{
- m_config->ch0Cur->setToolTip("Channel neutral point");
- m_config->ch1Cur->setToolTip("Channel neutral point");
- m_config->ch2Cur->setToolTip("Channel neutral point");
- m_config->ch3Cur->setToolTip("Channel neutral point");
- m_config->ch4Cur->setToolTip("Channel neutral point");
- m_config->ch5Cur->setToolTip("Channel neutral point");
- m_config->ch6Cur->setToolTip("Channel neutral point");
- m_config->ch7Cur->setToolTip("Channel neutral point");
+ trans=m_txRightStickOrig;
+ m_txRightStick->setTransform(trans.translate(manualCommandData.Roll*STICK_MAX_MOVE*10,-manualCommandData.Throttle*STICK_MAX_MOVE*10),false);
+ trans=m_txLeftStickOrig;
+ m_txLeftStick->setTransform(trans.translate(manualCommandData.Yaw*STICK_MAX_MOVE*10,manualCommandData.Pitch*STICK_MAX_MOVE*10),false);
+ }
+}
+
+void ConfigInputWidget::dimOtherControls(bool value)
+{
+ qreal opac;
+ if(value)
+ opac=0.1;
+ else
+ opac=1;
+ m_txAccess0->setOpacity(opac);
+ m_txAccess1->setOpacity(opac);
+ m_txAccess2->setOpacity(opac);
+ m_txFlightMode->setOpacity(opac);
+}
+
+void ConfigInputWidget::enableControls(bool enable)
+{
+ m_config->configurationWizard->setEnabled(enable);
+ m_config->runCalibration->setEnabled(enable);
+
+ ConfigTaskWidget::enableControls(enable);
+
+}
+
+void ConfigInputWidget::invertControls()
+{
+ manualSettingsData=manualSettingsObj->getData();
+ foreach(QWidget * wd,extraWidgets)
+ {
+ QCheckBox * cb=qobject_cast(wd);
+ if(cb)
+ {
+ int index=manualSettingsObj->getFields().at(0)->getElementNames().indexOf(cb->text());
+ if((cb->isChecked() && (manualSettingsData.ChannelMax[index]>manualSettingsData.ChannelMin[index])) ||
+ (!cb->isChecked() && (manualSettingsData.ChannelMax[index]setData(manualSettingsData);
+}
+void ConfigInputWidget::moveFMSlider()
+{
+ ManualControlSettings::DataFields manualSettingsDataPriv = manualSettingsObj->getData();
+ ManualControlCommand::DataFields manualCommandDataPriv=manualCommandObj->getData();
+
+ float valueScaled;
+ int chMin = manualSettingsDataPriv.ChannelMin[ManualControlSettings::CHANNELMIN_FLIGHTMODE];
+ int chMax = manualSettingsDataPriv.ChannelMax[ManualControlSettings::CHANNELMAX_FLIGHTMODE];
+ int chNeutral = manualSettingsDataPriv.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_FLIGHTMODE];
+
+ int value = manualCommandDataPriv.Channel[ManualControlSettings::CHANNELMIN_FLIGHTMODE];
+ if ((chMax > chMin && value >= chNeutral) || (chMin > chMax && value <= chNeutral))
+ {
+ if (chMax != chNeutral)
+ valueScaled = (float)(value - chNeutral) / (float)(chMax - chNeutral);
+ else
+ valueScaled = 0;
+ }
+ else
+ {
+ if (chMin != chNeutral)
+ valueScaled = (float)(value - chNeutral) / (float)(chNeutral - chMin);
+ else
+ valueScaled = 0;
+ }
+
+ if(valueScaled < -(1.0 / 3.0))
+ m_config->fmsSlider->setValue(-100);
+ else if (valueScaled > (1.0/3.0))
+ m_config->fmsSlider->setValue(100);
+ else
+ m_config->fmsSlider->setValue(0);
+}
+
+void ConfigInputWidget::updateCalibration()
+{
+ manualCommandData=manualCommandObj->getData();
+ for(uint i=0;imanualCommandData.Channel[i]) ||
+ (reverse[i] && manualSettingsData.ChannelMin[i]manualCommandData.Channel[i]))
+ manualSettingsData.ChannelMax[i]=manualCommandData.Channel[i];
+ manualSettingsData.ChannelNeutral[i] = manualCommandData.Channel[i];
+ }
+
+ manualSettingsObj->setData(manualSettingsData);
+ manualSettingsObj->updated();
+}
+
+void ConfigInputWidget::simpleCalibration(bool enable)
+{
+ if (enable) {
+ m_config->configurationWizard->setEnabled(false);
+
+ QMessageBox msgBox;
+ msgBox.setText(tr("Arming Settings are now set to Always Disarmed for your safety."));
+ msgBox.setDetailedText(tr("You will have to reconfigure arming settings yourself afterwards."));
+ msgBox.setStandardButtons(QMessageBox::Ok);
+ msgBox.setDefaultButton(QMessageBox::Ok);
+ msgBox.exec();
+
+ manualCommandData = manualCommandObj->getData();
+
+ manualSettingsData=manualSettingsObj->getData();
+ manualSettingsData.Arming=ManualControlSettings::ARMING_ALWAYSDISARMED;
+ manualSettingsObj->setData(manualSettingsData);
+
+ for (unsigned int i = 0; i < ManualControlCommand::CHANNEL_NUMELEM; i++) {
+ reverse[i] = manualSettingsData.ChannelMax[i] < manualSettingsData.ChannelMin[i];
+ manualSettingsData.ChannelMin[i] = manualCommandData.Channel[i];
+ manualSettingsData.ChannelNeutral[i] = manualCommandData.Channel[i];
+ manualSettingsData.ChannelMax[i] = manualCommandData.Channel[i];
+ }
+
+ fastMdata();
+
+ connect(manualCommandObj, SIGNAL(objectUnpacked(UAVObject*)), this, SLOT(updateCalibration()));
+ } else {
+ m_config->configurationWizard->setEnabled(true);
+
+ manualCommandData = manualCommandObj->getData();
+ manualSettingsData = manualSettingsObj->getData();
+
+ restoreMdata();
+
+ for (int i = 0; i < ManualControlCommand::CHANNEL_NUMELEM; i++)
+ manualSettingsData.ChannelNeutral[i] = manualCommandData.Channel[i];
+
+ // Force flight mode neutral to middle
+ manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNUMBER_FLIGHTMODE] =
+ (manualSettingsData.ChannelMax[ManualControlSettings::CHANNELNUMBER_FLIGHTMODE] +
+ manualSettingsData.ChannelMin[ManualControlSettings::CHANNELNUMBER_FLIGHTMODE]) / 2;
+
+ // Force throttle to be near min
+ manualSettingsData.ChannelNeutral[ManualControlSettings::CHANNELNEUTRAL_THROTTLE]=
+ manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_THROTTLE]+
+ ((manualSettingsData.ChannelMax[ManualControlSettings::CHANNELMAX_THROTTLE]-
+ manualSettingsData.ChannelMin[ManualControlSettings::CHANNELMIN_THROTTLE])*0.02);
+
+ manualSettingsObj->setData(manualSettingsData);
+
+ disconnect(manualCommandObj, SIGNAL(objectUnpacked(UAVObject*)), this, SLOT(updateCalibration()));
}
}
diff --git a/ground/openpilotgcs/src/plugins/config/configinputwidget.h b/ground/openpilotgcs/src/plugins/config/configinputwidget.h
index 75f47cc8d..0110bccb0 100644
--- a/ground/openpilotgcs/src/plugins/config/configinputwidget.h
+++ b/ground/openpilotgcs/src/plugins/config/configinputwidget.h
@@ -34,52 +34,126 @@
#include "uavobject.h"
#include
#include
+#include "inputchannelform.h"
+#include "ui_inputchannelform.h"
+#include
+#include "manualcontrolcommand.h"
+#include "manualcontrolsettings.h"
+#include "receiveractivity.h"
+#include
+#include
+#include
class Ui_InputWidget;
class ConfigInputWidget: public ConfigTaskWidget
{
Q_OBJECT
-
public:
ConfigInputWidget(QWidget *parent = 0);
~ConfigInputWidget();
-
+ enum wizardSteps{wizardWelcome,wizardChooseMode,wizardChooseType,wizardIdentifySticks,wizardIdentifyCenter,wizardIdentifyLimits,wizardIdentifyInverted,wizardFinish,wizardNone};
+ enum txMode{mode1,mode2};
+ enum txMovements{moveLeftVerticalStick,moveRightVerticalStick,moveLeftHorizontalStick,moveRightHorizontalStick,moveAccess0,moveAccess1,moveAccess2,moveFlightMode,centerAll,moveAll,nothing};
+ enum txMovementType{vertical,horizontal,jump,mix};
+ enum txType {acro, heli};
public slots:
private:
+ bool growing;
+ bool reverse[ManualControlSettings::CHANNELNEUTRAL_NUMELEM];
+ txMovements currentMovement;
+ int movePos;
+ void setTxMovement(txMovements movement);
Ui_InputWidget *m_config;
+ wizardSteps wizardStep;
+ QList extraWidgets;
+ txMode transmitterMode;
+ txType transmitterType;
+ struct channelsStruct
+ {
+ bool operator ==(const channelsStruct& rhs) const
+ {
+ return((group==rhs.group) &&(number==rhs.number));
+ }
+ int group;
+ int number;
+ }lastChannel;
+ channelsStruct currentChannel;
+ QList usedChannels;
+ bool channelDetected;
+ QEventLoop * loop;
+ bool skipflag;
- QList sliders;
+ int currentChannelNum;
+ QList heliChannelOrder;
+ QList acroChannelOrder;
- void updateChannelInSlider(QSlider *slider, QLabel *min, QLabel *max, int value, bool reversed);
+ ManualControlCommand * manualCommandObj;
+ ManualControlCommand::DataFields manualCommandData;
+ UAVObject::Metadata manualControlMdata;
+ ManualControlSettings * manualSettingsObj;
+ ManualControlSettings::DataFields manualSettingsData;
+ ManualControlSettings::DataFields previousManualSettingsData;
+ ReceiverActivity * receiverActivityObj;
+ ReceiverActivity::DataFields receiverActivityData;
- void assignChannel(UAVDataObject *obj, QString str);
- void assignOutputChannel(UAVDataObject *obj, QString str);
+ QSvgRenderer *m_renderer;
- int mccDataRate;
+ // Background: background
+ QGraphicsSvgItem *m_txMainBody;
+ QGraphicsSvgItem *m_txLeftStick;
+ QGraphicsSvgItem *m_txRightStick;
+ QGraphicsSvgItem *m_txAccess0;
+ QGraphicsSvgItem *m_txAccess1;
+ QGraphicsSvgItem *m_txAccess2;
+ QGraphicsSvgItem *m_txFlightMode;
+ QGraphicsSvgItem *m_txBackground;
+ QGraphicsSvgItem *m_txArrows;
+ QTransform m_txLeftStickOrig;
+ QTransform m_txRightStickOrig;
+ QTransform m_txAccess0Orig;
+ QTransform m_txAccess1Orig;
+ QTransform m_txAccess2Orig;
+ QTransform m_txFlightModeCOrig;
+ QTransform m_txFlightModeLOrig;
+ QTransform m_txFlightModeROrig;
+ QTransform m_txMainBodyOrig;
+ QTransform m_txArrowsOrig;
+ QTimer * animate;
+ void resetTxControls();
+ void setMoveFromCommand(int command);
- UAVObject::Metadata accInitialData;
+ void fastMdata();
+ void restoreMdata();
- QList inSliders;
- QList inMaxLabels;
- QList inMinLabels;
- QList inNeuLabels;
- QList inRevCheckboxes;
- QList inChannelAssign;
+ void setChannel(int);
+ void nextChannel();
+ void prevChannel();
- bool firstUpdate;
-
- virtual void enableControls(bool enable);
- void receiverHelp();
+ void wizardSetUpStep(enum wizardSteps);
+ void wizardTearDownStep(enum wizardSteps);
private slots:
- void updateChannels(UAVObject* obj);
- virtual void refreshValues();
- void sendRCInputUpdate();
- void saveRCInputObject();
- void reverseCheckboxClicked(bool state);
+ void wzNext();
+ void wzBack();
+ void wzCancel();
+ void goToWizard();
+
void openHelp();
- void updateTips(int);
+ void identifyControls();
+ void identifyLimits();
+ void moveTxControls();
+ void moveSticks();
+ void dimOtherControls(bool value);
+ void moveFMSlider();
+ void invertControls();
+ void simpleCalibration(bool state);
+ void updateCalibration();
+protected:
+ void resizeEvent(QResizeEvent *event);
+ virtual void enableControls(bool enable);
+
+
};
#endif
diff --git a/ground/openpilotgcs/src/plugins/config/configoutputwidget.cpp b/ground/openpilotgcs/src/plugins/config/configoutputwidget.cpp
index 1a961805b..0aa4ee809 100644
--- a/ground/openpilotgcs/src/plugins/config/configoutputwidget.cpp
+++ b/ground/openpilotgcs/src/plugins/config/configoutputwidget.cpp
@@ -1,13 +1,13 @@
/**
******************************************************************************
*
- * @file configservowidget.cpp
+ * @file configoutputwidget.cpp
* @author E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
- * @brief Servo input/output configuration panel for the config gadget
+ * @brief Servo output configuration panel for the config gadget
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@@ -26,6 +26,7 @@
*/
#include "configoutputwidget.h"
+#include "outputchannelform.h"
#include "uavtalk/telemetrymanager.h"
@@ -38,99 +39,41 @@
#include
#include
#include
+#include "actuatorcommand.h"
+#include "actuatorsettings.h"
+#include "systemalarms.h"
+#include "uavsettingsimportexport/uavsettingsimportexportfactory.h"
-ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(parent)
+ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(parent),wasItMe(false)
{
m_config = new Ui_OutputWidget();
m_config->setupUi(this);
- ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
- UAVObjectManager *objManager = pm->getObject();
+ ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
+ setupButtons(m_config->saveRCOutputToRAM,m_config->saveRCOutputToSD);
+ addUAVObject("ActuatorSettings");
- // First of all, put all the channel widgets into lists, so that we can
- // manipulate those:
+ UAVSettingsImportExportFactory * importexportplugin = pm->getObject();
+ connect(importexportplugin,SIGNAL(importAboutToBegin()),this,SLOT(stopTests()));
- // NOTE: for historical reasons, we have objects below called ch0 to ch7, but the convention for OP is Channel 1 to Channel 8.
- outLabels << m_config->ch0OutValue
- << m_config->ch1OutValue
- << m_config->ch2OutValue
- << m_config->ch3OutValue
- << m_config->ch4OutValue
- << m_config->ch5OutValue
- << m_config->ch6OutValue
- << m_config->ch7OutValue;
-
- outSliders << m_config->ch0OutSlider
- << m_config->ch1OutSlider
- << m_config->ch2OutSlider
- << m_config->ch3OutSlider
- << m_config->ch4OutSlider
- << m_config->ch5OutSlider
- << m_config->ch6OutSlider
- << m_config->ch7OutSlider;
-
- outMin << m_config->ch0OutMin
- << m_config->ch1OutMin
- << m_config->ch2OutMin
- << m_config->ch3OutMin
- << m_config->ch4OutMin
- << m_config->ch5OutMin
- << m_config->ch6OutMin
- << m_config->ch7OutMin;
-
- outMax << m_config->ch0OutMax
- << m_config->ch1OutMax
- << m_config->ch2OutMax
- << m_config->ch3OutMax
- << m_config->ch4OutMax
- << m_config->ch5OutMax
- << m_config->ch6OutMax
- << m_config->ch7OutMax;
-
- reversals << m_config->ch0Rev
- << m_config->ch1Rev
- << m_config->ch2Rev
- << m_config->ch3Rev
- << m_config->ch4Rev
- << m_config->ch5Rev
- << m_config->ch6Rev
- << m_config->ch7Rev;
-
- links << m_config->ch0Link
- << m_config->ch1Link
- << m_config->ch2Link
- << m_config->ch3Link
- << m_config->ch4Link
- << m_config->ch5Link
- << m_config->ch6Link
- << m_config->ch7Link;
+ setupButtons(m_config->saveRCOutputToRAM,m_config->saveRCOutputToSD);
+ addUAVObject("ActuatorSettings");
+ // NOTE: we have channel indices from 0 to 9, but the convention for OP is Channel 1 to Channel 10.
// Register for ActuatorSettings changes:
- UAVDataObject * obj = dynamic_cast(objManager->getObject(QString("ActuatorSettings")));
- connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
-
- for (int i = 0; i < 8; i++) {
- connect(outMin[i], SIGNAL(editingFinished()), this, SLOT(setChOutRange()));
- connect(outMax[i], SIGNAL(editingFinished()), this, SLOT(setChOutRange()));
- connect(reversals[i], SIGNAL(toggled(bool)), this, SLOT(reverseChannel(bool)));
- // Now connect the channel out sliders to our signal to send updates in test mode
- connect(outSliders[i], SIGNAL(valueChanged(int)), this, SLOT(sendChannelTest(int)));
+ for (unsigned int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++)
+ {
+ OutputChannelForm *form = new OutputChannelForm(i, this, i==0);
+ connect(m_config->channelOutTest, SIGNAL(toggled(bool)),
+ form, SLOT(enableChannelTest(bool)));
+ connect(form, SIGNAL(channelChanged(int,int)),
+ this, SLOT(sendChannelTest(int,int)));
+ m_config->channelLayout->addWidget(form);
}
connect(m_config->channelOutTest, SIGNAL(toggled(bool)), this, SLOT(runChannelTests(bool)));
- for (int i = 0; i < links.count(); i++)
- links[i]->setChecked(false);
- for (int i = 0; i < links.count(); i++)
- connect(links[i], SIGNAL(toggled(bool)), this, SLOT(linkToggled(bool)));
-
- connect(m_config->saveRCOutputToSD, SIGNAL(clicked()), this, SLOT(saveRCOutputObject()));
- connect(m_config->saveRCOutputToRAM, SIGNAL(clicked()), this, SLOT(sendRCOutputUpdate()));
-
- enableControls(false);
- refreshValues();
- connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
- connect(parent, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()));
+ refreshWidgetsValues();
firstUpdate = true;
@@ -138,6 +81,24 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
// Connect the help button
connect(m_config->outputHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
+ addWidget(m_config->cb_outputRate4);
+ addWidget(m_config->cb_outputRate3);
+ addWidget(m_config->cb_outputRate2);
+ addWidget(m_config->cb_outputRate1);
+ addWidget(m_config->spinningArmed);
+
+ UAVObjectManager *objManager = pm->getObject();
+ UAVObject* obj = objManager->getObject(QString("ActuatorCommand"));
+ if(obj->getMetadata().gcsTelemetryUpdateMode == UAVObject::UPDATEMODE_ONCHANGE)
+ this->setEnabled(false);
+ connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(disableIfNotMe(UAVObject*)));
+}
+void ConfigOutputWidget::enableControls(bool enable)
+{
+ ConfigTaskWidget::enableControls(enable);
+ if(!enable)
+ m_config->channelOutTest->setChecked(false);
+ m_config->channelOutTest->setEnabled(enable);
}
ConfigOutputWidget::~ConfigOutputWidget()
@@ -148,51 +109,29 @@ ConfigOutputWidget::~ConfigOutputWidget()
// ************************************
-void ConfigOutputWidget::enableControls(bool enable)
-{
- m_config->saveRCOutputToSD->setEnabled(enable);
- //m_config->saveRCOutputToRAM->setEnabled(enable);
-}
-
-// ************************************
-
-/**
- Toggles the channel linked state for use in testing mode
- */
-void ConfigOutputWidget::linkToggled(bool state)
-{
- Q_UNUSED(state)
- // find the minimum slider value for the linked ones
- int min = 10000;
- int linked_count = 0;
- for (int i = 0; i < outSliders.count(); i++)
- {
- if (!links[i]->checkState()) continue;
- int value = outSliders[i]->value();
- if (min > value) min = value;
- linked_count++;
- }
-
- if (linked_count <= 0)
- return; // no linked channels
-
- if (!m_config->channelOutTest->checkState())
- return; // we are not in Test Output mode
-
- // set the linked channels to the same value
- for (int i = 0; i < outSliders.count(); i++)
- {
- if (!links[i]->checkState()) continue;
- outSliders[i]->setValue(min);
- }
-}
-
/**
Toggles the channel testing mode by making the GCS take over
the ActuatorCommand objects
*/
void ConfigOutputWidget::runChannelTests(bool state)
{
+ qDebug()<<"configoutputwidget runChannelTests"<getData();
+
+ if(state && systemAlarms.Alarm[SystemAlarms::ALARM_ACTUATOR] != SystemAlarms::ALARM_OK) {
+ QMessageBox mbox;
+ mbox.setText(QString(tr("The actuator module is in an error state. This can also occur because there are no inputs. Please fix these before testing outputs.")));
+ mbox.setStandardButtons(QMessageBox::Ok);
+ mbox.exec();
+
+ // Unfortunately must cache this since callback will reoccur
+ accInitialData = ActuatorCommand::GetInstance(getObjectManager())->getMetadata();
+
+ m_config->channelOutTest->setChecked(false);
+ return;
+ }
+
// Confirm this is definitely what they want
if(state) {
QMessageBox mbox;
@@ -207,79 +146,54 @@ void ConfigOutputWidget::runChannelTests(bool state)
}
}
- qDebug() << "Running with state " << state;
- ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
- UAVObjectManager *objManager = pm->getObject();
-
- UAVDataObject* obj = dynamic_cast(objManager->getObject(QString("ActuatorCommand")));
+ ActuatorCommand * obj = ActuatorCommand::GetInstance(getObjectManager());
UAVObject::Metadata mdata = obj->getMetadata();
if (state)
{
+ wasItMe=true;
accInitialData = mdata;
mdata.flightAccess = UAVObject::ACCESS_READONLY;
mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_ONCHANGE;
mdata.gcsTelemetryAcked = false;
mdata.gcsTelemetryUpdateMode = UAVObject::UPDATEMODE_ONCHANGE;
mdata.gcsTelemetryUpdatePeriod = 100;
-
- // Prevent stupid users from touching the minimum & maximum ranges while
- // moving the sliders. Thanks Ivan for the tip :)
- foreach (QSpinBox* box, outMin) {
- box->setEnabled(false);
- }
- foreach (QSpinBox* box, outMax) {
- box->setEnabled(false);
- }
-
}
else
{
+ wasItMe=false;
mdata = accInitialData; // Restore metadata
- foreach (QSpinBox* box, outMin) {
- box->setEnabled(true);
- }
- foreach (QSpinBox* box, outMax) {
- box->setEnabled(true);
- }
-
}
obj->setMetadata(mdata);
+ obj->updated();
}
+OutputChannelForm* ConfigOutputWidget::getOutputChannelForm(const int index) const
+{
+ QList outputChannelForms = findChildren();
+ foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
+ {
+ if( outputChannelForm->index() == index)
+ return outputChannelForm;
+ }
+
+ // no OutputChannelForm found with given index
+ return NULL;
+}
+
/**
* Set the label for a channel output assignement
*/
void ConfigOutputWidget::assignOutputChannel(UAVDataObject *obj, QString str)
{
+ //FIXME: use signal/ slot approach
UAVObjectField* field = obj->getField(str);
QStringList options = field->getOptions();
- switch (options.indexOf(field->getValue().toString())) {
- case 0:
- m_config->ch0Output->setText(str);
- break;
- case 1:
- m_config->ch1Output->setText(str);
- break;
- case 2:
- m_config->ch2Output->setText(str);
- break;
- case 3:
- m_config->ch3Output->setText(str);
- break;
- case 4:
- m_config->ch4Output->setText(str);
- break;
- case 5:
- m_config->ch5Output->setText(str);
- break;
- case 6:
- m_config->ch6Output->setText(str);
- break;
- case 7:
- m_config->ch7Output->setText(str);
- break;
- }
+ int index = options.indexOf(field->getValue().toString());
+
+ OutputChannelForm *outputChannelForm = getOutputChannelForm(index);
+ if(outputChannelForm)
+ outputChannelForm->setAssignment(str);
}
/**
@@ -287,63 +201,36 @@ void ConfigOutputWidget::assignOutputChannel(UAVDataObject *obj, QString str)
*/
void ConfigOutputWidget::setSpinningArmed(bool val)
{
- UAVDataObject *obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings")));
- if (!obj) return;
- UAVObjectField *field = obj->getField("MotorsSpinWhileArmed");
- if (!field) return;
+ ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
+ Q_ASSERT(actuatorSettings);
+ ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
+
if(val)
- field->setValue("TRUE");
+ actuatorSettingsData.MotorsSpinWhileArmed = ActuatorSettings::MOTORSSPINWHILEARMED_TRUE;
else
- field->setValue("FALSE");
+ actuatorSettingsData.MotorsSpinWhileArmed = ActuatorSettings::MOTORSSPINWHILEARMED_FALSE;
+
+ // Apply settings
+ actuatorSettings->setData(actuatorSettingsData);
}
/**
Sends the channel value to the UAV to move the servo.
Returns immediately if we are not in testing mode
*/
-void ConfigOutputWidget::sendChannelTest(int value)
+void ConfigOutputWidget::sendChannelTest(int index, int value)
{
- int in_value = value;
+ if (!m_config->channelOutTest->isChecked())
+ return;
- QSlider *ob = (QSlider *)QObject::sender();
- if (!ob) return;
- int index = outSliders.indexOf(ob);
- if (index < 0) return;
+ if(index < 0 || (unsigned)index >= ActuatorCommand::CHANNEL_NUMELEM)
+ return;
- if (reversals[index]->isChecked())
- value = outMin[index]->value() - value + outMax[index]->value(); // the chsnnel is reversed
-
- // update the label
- outLabels[index]->setText(QString::number(value));
-
- if (links[index]->checkState())
- { // the channel is linked to other channels
- // set the linked channels to the same value
- for (int i = 0; i < outSliders.count(); i++)
- {
- if (i == index) continue;
- if (!links[i]->checkState()) continue;
-
- int val = in_value;
- if (val < outSliders[i]->minimum()) val = outSliders[i]->minimum();
- if (val > outSliders[i]->maximum()) val = outSliders[i]->maximum();
-
- if (outSliders[i]->value() == val) continue;
-
- outSliders[i]->setValue(val);
- outLabels[i]->setText(QString::number(val));
- }
- }
-
- if (!m_config->channelOutTest->isChecked())
- return;
-
- UAVDataObject *obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorCommand")));
- if (!obj) return;
- UAVObjectField *channel = obj->getField("Channel");
- if (!channel) return;
- channel->setValue(value, index);
- obj->updated();
+ ActuatorCommand *actuatorCommand = ActuatorCommand::GetInstance(getObjectManager());
+ Q_ASSERT(actuatorCommand);
+ ActuatorCommand::DataFields actuatorCommandFields = actuatorCommand->getData();
+ actuatorCommandFields.Channel[index] = value;
+ actuatorCommand->setData(actuatorCommandFields);
}
@@ -355,22 +242,24 @@ void ConfigOutputWidget::sendChannelTest(int value)
/**
Request the current config from the board (RC Output)
*/
-void ConfigOutputWidget::refreshValues()
+void ConfigOutputWidget::refreshWidgetsValues()
{
- ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
- UAVObjectManager *objManager = pm->getObject();
+ bool dirty=isDirty();
// Reset all channel assignements:
- m_config->ch0Output->setText("-");
- m_config->ch1Output->setText("-");
- m_config->ch2Output->setText("-");
- m_config->ch3Output->setText("-");
- m_config->ch4Output->setText("-");
- m_config->ch5Output->setText("-");
- m_config->ch6Output->setText("-");
- m_config->ch7Output->setText("-");
+ QList outputChannelForms = findChildren();
+ foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
+ {
+ outputChannelForm->setAssignment("-");
+ }
- // Get the channel assignements:
+ // FIXME: Use static accessor method for retrieving channel assignments
+ ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
+ Q_ASSERT(pm);
+ UAVObjectManager *objManager = pm->getObject();
+ Q_ASSERT(objManager);
+
+ // Get the channel assignements:
UAVDataObject * obj = dynamic_cast(objManager->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
QList fieldList = obj->getFields();
@@ -380,197 +269,104 @@ void ConfigOutputWidget::refreshValues()
}
}
+ ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
+ Q_ASSERT(actuatorSettings);
+ ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
+
// Get the SpinWhileArmed setting
- UAVObjectField *field = obj->getField(QString("MotorsSpinWhileArmed"));
- m_config->spinningArmed->setChecked(field->getValue().toString().contains("TRUE"));
+ m_config->spinningArmed->setChecked(actuatorSettingsData.MotorsSpinWhileArmed == ActuatorSettings::MOTORSSPINWHILEARMED_TRUE);
// Get Output rates for both banks
- field = obj->getField(QString("ChannelUpdateFreq"));
+ if(m_config->cb_outputRate1->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[0]))==-1)
+ {
+ m_config->cb_outputRate1->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[0]));
+ }
+ if(m_config->cb_outputRate2->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[1]))==-1)
+ {
+ m_config->cb_outputRate2->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[1]));
+ }
+ m_config->cb_outputRate1->setCurrentIndex(m_config->cb_outputRate1->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[0])));
+ m_config->cb_outputRate2->setCurrentIndex(m_config->cb_outputRate2->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[1])));
+
UAVObjectUtilManager* utilMngr = pm->getObject();
- m_config->outputRate1->setValue(field->getValue(0).toInt());
- m_config->outputRate2->setValue(field->getValue(1).toInt());
if (utilMngr) {
int board = utilMngr->getBoardModel();
if ((board & 0xff00) == 1024) {
// CopterControl family
m_config->chBank1->setText("1-3");
m_config->chBank2->setText("4");
- m_config->chBank3->setText("5");
- m_config->chBank4->setText("6");
- m_config->outputRate1->setEnabled(true);
- m_config->outputRate2->setEnabled(true);
- m_config->outputRate3->setEnabled(true);
- m_config->outputRate4->setEnabled(true);
- m_config->outputRate3->setValue(field->getValue(2).toInt());
- m_config->outputRate4->setValue(field->getValue(3).toInt());
+ m_config->chBank3->setText("5,7-8");
+ m_config->chBank4->setText("6,9-10");
+ m_config->cb_outputRate1->setEnabled(true);
+ m_config->cb_outputRate2->setEnabled(true);
+ m_config->cb_outputRate3->setEnabled(true);
+ m_config->cb_outputRate4->setEnabled(true);
+ if(m_config->cb_outputRate3->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[2]))==-1)
+ {
+ m_config->cb_outputRate3->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[2]));
+ }
+ if(m_config->cb_outputRate4->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[3]))==-1)
+ {
+ m_config->cb_outputRate4->addItem(QString::number(actuatorSettingsData.ChannelUpdateFreq[3]));
+ }
+ m_config->cb_outputRate3->setCurrentIndex(m_config->cb_outputRate3->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[2])));
+ m_config->cb_outputRate4->setCurrentIndex(m_config->cb_outputRate4->findText(QString::number(actuatorSettingsData.ChannelUpdateFreq[3])));
} else if ((board & 0xff00) == 256 ) {
// Mainboard family
- m_config->outputRate1->setEnabled(true);
- m_config->outputRate2->setEnabled(true);
- m_config->outputRate3->setEnabled(false);
- m_config->outputRate4->setEnabled(false);
+ m_config->cb_outputRate1->setEnabled(true);
+ m_config->cb_outputRate2->setEnabled(true);
+ m_config->cb_outputRate3->setEnabled(false);
+ m_config->cb_outputRate4->setEnabled(false);
m_config->chBank1->setText("1-4");
m_config->chBank2->setText("5-8");
m_config->chBank3->setText("-");
m_config->chBank4->setText("-");
- m_config->outputRate3->setValue(0);
- m_config->outputRate4->setValue(0);
+ m_config->cb_outputRate3->addItem("0");
+ m_config->cb_outputRate3->setCurrentIndex(m_config->cb_outputRate3->findText("0"));
+ m_config->cb_outputRate4->addItem("0");
+ m_config->cb_outputRate4->setCurrentIndex(m_config->cb_outputRate4->findText("0"));
}
}
-
// Get Channel ranges:
- for (int i=0;i<8;i++) {
- field = obj->getField(QString("ChannelMin"));
- int minValue = field->getValue(i).toInt();
- outMin[i]->setValue(minValue);
- field = obj->getField(QString("ChannelMax"));
- int maxValue = field->getValue(i).toInt();
- outMax[i]->setValue(maxValue);
- if (maxValue>minValue) {
- outSliders[i]->setMinimum(minValue);
- outSliders[i]->setMaximum(maxValue);
- reversals[i]->setChecked(false);
- } else {
- outSliders[i]->setMinimum(maxValue);
- outSliders[i]->setMaximum(minValue);
- reversals[i]->setChecked(true);
- }
+ foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
+ {
+ int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()];
+ int maxValue = actuatorSettingsData.ChannelMax[outputChannelForm->index()];
+ outputChannelForm->minmax(minValue, maxValue);
+
+ int neutral = actuatorSettingsData.ChannelNeutral[outputChannelForm->index()];
+ outputChannelForm->neutral(neutral);
}
- field = obj->getField(QString("ChannelNeutral"));
- for (int i=0; i<8; i++) {
- int value = field->getValue(i).toInt();
- outSliders[i]->setValue(value);
- outLabels[i]->setText(QString::number(value));
- }
-
-
+ setDirty(dirty);
}
/**
* Sends the config to the board, without saving to the SD card (RC Output)
*/
-void ConfigOutputWidget::sendRCOutputUpdate()
+void ConfigOutputWidget::updateObjectsFromWidgets()
{
- ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
- UAVObjectManager *objManager = pm->getObject();
- UAVDataObject* obj = dynamic_cast(objManager->getObject(QString("ActuatorSettings")));
- Q_ASSERT(obj);
+ ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
+ Q_ASSERT(actuatorSettings);
+ ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
- // Now send channel ranges:
- UAVObjectField * field = obj->getField(QString("ChannelMax"));
- for (int i = 0; i < 8; i++) {
- field->setValue(outMax[i]->value(),i);
- }
-
- field = obj->getField(QString("ChannelMin"));
- for (int i = 0; i < 8; i++) {
- field->setValue(outMin[i]->value(),i);
- }
-
- field = obj->getField(QString("ChannelNeutral"));
- for (int i = 0; i < 8; i++) {
- field->setValue(outSliders[i]->value(),i);
- }
-
- field = obj->getField(QString("ChannelUpdateFreq"));
- field->setValue(m_config->outputRate1->value(),0);
- field->setValue(m_config->outputRate2->value(),1);
- field->setValue(m_config->outputRate3->value(),2);
- field->setValue(m_config->outputRate4->value(),3);
-
- // ... and send to the OP Board
- obj->updated();
-
-}
-
-
-/**
- Sends the config to the board and request saving into the SD card (RC Output)
- */
-void ConfigOutputWidget::saveRCOutputObject()
-{
- // Send update so that the latest value is saved
- sendRCOutputUpdate();
- UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("ActuatorSettings")));
- Q_ASSERT(obj);
- saveObjectToSD(obj);
-
-}
-
-
-/**
- Sets the minimum/maximum value of the channel 0 to seven output sliders.
- Have to do it here because setMinimum is not a slot.
-
- One added trick: if the slider is at its min when the value
- is changed, then keep it on the min.
- */
-void ConfigOutputWidget::setChOutRange()
-{
- QSpinBox *spinbox = (QSpinBox*)QObject::sender();
-
- int index = outMin.indexOf(spinbox); // This is the channel number
- if (index < 0)
- index = outMax.indexOf(spinbox); // We can't know if the signal came from min or max
-
- QSlider *slider = outSliders[index];
-
- int oldMini = slider->minimum();
-// int oldMaxi = slider->maximum();
-
- if (outMin[index]->value()value())
+ // Set channel ranges
+ QList outputChannelForms = findChildren();
+ foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
- slider->setRange(outMin[index]->value(), outMax[index]->value());
- reversals[index]->setChecked(false);
- }
- else
- {
- slider->setRange(outMax[index]->value(), outMin[index]->value());
- reversals[index]->setChecked(true);
- }
-
- if (slider->value() == oldMini)
- slider->setValue(slider->minimum());
-
-// if (slider->value() == oldMaxi)
-// slider->setValue(slider->maximum()); // this can be dangerous if it happens to be controlling a motor at the time!
-}
-
-/**
- Reverses the channel when the checkbox is clicked
- */
-void ConfigOutputWidget::reverseChannel(bool state)
-{
- QCheckBox *checkbox = (QCheckBox*)QObject::sender();
- int index = reversals.indexOf(checkbox); // This is the channel number
-
- // Sanity check: if state became true, make sure the Maxvalue was higher than Minvalue
- // the situations below can happen!
- if (state && (outMax[index]->value()value()))
- return;
- if (!state && (outMax[index]->value()>outMin[index]->value()))
- return;
-
- // Now, swap the min & max values (only on the spinboxes, the slider
- // does not change!
- int temp = outMax[index]->value();
- outMax[index]->setValue(outMin[index]->value());
- outMin[index]->setValue(temp);
-
- // Also update the channel value
- // This is a trick to force the slider to update its value and
- // emit the right signal itself, because our sendChannelTest(int) method
- // relies on the object sender's identity.
- if (outSliders[index]->value()maximum()) {
- outSliders[index]->setValue(outSliders[index]->value()+1);
- outSliders[index]->setValue(outSliders[index]->value()-1);
- } else {
- outSliders[index]->setValue(outSliders[index]->value()-1);
- outSliders[index]->setValue(outSliders[index]->value()+1);
+ actuatorSettingsData.ChannelMax[outputChannelForm->index()] = outputChannelForm->max();
+ actuatorSettingsData.ChannelMin[outputChannelForm->index()] = outputChannelForm->min();
+ actuatorSettingsData.ChannelNeutral[outputChannelForm->index()] = outputChannelForm->neutral();
}
+ // Set update rates
+ actuatorSettingsData.ChannelUpdateFreq[0] = m_config->cb_outputRate1->currentText().toUInt();
+ actuatorSettingsData.ChannelUpdateFreq[1] = m_config->cb_outputRate2->currentText().toUInt();
+ actuatorSettingsData.ChannelUpdateFreq[2] = m_config->cb_outputRate3->currentText().toUInt();
+ actuatorSettingsData.ChannelUpdateFreq[3] = m_config->cb_outputRate4->currentText().toUInt();
+ // Apply settings
+ actuatorSettings->setData(actuatorSettingsData);
}
void ConfigOutputWidget::openHelp()
@@ -579,4 +375,18 @@ void ConfigOutputWidget::openHelp()
QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/display/Doc/Output+Configuration", QUrl::StrictMode) );
}
+void ConfigOutputWidget::stopTests()
+{
+ m_config->channelOutTest->setChecked(false);
+}
+void ConfigOutputWidget::disableIfNotMe(UAVObject* obj)
+{
+ if(obj->getMetadata().gcsTelemetryUpdateMode == UAVObject::UPDATEMODE_ONCHANGE)
+ {
+ if(!wasItMe)
+ this->setEnabled(false);
+ }
+ else
+ this->setEnabled(true);
+}
diff --git a/ground/openpilotgcs/src/plugins/config/configoutputwidget.h b/ground/openpilotgcs/src/plugins/config/configoutputwidget.h
index 2a197e3ac..76dc51658 100644
--- a/ground/openpilotgcs/src/plugins/config/configoutputwidget.h
+++ b/ground/openpilotgcs/src/plugins/config/configoutputwidget.h
@@ -1,13 +1,13 @@
/**
******************************************************************************
*
- * @file configservowidget.h
+ * @file configoutputwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
- * @brief Servo input/output configuration panel for the config gadget
+ * @brief Servo output configuration panel for the config gadget
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@@ -37,6 +37,7 @@
#include
class Ui_OutputWidget;
+class OutputChannelForm;
class ConfigOutputWidget: public ConfigTaskWidget
{
@@ -46,6 +47,7 @@ public:
ConfigOutputWidget(QWidget *parent = 0);
~ConfigOutputWidget();
+
private:
Ui_OutputWidget *m_config;
@@ -55,33 +57,26 @@ private:
void assignChannel(UAVDataObject *obj, QString str);
void assignOutputChannel(UAVDataObject *obj, QString str);
+ OutputChannelForm* getOutputChannelForm(const int index) const;
int mccDataRate;
UAVObject::Metadata accInitialData;
- QList outSliders;
- QList