2011-02-08 17:49:33 +01:00
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
*
|
|
|
|
* @file configservowidget.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
|
|
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
2011-02-27 20:20:43 +01:00
|
|
|
|
2011-03-28 17:39:22 +02:00
|
|
|
#include "configinputwidget.h"
|
2011-02-08 17:49:33 +01:00
|
|
|
|
2011-02-27 20:20:43 +01:00
|
|
|
#include "uavtalk/telemetrymanager.h"
|
|
|
|
|
2011-02-08 17:49:33 +01:00
|
|
|
#include <QDebug>
|
|
|
|
#include <QStringList>
|
|
|
|
#include <QtGui/QWidget>
|
|
|
|
#include <QtGui/QTextEdit>
|
|
|
|
#include <QtGui/QVBoxLayout>
|
|
|
|
#include <QtGui/QPushButton>
|
2011-05-31 09:16:01 +02:00
|
|
|
#include <QDesktopServices>
|
|
|
|
#include <QUrl>
|
2011-06-13 12:14:40 +02:00
|
|
|
#include <QMessageBox>
|
2011-02-08 17:49:33 +01:00
|
|
|
|
2011-06-08 00:35:21 +02:00
|
|
|
#include "manualcontrolsettings.h"
|
|
|
|
|
2011-03-28 17:39:22 +02:00
|
|
|
ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent)
|
2011-02-08 17:49:33 +01:00
|
|
|
{
|
2011-03-28 17:39:22 +02:00
|
|
|
m_config = new Ui_InputWidget();
|
2011-02-08 17:49:33 +01:00
|
|
|
m_config->setupUi(this);
|
|
|
|
|
2011-06-07 16:56:16 +02:00
|
|
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
|
|
|
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
2011-02-27 20:20:43 +01:00
|
|
|
|
|
|
|
// First of all, put all the channel widgets into lists, so that we can
|
2011-02-08 17:49:33 +01:00
|
|
|
// manipulate those:
|
|
|
|
|
|
|
|
|
2011-02-25 21:43:58 +01:00
|
|
|
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;
|
|
|
|
|
2011-02-28 17:44:04 +01:00
|
|
|
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;
|
|
|
|
|
2011-04-03 08:47:07 +02:00
|
|
|
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;
|
|
|
|
|
2011-06-08 22:15:10 +02:00
|
|
|
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;
|
2011-04-03 08:47:07 +02:00
|
|
|
|
2011-02-08 17:49:33 +01:00
|
|
|
// Now connect the widget to the ManualControlCommand / Channel UAVObject
|
|
|
|
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlCommand")));
|
|
|
|
connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateChannels(UAVObject*)));
|
|
|
|
|
2011-06-05 18:40:52 +02:00
|
|
|
// Register for ManualControlSettings changes:
|
|
|
|
obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings")));
|
2011-06-07 16:56:16 +02:00
|
|
|
connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
2011-06-05 18:40:52 +02:00
|
|
|
|
|
|
|
|
2011-02-08 17:49:33 +01:00
|
|
|
// Get the receiver types supported by OpenPilot and fill the corresponding
|
|
|
|
// dropdown menu:
|
|
|
|
obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings")));
|
2011-07-26 22:44:59 +02:00
|
|
|
UAVObjectField * field;
|
2011-02-08 17:49:33 +01:00
|
|
|
// Fill in the dropdown menus for the channel RC Input assignement.
|
|
|
|
QStringList channelsList;
|
|
|
|
channelsList << "None";
|
|
|
|
QList<UAVObjectField*> fieldList = obj->getFields();
|
|
|
|
foreach (UAVObjectField* field, fieldList) {
|
|
|
|
if (field->getUnits().contains("channel")) {
|
|
|
|
channelsList.append(field->getName());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
// And the flight mode settings:
|
2011-03-02 02:25:47 +01:00
|
|
|
field = obj->getField(QString("FlightModePosition"));
|
2011-02-08 17:49:33 +01:00
|
|
|
m_config->fmsModePos1->addItems(field->getOptions());
|
|
|
|
m_config->fmsModePos2->addItems(field->getOptions());
|
|
|
|
m_config->fmsModePos3->addItems(field->getOptions());
|
2011-03-02 02:25:47 +01:00
|
|
|
field = obj->getField(QString("Stabilization1Settings"));
|
2011-02-08 17:49:33 +01:00
|
|
|
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);
|
|
|
|
|
|
|
|
// And the Armin configurations:
|
|
|
|
field = obj->getField(QString("Arming"));
|
|
|
|
m_config->armControl->clear();
|
|
|
|
m_config->armControl->addItems(field->getOptions());
|
|
|
|
|
|
|
|
|
|
|
|
connect(m_config->saveRCInputToSD, SIGNAL(clicked()), this, SLOT(saveRCInputObject()));
|
|
|
|
connect(m_config->saveRCInputToRAM, SIGNAL(clicked()), this, SLOT(sendRCInputUpdate()));
|
|
|
|
|
2011-06-07 16:56:16 +02:00
|
|
|
enableControls(false);
|
|
|
|
refreshValues();
|
|
|
|
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
|
|
|
|
connect(parent, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()));
|
2011-02-08 17:49:33 +01:00
|
|
|
|
2011-04-03 08:47:07 +02:00
|
|
|
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)));
|
2011-06-21 19:58:46 +02:00
|
|
|
connect(m_config->doRCInputCalibration,SIGNAL(stateChanged(int)),this,SLOT(updateTips(int)));
|
2011-02-08 17:49:33 +01:00
|
|
|
firstUpdate = true;
|
|
|
|
|
2011-05-31 09:16:01 +02:00
|
|
|
// Connect the help button
|
|
|
|
connect(m_config->inputHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
|
2011-06-21 20:14:39 +02:00
|
|
|
updateTips(Qt::Unchecked);
|
2011-06-20 15:28:16 +02:00
|
|
|
|
2011-02-08 17:49:33 +01:00
|
|
|
}
|
|
|
|
|
2011-03-28 17:39:22 +02:00
|
|
|
ConfigInputWidget::~ConfigInputWidget()
|
2011-02-08 17:49:33 +01:00
|
|
|
{
|
|
|
|
// Do nothing
|
|
|
|
}
|
|
|
|
|
2011-04-03 08:47:07 +02:00
|
|
|
/**
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-27 20:20:43 +01:00
|
|
|
|
|
|
|
// ************************************
|
|
|
|
|
2011-06-05 18:40:52 +02:00
|
|
|
/*
|
|
|
|
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)
|
|
|
|
*/
|
2011-03-28 17:39:22 +02:00
|
|
|
void ConfigInputWidget::enableControls(bool enable)
|
2011-02-27 20:20:43 +01:00
|
|
|
{
|
2011-06-07 16:56:16 +02:00
|
|
|
//m_config->saveRCInputToRAM->setEnabled(enable);
|
2011-02-27 20:20:43 +01:00
|
|
|
m_config->saveRCInputToSD->setEnabled(enable);
|
2011-02-27 20:52:03 +01:00
|
|
|
m_config->doRCInputCalibration->setEnabled(enable);
|
2011-02-27 20:20:43 +01:00
|
|
|
}
|
2011-02-08 17:49:33 +01:00
|
|
|
|
|
|
|
|
|
|
|
/********************************
|
|
|
|
* Input settings
|
|
|
|
*******************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
Request the current config from the board
|
|
|
|
*/
|
2011-06-07 16:56:16 +02:00
|
|
|
void ConfigInputWidget::refreshValues()
|
2011-02-08 17:49:33 +01:00
|
|
|
{
|
|
|
|
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ManualControlSettings")));
|
|
|
|
Q_ASSERT(obj);
|
2011-06-05 18:40:52 +02:00
|
|
|
//obj->requestUpdate();
|
2011-04-03 08:47:07 +02:00
|
|
|
UAVObjectField *field;
|
2011-02-08 17:49:33 +01:00
|
|
|
|
2011-02-25 21:43:58 +01:00
|
|
|
// Now update all the slider values:
|
2011-02-08 17:49:33 +01:00
|
|
|
|
2011-04-03 08:47:07 +02:00
|
|
|
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());
|
|
|
|
}
|
2011-02-08 17:49:33 +01:00
|
|
|
|
|
|
|
// Update receiver type
|
2011-04-03 08:47:07 +02:00
|
|
|
field = obj->getField(QString("InputMode"));
|
2011-07-26 00:18:41 +02:00
|
|
|
m_config->receiverType->setText(field->getValue().toString());
|
2011-02-08 17:49:33 +01:00
|
|
|
|
|
|
|
// Reset all channel assignement dropdowns:
|
2011-06-08 22:15:10 +02:00
|
|
|
foreach (QComboBox *combo, inChannelAssign) {
|
|
|
|
combo->setCurrentIndex(0);
|
|
|
|
}
|
2011-02-08 17:49:33 +01:00
|
|
|
|
|
|
|
// Update all channels assignements
|
2011-04-03 08:47:07 +02:00
|
|
|
QList<UAVObjectField *> fieldList = obj->getFields();
|
|
|
|
foreach (UAVObjectField *field, fieldList) {
|
|
|
|
if (field->getUnits().contains("channel"))
|
2011-02-08 17:49:33 +01:00
|
|
|
assignChannel(obj, field->getName());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update all the flight mode settingsin the relevant tab
|
2011-03-02 02:25:47 +01:00
|
|
|
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"));
|
2011-02-25 21:43:58 +01:00
|
|
|
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()));
|
2011-03-02 02:25:47 +01:00
|
|
|
field = obj->getField(QString("Stabilization2Settings"));
|
2011-02-25 21:43:58 +01:00
|
|
|
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()));
|
2011-03-02 02:25:47 +01:00
|
|
|
field = obj->getField(QString("Stabilization3Settings"));
|
2011-02-25 21:43:58 +01:00
|
|
|
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()));
|
2011-02-08 17:49:33 +01:00
|
|
|
|
|
|
|
// 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
|
|
|
|
*/
|
2011-03-28 17:39:22 +02:00
|
|
|
void ConfigInputWidget::sendRCInputUpdate()
|
2011-02-08 17:49:33 +01:00
|
|
|
{
|
|
|
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
|
|
|
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
|
|
|
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings")));
|
|
|
|
Q_ASSERT(obj);
|
|
|
|
// Now update all fields from the sliders:
|
|
|
|
QString fieldName = QString("ChannelMax");
|
|
|
|
UAVObjectField * field = obj->getField(fieldName);
|
2011-04-03 08:47:07 +02:00
|
|
|
for (int i = 0; i < 8; i++) {
|
|
|
|
field->setValue(inMaxLabels[i]->text().toInt(), i);
|
|
|
|
}
|
2011-02-08 17:49:33 +01:00
|
|
|
|
|
|
|
fieldName = QString("ChannelMin");
|
|
|
|
field = obj->getField(fieldName);
|
2011-04-03 08:47:07 +02:00
|
|
|
for (int i = 0; i < 8; i++) {
|
|
|
|
field->setValue(inMinLabels[i]->text().toInt(), i);
|
|
|
|
}
|
2011-02-08 17:49:33 +01:00
|
|
|
|
|
|
|
fieldName = QString("ChannelNeutral");
|
|
|
|
field = obj->getField(fieldName);
|
2011-04-03 08:47:07 +02:00
|
|
|
for (int i = 0; i < 8; i++)
|
|
|
|
field->setValue(inSliders[i]->value(), i);
|
2011-02-08 17:49:33 +01:00
|
|
|
|
|
|
|
// 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<UAVObjectField*> 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
|
2011-03-02 02:25:47 +01:00
|
|
|
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"));
|
2011-02-08 17:49:33 +01:00
|
|
|
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"));
|
2011-03-02 02:25:47 +01:00
|
|
|
field = obj->getField(QString("Stabilization2Settings"));
|
2011-02-08 17:49:33 +01:00
|
|
|
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"));
|
2011-03-02 02:25:47 +01:00
|
|
|
field = obj->getField(QString("Stabilization3Settings"));
|
2011-02-08 17:49:33 +01:00
|
|
|
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
|
|
|
|
*/
|
2011-03-28 17:39:22 +02:00
|
|
|
void ConfigInputWidget::saveRCInputObject()
|
2011-02-08 17:49:33 +01:00
|
|
|
{
|
|
|
|
// Send update so that the latest value is saved
|
|
|
|
sendRCInputUpdate();
|
2011-06-02 16:08:19 +02:00
|
|
|
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ManualControlSettings")));
|
2011-02-08 17:49:33 +01:00
|
|
|
Q_ASSERT(obj);
|
2011-06-02 16:08:19 +02:00
|
|
|
saveObjectToSD(obj);
|
2011-02-08 17:49:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the dropdown option for a channel Input assignement
|
|
|
|
*/
|
2011-03-28 17:39:22 +02:00
|
|
|
void ConfigInputWidget::assignChannel(UAVDataObject *obj, QString str)
|
2011-02-08 17:49:33 +01:00
|
|
|
{
|
|
|
|
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
|
|
|
|
*
|
|
|
|
*/
|
2011-03-28 17:39:22 +02:00
|
|
|
void ConfigInputWidget::updateChannels(UAVObject* controlCommand)
|
2011-02-08 17:49:33 +01:00
|
|
|
{
|
|
|
|
|
|
|
|
QString fieldName = QString("Connected");
|
|
|
|
UAVObjectField *field = controlCommand->getField(fieldName);
|
2011-04-03 08:47:07 +02:00
|
|
|
if (field->getValue().toBool())
|
2011-06-21 19:58:46 +02:00
|
|
|
{
|
2011-04-30 01:00:20 +02:00
|
|
|
m_config->RCInputConnected->setText("RC Receiver connected");
|
2011-06-21 19:58:46 +02:00
|
|
|
m_config->lblMissingInputs->setText("");
|
|
|
|
}
|
2011-04-03 08:47:07 +02:00
|
|
|
else
|
2011-06-21 19:58:46 +02:00
|
|
|
{
|
2011-04-30 01:00:20 +02:00
|
|
|
m_config->RCInputConnected->setText("RC Receiver not connected or invalid input configuration (missing channels)");
|
2011-06-21 19:58:46 +02:00
|
|
|
receiverHelp();
|
|
|
|
}
|
2011-04-03 08:47:07 +02:00
|
|
|
if (m_config->doRCInputCalibration->isChecked()) {
|
|
|
|
if (firstUpdate) {
|
2011-06-08 19:21:43 +02:00
|
|
|
// 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);
|
2011-02-13 20:10:29 +01:00
|
|
|
|
2011-06-08 19:21:43 +02:00
|
|
|
// Also protect the user by setting all values to zero
|
|
|
|
// and making the ActuatorCommand object readonly
|
|
|
|
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(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);
|
2011-02-13 20:10:29 +01:00
|
|
|
}
|
2011-06-08 19:21:43 +02:00
|
|
|
obj->updated();
|
2011-06-08 22:15:10 +02:00
|
|
|
|
2011-06-13 12:14:40 +02:00
|
|
|
// OP-534: make sure the airframe can NEVER arm
|
|
|
|
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ManualControlSettings")));
|
|
|
|
field = obj->getField("Arming");
|
|
|
|
field->setValue("Always Disarmed");
|
|
|
|
obj->updated();
|
|
|
|
|
2011-06-08 22:15:10 +02:00
|
|
|
// Last, make sure the user won't apply/save during calibration
|
|
|
|
m_config->saveRCInputToRAM->setEnabled(false);
|
|
|
|
m_config->saveRCInputToSD->setEnabled(false);
|
2011-06-13 12:14:40 +02:00
|
|
|
|
|
|
|
// 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();
|
|
|
|
|
2011-06-08 19:21:43 +02:00
|
|
|
}
|
2011-02-25 21:43:58 +01:00
|
|
|
|
2011-04-03 08:47:07 +02:00
|
|
|
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());
|
2011-06-08 19:21:43 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!firstUpdate) {
|
2011-02-08 17:49:33 +01:00
|
|
|
// Restore original data rate from the board:
|
|
|
|
UAVObject::Metadata mdata = controlCommand->getMetadata();
|
|
|
|
mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
|
|
|
|
mdata.flightTelemetryUpdatePeriod = mccDataRate;
|
|
|
|
controlCommand->setMetadata(mdata);
|
2011-02-13 20:10:29 +01:00
|
|
|
|
|
|
|
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorCommand")));
|
|
|
|
mdata = obj->getMetadata();
|
|
|
|
mdata.flightAccess = UAVObject::ACCESS_READWRITE;
|
|
|
|
obj->setMetadata(mdata);
|
2011-06-08 19:21:43 +02:00
|
|
|
|
|
|
|
// Set some slider values to better defaults
|
2011-06-19 18:37:22 +02:00
|
|
|
// Find some channels first
|
2011-06-08 22:15:10 +02:00
|
|
|
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;
|
|
|
|
}
|
2011-06-08 19:21:43 +02:00
|
|
|
}
|
2011-06-08 22:15:10 +02:00
|
|
|
|
|
|
|
// Throttle neutral defaults to 2% of range
|
|
|
|
if (throttleChannel > -1) {
|
2011-06-19 18:37:22 +02:00
|
|
|
inSliders.at(throttleChannel)->setValue(
|
|
|
|
inSliders.at(throttleChannel)->minimum() +
|
|
|
|
(inSliders.at(throttleChannel)->maximum()-
|
|
|
|
inSliders.at(throttleChannel)->minimum())*0.02);
|
2011-06-08 22:15:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
2011-06-08 19:21:43 +02:00
|
|
|
}
|
2011-06-08 22:15:10 +02:00
|
|
|
|
|
|
|
m_config->saveRCInputToRAM->setEnabled(true);
|
|
|
|
m_config->saveRCInputToSD->setEnabled(true);
|
2011-02-08 17:49:33 +01:00
|
|
|
}
|
|
|
|
firstUpdate = true;
|
|
|
|
}
|
2011-06-08 00:35:21 +02:00
|
|
|
|
2011-02-08 17:49:33 +01:00
|
|
|
//Update the Flight mode channel slider
|
2011-06-08 00:35:21 +02:00
|
|
|
ManualControlSettings * manualSettings = ManualControlSettings::GetInstance(getObjectManager());
|
|
|
|
ManualControlSettings::DataFields manualSettingsData = manualSettings->getData();
|
|
|
|
uint chIndex = manualSettingsData.FlightMode;
|
2011-06-08 19:01:47 +02:00
|
|
|
if (chIndex < manualSettings->FLIGHTMODE_NONE) {
|
2011-04-03 08:47:07 +02:00
|
|
|
float valueScaled;
|
|
|
|
|
2011-06-08 00:35:21 +02:00
|
|
|
int chMin = manualSettingsData.ChannelMin[chIndex];
|
|
|
|
int chMax = manualSettingsData.ChannelMax[chIndex];
|
|
|
|
int chNeutral = manualSettingsData.ChannelNeutral[chIndex];
|
2011-04-03 08:47:07 +02:00
|
|
|
|
|
|
|
int value = controlCommand->getField("Channel")->getValue(chIndex).toInt();
|
|
|
|
if ((chMax > chMin && value >= chNeutral) || (chMin > chMax && value <= chNeutral))
|
|
|
|
{
|
2011-06-08 19:21:43 +02:00
|
|
|
if (chMax != chNeutral)
|
|
|
|
valueScaled = (float)(value - chNeutral) / (float)(chMax - chNeutral);
|
|
|
|
else
|
|
|
|
valueScaled = 0;
|
2011-04-03 08:47:07 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-06-08 19:21:43 +02:00
|
|
|
if (chMin != chNeutral)
|
|
|
|
valueScaled = (float)(value - chNeutral) / (float)(chNeutral - chMin);
|
|
|
|
else
|
|
|
|
valueScaled = 0;
|
2011-02-08 17:49:33 +01:00
|
|
|
}
|
2011-02-25 21:43:58 +01:00
|
|
|
|
2011-06-08 00:04:36 +02:00
|
|
|
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);
|
2011-02-08 17:49:33 +01:00
|
|
|
|
2011-06-08 19:21:43 +02:00
|
|
|
}
|
2011-02-25 21:43:58 +01:00
|
|
|
}
|
2011-02-08 17:49:33 +01:00
|
|
|
|
2011-04-03 08:47:07 +02:00
|
|
|
void ConfigInputWidget::updateChannelInSlider(QSlider *slider, QLabel *min, QLabel *max, int value, bool reversed)
|
2011-02-28 17:44:04 +01:00
|
|
|
{
|
2011-04-03 08:47:07 +02:00
|
|
|
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;
|
|
|
|
}
|
2011-02-28 17:44:04 +01:00
|
|
|
|
2011-04-03 08:47:07 +02:00
|
|
|
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);
|
|
|
|
}
|
2011-02-28 17:44:04 +01:00
|
|
|
}
|
2011-05-31 09:16:01 +02:00
|
|
|
|
|
|
|
void ConfigInputWidget::openHelp()
|
|
|
|
{
|
|
|
|
|
|
|
|
QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/display/Doc/Input+Configuration", QUrl::StrictMode) );
|
|
|
|
}
|
2011-06-20 15:28:16 +02:00
|
|
|
void ConfigInputWidget::receiverHelp()
|
|
|
|
{
|
|
|
|
QString unassigned;
|
|
|
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
|
|
|
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
|
|
|
UAVDataObject* controlCommand = dynamic_cast<UAVDataObject*>(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)
|
2011-06-22 11:11:19 +02:00
|
|
|
unassigned.append(", ");
|
2011-06-20 15:28:16 +02:00
|
|
|
unassigned.append("Pitch");
|
|
|
|
}
|
|
|
|
|
|
|
|
field =controlCommand->getField("Yaw");
|
|
|
|
if(field->getValue().toString()=="None")
|
|
|
|
{
|
|
|
|
if(unassigned.length()>0)
|
2011-06-22 11:11:19 +02:00
|
|
|
unassigned.append(", ");
|
2011-06-20 15:28:16 +02:00
|
|
|
unassigned.append("Yaw");
|
|
|
|
}
|
|
|
|
|
|
|
|
field =controlCommand->getField("Throttle");
|
|
|
|
if(field->getValue().toString()=="None")
|
|
|
|
{
|
|
|
|
if(unassigned.length()>0)
|
2011-06-22 11:11:19 +02:00
|
|
|
unassigned.append(", ");
|
2011-06-20 15:28:16 +02:00
|
|
|
unassigned.append("Throttle");
|
|
|
|
}
|
2011-05-31 09:16:01 +02:00
|
|
|
|
2011-06-20 15:28:16 +02:00
|
|
|
field =controlCommand->getField("FlightMode");
|
|
|
|
if(field->getValue().toString()=="None")
|
|
|
|
{
|
|
|
|
if(unassigned.length()>0)
|
2011-06-22 11:11:19 +02:00
|
|
|
unassigned.append(", ");
|
2011-06-20 15:28:16 +02:00
|
|
|
unassigned.append("FlightMode");
|
|
|
|
}
|
|
|
|
if(unassigned.length()>0)
|
2011-07-28 22:26:07 +02:00
|
|
|
m_config->lblMissingInputs->setText(QString("Channels left to assign: ")+unassigned);
|
2011-06-20 15:28:16 +02:00
|
|
|
else
|
2011-06-21 19:58:46 +02:00
|
|
|
m_config->lblMissingInputs->setText("");
|
|
|
|
}
|
|
|
|
void ConfigInputWidget::updateTips(int value)
|
|
|
|
{
|
|
|
|
if(value==Qt::Checked)
|
|
|
|
{
|
|
|
|
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");
|
|
|
|
}
|
|
|
|
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");
|
|
|
|
}
|
2011-06-20 15:28:16 +02:00
|
|
|
}
|