mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-29 14:52:12 +01:00
Merged in f5soh/librepilot/LP-551_Tx_Wizard_output (pull request #488)
LP-551 Tx Wizard output Approved-by: Lalanne Laurent <f5soh@free.fr> Approved-by: Philippe Renon <philippe_renon@yahoo.fr>
This commit is contained in:
commit
b0e309356c
@ -98,6 +98,7 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
|
||||
widget = new ConfigInputWidget(this);
|
||||
static_cast<ConfigTaskWidget *>(widget)->bind();
|
||||
stackWidget->insertTab(ConfigGadgetWidget::Input, widget, *icon, QString("Input"));
|
||||
QWidget *inputWidget = widget;
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/output_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
@ -105,6 +106,7 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
|
||||
widget = new ConfigOutputWidget(this);
|
||||
static_cast<ConfigTaskWidget *>(widget)->bind();
|
||||
stackWidget->insertTab(ConfigGadgetWidget::Output, widget, *icon, QString("Output"));
|
||||
QWidget *outputWidget = widget;
|
||||
|
||||
icon = new QIcon();
|
||||
icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off);
|
||||
@ -165,6 +167,12 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
|
||||
onOPLinkConnect();
|
||||
}
|
||||
|
||||
// Connect output tab and input tab
|
||||
// Input tab do not start calibration if Output tab is not safe
|
||||
// Output tab uses the signal from Input tab and freeze all output UI while calibrating inputs
|
||||
connect(outputWidget, SIGNAL(outputConfigSafeChanged(bool)), inputWidget, SLOT(setOutputConfigSafe(bool)));
|
||||
connect(inputWidget, SIGNAL(inputCalibrationStateChanged(bool)), outputWidget, SLOT(setInputCalibrationState(bool)));
|
||||
|
||||
help = 0;
|
||||
connect(stackWidget, SIGNAL(currentAboutToShow(int, bool *)), this, SLOT(tabAboutToChange(int, bool *)));
|
||||
}
|
||||
|
@ -497,6 +497,16 @@ void ConfigInputWidget::enableControls(bool enable)
|
||||
} else {
|
||||
// Hide configAlarmStatus when disconnected
|
||||
ui->configAlarmStatus->setVisible(false);
|
||||
if (wizardStep != wizardNone) {
|
||||
// Close input wizard
|
||||
wzCancel();
|
||||
}
|
||||
if (ui->runCalibration->isChecked()) {
|
||||
// Close manual calibration
|
||||
ui->runCalibration->setChecked(false);
|
||||
ui->runCalibration->setText(tr("Start Manual Calibration"));
|
||||
emit inputCalibrationStateChanged(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -509,6 +519,12 @@ void ConfigInputWidget::resizeEvent(QResizeEvent *event)
|
||||
|
||||
void ConfigInputWidget::goToWizard()
|
||||
{
|
||||
if (!outputConfigIsSafe) {
|
||||
QMessageBox::warning(this, tr("Warning"), tr("There is something wrong in <b>Output</b> tab."
|
||||
"<p>Please fix the issue before starting the Transmitter wizard.</p>"), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
QMessageBox msgBox;
|
||||
|
||||
msgBox.setText(tr("Arming Settings are now set to 'Always Disarmed' for your safety."));
|
||||
@ -519,6 +535,9 @@ void ConfigInputWidget::goToWizard()
|
||||
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
|
||||
// Tell Output tab we freeze actuators soon
|
||||
emit inputCalibrationStateChanged(true);
|
||||
|
||||
// Set correct tab visible before starting wizard.
|
||||
if (ui->tabWidget->currentIndex() != 0) {
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
@ -587,6 +606,9 @@ void ConfigInputWidget::wzCancel()
|
||||
flightModeSettingsObj->setData(memento.flightModeSettingsData);
|
||||
actuatorSettingsObj->setData(memento.actuatorSettingsData);
|
||||
systemSettingsObj->setData(memento.systemSettingsData);
|
||||
|
||||
// Tell Output tab the calibration is ended
|
||||
emit inputCalibrationStateChanged(false);
|
||||
}
|
||||
|
||||
void ConfigInputWidget::registerControlActivity()
|
||||
@ -682,6 +704,9 @@ void ConfigInputWidget::wzNext()
|
||||
// move to Arming Settings tab
|
||||
ui->stackedWidget->setCurrentIndex(0);
|
||||
ui->tabWidget->setCurrentIndex(3);
|
||||
|
||||
// Tell Output tab the calibration is ended
|
||||
emit inputCalibrationStateChanged(false);
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(0);
|
||||
@ -1872,7 +1897,7 @@ void ConfigInputWidget::updateConfigAlarmStatus()
|
||||
switch (systemAlarms.ExtendedAlarmStatus[SystemAlarms::EXTENDEDALARMSTATUS_SYSTEMCONFIGURATION]) {
|
||||
case SystemAlarms::EXTENDEDALARMSTATUS_FLIGHTMODE:
|
||||
message = tr("Config error");
|
||||
tooltipMessage = tr("There is something wrong with your config,\nusually a Thrust mode or Assisted mode not supported.\n\n"
|
||||
tooltipMessage = tr("There is something wrong in the current config,\nusually a Thrust mode or Assisted mode not supported.\n\n"
|
||||
"Tip: Reduce the Flight Mode Count to find the culprit.");
|
||||
bgColor = "red";
|
||||
}
|
||||
@ -1916,6 +1941,19 @@ void ConfigInputWidget::updateCalibration()
|
||||
|
||||
void ConfigInputWidget::simpleCalibration(bool enable)
|
||||
{
|
||||
if (!isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!outputConfigIsSafe) {
|
||||
if (enable) {
|
||||
QMessageBox::warning(this, tr("Warning"), tr("There is something wrong in <b>Output</b> tab."
|
||||
"<p>Please fix the issue before starting the Manual Calibration.</p>"), QMessageBox::Ok);
|
||||
ui->runCalibration->setChecked(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
ui->configurationWizard->setEnabled(false);
|
||||
ui->applyButton->setEnabled(false);
|
||||
@ -1932,6 +1970,9 @@ void ConfigInputWidget::simpleCalibration(bool enable)
|
||||
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||
msgBox.exec();
|
||||
|
||||
// Tell Output tab we freeze actuators soon
|
||||
emit inputCalibrationStateChanged(true);
|
||||
|
||||
manualCommandData = manualCommandObj->getData();
|
||||
|
||||
manualSettingsData = manualSettingsObj->getData();
|
||||
@ -1999,6 +2040,9 @@ void ConfigInputWidget::simpleCalibration(bool enable)
|
||||
ui->saveButton->setEnabled(true);
|
||||
ui->runCalibration->setText(tr("Start Manual Calibration"));
|
||||
|
||||
// Tell Output tab the calibration is ended
|
||||
emit inputCalibrationStateChanged(false);
|
||||
|
||||
disconnect(manualCommandObj, SIGNAL(objectUnpacked(UAVObject *)), this, SLOT(updateCalibration()));
|
||||
}
|
||||
}
|
||||
@ -2082,7 +2126,7 @@ void ConfigInputWidget::resetActuatorSettings()
|
||||
QString mixerType;
|
||||
|
||||
// Clear all output data : Min, max, neutral at same value
|
||||
// 1000 for motors and 1500 for all others (Reversable motor included)
|
||||
// min value for motors and neutral for all others (Reversable motor, servo)
|
||||
for (unsigned int output = 0; output < ActuatorSettings::CHANNELMAX_NUMELEM; output++) {
|
||||
QString mixerNumType = QString("Mixer%1Type").arg(output + 1);
|
||||
UAVObjectField *field = mixer->getField(mixerNumType);
|
||||
@ -2092,13 +2136,13 @@ void ConfigInputWidget::resetActuatorSettings()
|
||||
mixerType = field->getValue().toString();
|
||||
}
|
||||
if ((mixerType == "Motor") || (mixerType == "Disabled")) {
|
||||
actuatorSettingsData.ChannelMax[output] = 1000;
|
||||
actuatorSettingsData.ChannelMin[output] = 1000;
|
||||
actuatorSettingsData.ChannelNeutral[output] = 1000;
|
||||
// Apply current min setting to neutral/max values
|
||||
actuatorSettingsData.ChannelMax[output] = actuatorSettingsData.ChannelMin[output];
|
||||
actuatorSettingsData.ChannelNeutral[output] = actuatorSettingsData.ChannelMin[output];
|
||||
} else {
|
||||
actuatorSettingsData.ChannelMax[output] = 1500;
|
||||
actuatorSettingsData.ChannelMin[output] = 1500;
|
||||
actuatorSettingsData.ChannelNeutral[output] = 1500;
|
||||
// Apply current neutral setting to min/max values
|
||||
actuatorSettingsData.ChannelMax[output] = actuatorSettingsData.ChannelNeutral[output];
|
||||
actuatorSettingsData.ChannelMin[output] = actuatorSettingsData.ChannelNeutral[output];
|
||||
}
|
||||
UAVObjectUpdaterHelper updateHelper;
|
||||
actuatorSettingsObj->setData(actuatorSettingsData, false);
|
||||
@ -2189,3 +2233,8 @@ void ConfigInputWidget::enableControlsChanged(bool enabled)
|
||||
ui->failsafeBatteryWarningFlightModeCb->setEnabled(enabled && batteryModuleEnabled);
|
||||
ui->failsafeBatteryCriticalFlightModeCb->setEnabled(enabled && batteryModuleEnabled);
|
||||
}
|
||||
|
||||
void ConfigInputWidget::setOutputConfigSafe(bool status)
|
||||
{
|
||||
outputConfigIsSafe = status;
|
||||
}
|
||||
|
@ -72,10 +72,17 @@ public:
|
||||
void enableControls(bool enable);
|
||||
bool shouldObjectBeSaved(UAVObject *object);
|
||||
|
||||
public slots:
|
||||
void setOutputConfigSafe(bool status);
|
||||
|
||||
signals:
|
||||
void inputCalibrationStateChanged(bool newState);
|
||||
|
||||
private:
|
||||
bool throttleError;
|
||||
bool growing;
|
||||
bool reverse[ManualControlSettings::CHANNELNEUTRAL_NUMELEM];
|
||||
bool outputConfigIsSafe;
|
||||
txMovements currentMovement;
|
||||
int movePos;
|
||||
void setTxMovement(txMovements movement);
|
||||
|
@ -51,8 +51,23 @@
|
||||
#include <QTextEdit>
|
||||
#include <QMessageBox>
|
||||
|
||||
#define MAXOUTPUT_VALUE 2500
|
||||
#define MINOUTPUT_VALUE 500
|
||||
// Motor settings
|
||||
#define DSHOT_MAXOUTPUT_RANGE 2000
|
||||
#define DSHOT_MINTOUTPUT_RANGE 0
|
||||
#define PWMSYNC_MAXOUTPUT_RANGE 1900
|
||||
#define DEFAULT_MAXOUTPUT_RANGE 2000
|
||||
#define DEFAULT_MINOUTPUT_RANGE 900
|
||||
#define DEFAULT_MINOUTPUT_VALUE 1000
|
||||
#define REVMOTOR_NEUTRAL_TARGET_VALUE 1500
|
||||
#define REVMOTOR_NEUTRAL_DIFF_VALUE 200
|
||||
#define MOTOR_NEUTRAL_DIFF_VALUE 300
|
||||
|
||||
// Servo settings
|
||||
#define SERVO_MAXOUTPUT_RANGE 2500
|
||||
#define SERVO_MINOUTPUT_RANGE 500
|
||||
#define SERVO_MAXOUTPUT_VALUE 2000
|
||||
#define SERVO_MINOUTPUT_VALUE 1000
|
||||
#define SERVO_NEUTRAL_VALUE 1500
|
||||
|
||||
ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(parent)
|
||||
{
|
||||
@ -64,7 +79,8 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
|
||||
|
||||
addAutoBindings();
|
||||
|
||||
m_ui->gvFrame->setVisible(false);
|
||||
m_ui->boardWarningFrame->setVisible(false);
|
||||
m_ui->configWarningFrame->setVisible(false);
|
||||
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
UAVSettingsImportExportFactory *importexportplugin = pm->getObject<UAVSettingsImportExportFactory>();
|
||||
@ -128,7 +144,10 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
|
||||
}
|
||||
|
||||
SystemAlarms *systemAlarmsObj = SystemAlarms::GetInstance(getObjectManager());
|
||||
connect(systemAlarmsObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateWarnings(UAVObject *)));
|
||||
connect(systemAlarmsObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateBoardWarnings(UAVObject *)));
|
||||
|
||||
inputCalibrationStarted = false;
|
||||
channelTestsStarted = false;
|
||||
|
||||
// TODO why do we do that ?
|
||||
disconnect(this, SLOT(refreshWidgetsValues(UAVObject *)));
|
||||
@ -138,7 +157,7 @@ ConfigOutputWidget::~ConfigOutputWidget()
|
||||
{
|
||||
SystemAlarms *systemAlarmsObj = SystemAlarms::GetInstance(getObjectManager());
|
||||
|
||||
disconnect(systemAlarmsObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateWarnings(UAVObject *)));
|
||||
disconnect(systemAlarmsObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateBoardWarnings(UAVObject *)));
|
||||
foreach(OutputBankControls controls, m_banks) {
|
||||
disconnect(controls.modeCombo(), SIGNAL(currentIndexChanged(int)), this, SLOT(onBankTypeChange()));
|
||||
}
|
||||
@ -150,6 +169,7 @@ void ConfigOutputWidget::enableControls(bool enable)
|
||||
|
||||
if (!enable) {
|
||||
m_ui->channelOutTest->setChecked(false);
|
||||
channelTestsStarted = false;
|
||||
}
|
||||
m_ui->channelOutTest->setEnabled(enable);
|
||||
}
|
||||
@ -203,6 +223,17 @@ void ConfigOutputWidget::runChannelTests(bool state)
|
||||
}
|
||||
}
|
||||
|
||||
channelTestsStarted = state;
|
||||
|
||||
// Emit signal to be received by Input tab
|
||||
emit outputConfigSafeChanged(!state);
|
||||
|
||||
m_ui->spinningArmed->setEnabled(!state);
|
||||
m_ui->alwaysStabilizedSwitch->setEnabled((m_ui->spinningArmed->isChecked()) && !state);
|
||||
m_ui->alwayStabilizedLabel1->setEnabled((m_ui->spinningArmed->isChecked()) && !state);
|
||||
m_ui->alwayStabilizedLabel2->setEnabled((m_ui->spinningArmed->isChecked()) && !state);
|
||||
setBanksEnabled(!state);
|
||||
|
||||
ActuatorCommand *obj = ActuatorCommand::GetInstance(getObjectManager());
|
||||
UAVObject::Metadata mdata = obj->getMetadata();
|
||||
if (state) {
|
||||
@ -390,6 +421,9 @@ void ConfigOutputWidget::refreshWidgetsValuesImpl(UAVObject *obj)
|
||||
}
|
||||
}
|
||||
|
||||
// Store how many banks are active according to the board
|
||||
activeBanksCount = bankLabels.count();
|
||||
|
||||
int i = 0;
|
||||
foreach(QString banklabel, bankLabels) {
|
||||
OutputBankControls controls = m_banks.at(i);
|
||||
@ -399,10 +433,11 @@ void ConfigOutputWidget::refreshWidgetsValuesImpl(UAVObject *obj)
|
||||
if (index == -1) {
|
||||
controls.rateCombo()->addItem(tr("%1 Hz").arg(actuatorSettingsData.BankUpdateFreq[i]), actuatorSettingsData.BankUpdateFreq[i]);
|
||||
}
|
||||
bool isPWM = (controls.modeCombo()->currentIndex() == ActuatorSettings::BANKMODE_PWM);
|
||||
controls.rateCombo()->setCurrentIndex(index);
|
||||
controls.rateCombo()->setEnabled(controls.modeCombo()->currentIndex() == ActuatorSettings::BANKMODE_PWM);
|
||||
controls.rateCombo()->setEnabled(!inputCalibrationStarted && !channelTestsStarted && isPWM);
|
||||
setColor(controls.rateCombo(), controls.color());
|
||||
controls.modeCombo()->setEnabled(true);
|
||||
controls.modeCombo()->setEnabled(!inputCalibrationStarted && !channelTestsStarted);
|
||||
setColor(controls.modeCombo(), controls.color());
|
||||
i++;
|
||||
}
|
||||
@ -430,6 +465,7 @@ void ConfigOutputWidget::refreshWidgetsValuesImpl(UAVObject *obj)
|
||||
}
|
||||
|
||||
updateSpinStabilizeCheckComboBoxes();
|
||||
checkOutputConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -483,9 +519,9 @@ void ConfigOutputWidget::updateObjectsFromWidgetsImpl()
|
||||
|
||||
void ConfigOutputWidget::updateSpinStabilizeCheckComboBoxes()
|
||||
{
|
||||
m_ui->alwayStabilizedLabel1->setEnabled(m_ui->spinningArmed->isChecked());
|
||||
m_ui->alwayStabilizedLabel2->setEnabled(m_ui->spinningArmed->isChecked());
|
||||
m_ui->alwaysStabilizedSwitch->setEnabled(m_ui->spinningArmed->isChecked());
|
||||
m_ui->alwayStabilizedLabel1->setEnabled((m_ui->spinningArmed->isChecked()) && (m_ui->spinningArmed->isEnabled()));
|
||||
m_ui->alwayStabilizedLabel2->setEnabled((m_ui->spinningArmed->isChecked()) && (m_ui->spinningArmed->isEnabled()));
|
||||
m_ui->alwaysStabilizedSwitch->setEnabled((m_ui->spinningArmed->isChecked()) && (m_ui->spinningArmed->isEnabled()));
|
||||
|
||||
if (!m_ui->spinningArmed->isChecked()) {
|
||||
m_ui->alwaysStabilizedSwitch->setCurrentIndex(FlightModeSettings::ALWAYSSTABILIZEWHENARMEDSWITCH_DISABLED);
|
||||
@ -506,23 +542,118 @@ void ConfigOutputWidget::updateAlwaysStabilizeStatus()
|
||||
|
||||
void ConfigOutputWidget::setChannelLimits(OutputChannelForm *channelForm, OutputBankControls *bankControls)
|
||||
{
|
||||
// Set UI limits according to the bankmode and destination
|
||||
switch (bankControls->modeCombo()->currentIndex()) {
|
||||
case ActuatorSettings::BANKMODE_DSHOT:
|
||||
channelForm->setLimits(0, 0, 0, 2000);
|
||||
// 0 - 2000 UI limits, DShot min value is fixed to zero
|
||||
if (channelForm->isServoOutput()) {
|
||||
// Driving a servo using DShot doest not make sense so break
|
||||
break;
|
||||
}
|
||||
channelForm->setLimits(DSHOT_MINTOUTPUT_RANGE, DSHOT_MINTOUTPUT_RANGE, DSHOT_MINTOUTPUT_RANGE, DSHOT_MAXOUTPUT_RANGE);
|
||||
channelForm->setRange(DSHOT_MINTOUTPUT_RANGE, DSHOT_MAXOUTPUT_RANGE);
|
||||
channelForm->setNeutral(DSHOT_MINTOUTPUT_RANGE);
|
||||
break;
|
||||
// case ActuatorSettings::BANKMODE_BRUSHED:
|
||||
// channelForm->setLimits(0, 0, 0, 100); // 0 to 100%
|
||||
// break;
|
||||
case ActuatorSettings::BANKMODE_PWMSYNC:
|
||||
// 900 - 1900 UI limits
|
||||
// Default values 1000 - 1900
|
||||
channelForm->setLimits(DEFAULT_MINOUTPUT_RANGE, PWMSYNC_MAXOUTPUT_RANGE, DEFAULT_MINOUTPUT_RANGE, PWMSYNC_MAXOUTPUT_RANGE);
|
||||
channelForm->setRange(DEFAULT_MINOUTPUT_VALUE, PWMSYNC_MAXOUTPUT_RANGE);
|
||||
channelForm->setNeutral(DEFAULT_MINOUTPUT_VALUE);
|
||||
if (channelForm->isServoOutput()) {
|
||||
// Servo: Some of them can handle PWMSync, 500 - 1900 UI limits
|
||||
// Default values 1000 - 1900 + neutral 1500
|
||||
channelForm->setRange(SERVO_MINOUTPUT_VALUE, PWMSYNC_MAXOUTPUT_RANGE);
|
||||
channelForm->setNeutral(SERVO_NEUTRAL_VALUE);
|
||||
}
|
||||
break;
|
||||
case ActuatorSettings::BANKMODE_PWM:
|
||||
if (channelForm->isServoOutput()) {
|
||||
// Servo: 500 - 2500 UI limits
|
||||
// Default values 1000 - 2000 + neutral 1500
|
||||
channelForm->setLimits(SERVO_MINOUTPUT_RANGE, SERVO_MAXOUTPUT_RANGE, SERVO_MINOUTPUT_RANGE, SERVO_MAXOUTPUT_RANGE);
|
||||
channelForm->setRange(SERVO_MINOUTPUT_VALUE, SERVO_MAXOUTPUT_VALUE);
|
||||
channelForm->setNeutral(SERVO_NEUTRAL_VALUE);
|
||||
break;
|
||||
}
|
||||
// PWM motor outputs fall to default
|
||||
case ActuatorSettings::BANKMODE_ONESHOT125:
|
||||
case ActuatorSettings::BANKMODE_ONESHOT42:
|
||||
case ActuatorSettings::BANKMODE_MULTISHOT:
|
||||
if (channelForm->isServoOutput()) {
|
||||
// Driving a servo using this mode does not make sense so break
|
||||
break;
|
||||
}
|
||||
default:
|
||||
channelForm->setLimits(MINOUTPUT_VALUE, MAXOUTPUT_VALUE, MINOUTPUT_VALUE, MAXOUTPUT_VALUE);
|
||||
// Motors 900 - 2000 UI limits
|
||||
// Default values 1000 - 2000, neutral set to min
|
||||
// This settings are used for PWM, OneShot125, OneShot42 and MultiShot
|
||||
channelForm->setLimits(DEFAULT_MINOUTPUT_RANGE, DEFAULT_MAXOUTPUT_RANGE, DEFAULT_MINOUTPUT_RANGE, DEFAULT_MAXOUTPUT_RANGE);
|
||||
channelForm->setRange(DEFAULT_MINOUTPUT_VALUE, DEFAULT_MAXOUTPUT_RANGE);
|
||||
channelForm->setNeutral(DEFAULT_MINOUTPUT_VALUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigOutputWidget::ChannelConfigWarning ConfigOutputWidget::checkChannelConfig(OutputChannelForm *channelForm, OutputBankControls *bankControls)
|
||||
{
|
||||
ChannelConfigWarning warning = None;
|
||||
int currentNeutralValue = channelForm->neutralValue();
|
||||
|
||||
// Check if RevMotor has neutral value around center
|
||||
if (channelForm->isReversibleMotorOutput()) {
|
||||
warning = IsReversibleMotorCheckNeutral;
|
||||
int neutralDiff = qAbs(REVMOTOR_NEUTRAL_TARGET_VALUE - currentNeutralValue);
|
||||
if (neutralDiff < REVMOTOR_NEUTRAL_DIFF_VALUE) {
|
||||
// Reset warning
|
||||
warning = None;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if NormalMotor neutral is not too high
|
||||
if (channelForm->isNormalMotorOutput()) {
|
||||
warning = IsNormalMotorCheckNeutral;
|
||||
int neutralDiff = currentNeutralValue - DEFAULT_MINOUTPUT_VALUE;
|
||||
if (neutralDiff < MOTOR_NEUTRAL_DIFF_VALUE) {
|
||||
// Reset warning
|
||||
warning = None;
|
||||
}
|
||||
}
|
||||
|
||||
switch (bankControls->modeCombo()->currentIndex()) {
|
||||
case ActuatorSettings::BANKMODE_DSHOT:
|
||||
if (channelForm->isServoOutput()) {
|
||||
// Driving a servo using DShot doest not make sense
|
||||
warning = CannotDriveServo;
|
||||
} else if (channelForm->isReversibleMotorOutput()) {
|
||||
// Bi-directional DShot not yet supported
|
||||
warning = BiDirectionalDShotNotSupported;
|
||||
}
|
||||
break;
|
||||
case ActuatorSettings::BANKMODE_PWMSYNC:
|
||||
case ActuatorSettings::BANKMODE_PWM:
|
||||
break;
|
||||
case ActuatorSettings::BANKMODE_ONESHOT125:
|
||||
case ActuatorSettings::BANKMODE_ONESHOT42:
|
||||
case ActuatorSettings::BANKMODE_MULTISHOT:
|
||||
if (channelForm->isServoOutput()) {
|
||||
warning = CannotDriveServo;
|
||||
// Driving a servo using this mode does not make sense so break
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return warning;
|
||||
}
|
||||
|
||||
|
||||
void ConfigOutputWidget::onBankTypeChange()
|
||||
{
|
||||
QComboBox *bankModeCombo = qobject_cast<QComboBox *>(sender());
|
||||
|
||||
ChannelConfigWarning new_warning = None;
|
||||
|
||||
if (bankModeCombo != NULL) {
|
||||
int bankNumber = 1;
|
||||
QList<OutputChannelForm *> outputChannelForms = findChildren<OutputChannelForm *>();
|
||||
@ -534,6 +665,10 @@ void ConfigOutputWidget::onBankTypeChange()
|
||||
foreach(OutputChannelForm * outputChannelForm, outputChannelForms) {
|
||||
if (outputChannelForm->bank().toInt() == bankNumber) {
|
||||
setChannelLimits(outputChannelForm, &controls);
|
||||
ChannelConfigWarning warning = checkChannelConfig(outputChannelForm, &controls);
|
||||
if (warning > None) {
|
||||
new_warning = warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -542,14 +677,46 @@ void ConfigOutputWidget::onBankTypeChange()
|
||||
bankNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
updateChannelConfigWarning(new_warning);
|
||||
}
|
||||
|
||||
bool ConfigOutputWidget::checkOutputConfig()
|
||||
{
|
||||
ChannelConfigWarning new_warning = None;
|
||||
|
||||
int bankNumber = 1;
|
||||
|
||||
QList<OutputChannelForm *> outputChannelForms = findChildren<OutputChannelForm *>();
|
||||
|
||||
foreach(OutputBankControls controls, m_banks) {
|
||||
foreach(OutputChannelForm * outputChannelForm, outputChannelForms) {
|
||||
if (!outputChannelForm->isDisabledOutput() && (outputChannelForm->bank().toInt() == bankNumber)) {
|
||||
ChannelConfigWarning warning = checkChannelConfig(outputChannelForm, &controls);
|
||||
if (warning > None) {
|
||||
new_warning = warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bankNumber++;
|
||||
}
|
||||
|
||||
updateChannelConfigWarning(new_warning);
|
||||
|
||||
// Emit signal to be received by Input tab
|
||||
emit outputConfigSafeChanged(new_warning == None);
|
||||
|
||||
return new_warning == None;
|
||||
}
|
||||
|
||||
void ConfigOutputWidget::stopTests()
|
||||
{
|
||||
m_ui->channelOutTest->setChecked(false);
|
||||
channelTestsStarted = false;
|
||||
}
|
||||
|
||||
void ConfigOutputWidget::updateWarnings(UAVObject *)
|
||||
void ConfigOutputWidget::updateBoardWarnings(UAVObject *)
|
||||
{
|
||||
SystemAlarms *systemAlarmsObj = SystemAlarms::GetInstance(getObjectManager());
|
||||
SystemAlarms::DataFields systemAlarms = systemAlarmsObj->getData();
|
||||
@ -557,23 +724,96 @@ void ConfigOutputWidget::updateWarnings(UAVObject *)
|
||||
if (systemAlarms.Alarm[SystemAlarms::ALARM_SYSTEMCONFIGURATION] > SystemAlarms::ALARM_WARNING) {
|
||||
switch (systemAlarms.ExtendedAlarmStatus[SystemAlarms::EXTENDEDALARMSTATUS_SYSTEMCONFIGURATION]) {
|
||||
case SystemAlarms::EXTENDEDALARMSTATUS_UNSUPPORTEDCONFIG_ONESHOT:
|
||||
setWarning(tr("OneShot and PWMSync output only works with Receiver Port settings marked with '+OneShot'<br>"
|
||||
"When using Receiver Port setting 'PPM_PIN8+OneShot' "
|
||||
"<b><font color='%1'>Bank %2</font></b> must be set to PWM")
|
||||
.arg(m_banks.at(3).color().name()).arg(m_banks.at(3).label()->text()));
|
||||
setBoardWarning(tr("OneShot and PWMSync output only works with Receiver Port settings marked with '+OneShot'<br>"
|
||||
"When using Receiver Port setting 'PPM_PIN8+OneShot' "
|
||||
"<b><font color='%1'>Bank %2</font></b> must be set to PWM")
|
||||
.arg(m_banks.at(3).color().name()).arg(m_banks.at(3).label()->text()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
setWarning(NULL);
|
||||
setBoardWarning(NULL);
|
||||
}
|
||||
|
||||
void ConfigOutputWidget::setWarning(QString message)
|
||||
void ConfigOutputWidget::updateChannelConfigWarning(ChannelConfigWarning warning)
|
||||
{
|
||||
m_ui->gvFrame->setVisible(!message.isNull());
|
||||
m_ui->picWarning->setPixmap(message.isNull() ? QPixmap() : QPixmap(":/configgadget/images/error.svg"));
|
||||
m_ui->txtWarning->setText(message);
|
||||
QString warning_str;
|
||||
|
||||
if (warning == BiDirectionalDShotNotSupported) {
|
||||
// TODO: Implement bi-directional DShot
|
||||
warning_str = "There is <b>one reversible motor</b> using DShot is configured.<br>"
|
||||
"Bi-directional DShot is currently not supported. Please use PWM, OneShotXXX or MultiShot.";
|
||||
}
|
||||
|
||||
if (warning == IsNormalMotorCheckNeutral) {
|
||||
warning_str = "There is at least one pretty <b>high neutral value</b> set in your configuration.<br>"
|
||||
"Make sure all ESCs are calibrated and no mechanical stress in all motors.";
|
||||
}
|
||||
|
||||
if (warning == IsReversibleMotorCheckNeutral) {
|
||||
warning_str = "A least one <b>reversible motor</b> is configured.<br>"
|
||||
"Make sure a appropriate neutral value is set before saving and applying power to the vehicule.";
|
||||
}
|
||||
|
||||
if (warning == CannotDriveServo) {
|
||||
warning_str = "One bank cannot drive a <b>servo output</b>!<br>"
|
||||
"You must use PWM for this bank or move the servo output to another compatible bank.";
|
||||
}
|
||||
|
||||
setConfigWarning(warning_str);
|
||||
}
|
||||
|
||||
void ConfigOutputWidget::setBanksEnabled(bool state)
|
||||
{
|
||||
// Disable/Enable banks
|
||||
for (int i = 0; i < m_banks.count(); i++) {
|
||||
OutputBankControls controls = m_banks.at(i);
|
||||
if (i < activeBanksCount) {
|
||||
controls.modeCombo()->setEnabled(state);
|
||||
controls.rateCombo()->setEnabled(state);
|
||||
} else {
|
||||
controls.modeCombo()->setEnabled(false);
|
||||
controls.rateCombo()->setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigOutputWidget::setBoardWarning(QString message)
|
||||
{
|
||||
m_ui->boardWarningFrame->setVisible(!message.isNull());
|
||||
m_ui->boardWarningPic->setPixmap(message.isNull() ? QPixmap() : QPixmap(":/configgadget/images/error.svg"));
|
||||
m_ui->boardWarningTxt->setText(message);
|
||||
}
|
||||
|
||||
void ConfigOutputWidget::setConfigWarning(QString message)
|
||||
{
|
||||
m_ui->configWarningFrame->setVisible(!message.isNull());
|
||||
m_ui->configWarningPic->setPixmap(message.isNull() ? QPixmap() : QPixmap(":/configgadget/images/error.svg"));
|
||||
m_ui->configWarningTxt->setText(message);
|
||||
}
|
||||
|
||||
void ConfigOutputWidget::setInputCalibrationState(bool started)
|
||||
{
|
||||
inputCalibrationStarted = started;
|
||||
|
||||
// Disable UI when a input calibration is started
|
||||
// so user cannot manipulate settings.
|
||||
enableControls(!started);
|
||||
setBanksEnabled(!started);
|
||||
// Disable ASWA
|
||||
m_ui->spinningArmed->setEnabled(!started);
|
||||
m_ui->alwaysStabilizedSwitch->setEnabled((m_ui->spinningArmed->isChecked()) && !started);
|
||||
m_ui->alwayStabilizedLabel1->setEnabled((m_ui->spinningArmed->isChecked()) && !started);
|
||||
m_ui->alwayStabilizedLabel2->setEnabled((m_ui->spinningArmed->isChecked()) && !started);
|
||||
|
||||
// Disable every channel form when needed
|
||||
for (unsigned int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) {
|
||||
OutputChannelForm *form = getOutputChannelForm(i);
|
||||
form->ui->actuatorRev->setChecked(false);
|
||||
form->ui->actuatorLink->setChecked(false);
|
||||
form->setChannelRangeEnabled(!started);
|
||||
form->setControlsEnabled(!started);
|
||||
}
|
||||
}
|
||||
|
||||
OutputBankControls::OutputBankControls(MixerSettings *mixer, QLabel *label, QColor color, QComboBox *rateCombo, QComboBox *modeCombo) :
|
||||
m_mixer(mixer), m_label(label), m_color(color), m_rateCombo(rateCombo), m_modeCombo(modeCombo)
|
||||
|
@ -85,9 +85,16 @@ public:
|
||||
ConfigOutputWidget(QWidget *parent = 0);
|
||||
~ConfigOutputWidget();
|
||||
|
||||
public slots:
|
||||
void setInputCalibrationState(bool state);
|
||||
|
||||
signals:
|
||||
void outputConfigSafeChanged(bool newStatus);
|
||||
|
||||
protected:
|
||||
void enableControls(bool enable);
|
||||
void setWarning(QString message);
|
||||
void setBoardWarning(QString message);
|
||||
void setConfigWarning(QString message);
|
||||
|
||||
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
|
||||
virtual void updateObjectsFromWidgetsImpl();
|
||||
@ -98,16 +105,25 @@ private:
|
||||
int m_mccDataRate;
|
||||
UAVObject::Metadata m_accInitialData;
|
||||
QList<OutputBankControls> m_banks;
|
||||
int activeBanksCount;
|
||||
void setBanksEnabled(bool state);
|
||||
|
||||
bool inputCalibrationStarted;
|
||||
bool channelTestsStarted;
|
||||
|
||||
OutputChannelForm *getOutputChannelForm(const int index) const;
|
||||
void updateChannelInSlider(QSlider *slider, QLabel *min, QLabel *max, QCheckBox *rev, int value);
|
||||
void assignOutputChannel(UAVDataObject *obj, QString &str);
|
||||
void setColor(QWidget *widget, const QColor color);
|
||||
void sendAllChannelTests();
|
||||
enum ChannelConfigWarning { None, CannotDriveServo, IsNormalMotorCheckNeutral, IsReversibleMotorCheckNeutral, BiDirectionalDShotNotSupported };
|
||||
void setChannelLimits(OutputChannelForm *channelForm, OutputBankControls *bankControls);
|
||||
ChannelConfigWarning checkChannelConfig(OutputChannelForm *channelForm, OutputBankControls *bankControls);
|
||||
bool checkOutputConfig();
|
||||
void updateChannelConfigWarning(ChannelConfigWarning warning);
|
||||
|
||||
private slots:
|
||||
void updateWarnings(UAVObject *);
|
||||
void updateBoardWarnings(UAVObject *);
|
||||
void updateSpinStabilizeCheckComboBoxes();
|
||||
void updateAlwaysStabilizeStatus();
|
||||
void stopTests();
|
||||
|
@ -123,7 +123,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>743</width>
|
||||
<height>668</height>
|
||||
<height>666</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,0,0">
|
||||
@ -147,7 +147,7 @@
|
||||
<property name="title">
|
||||
<string>Output Configuration</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="0,0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="0,0,0">
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
@ -698,7 +698,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="gvFrame">
|
||||
<widget class="QFrame" name="boardWarningFrame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
@ -741,14 +741,14 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="picWarning">
|
||||
<widget class="QLabel" name="boardWarningPic">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="txtWarning">
|
||||
<widget class="QLabel" name="boardWarningTxt">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
@ -770,6 +770,79 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="configWarningFrame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_10">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configWarningPic">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="configWarningTxt">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_11">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -28,9 +28,10 @@
|
||||
#include "outputchannelform.h"
|
||||
|
||||
#include "ui_outputchannelform.h"
|
||||
#include <QDebug>
|
||||
|
||||
OutputChannelForm::OutputChannelForm(const int index, QWidget *parent) :
|
||||
ChannelForm(index, parent), ui(new Ui::outputChannelForm), m_inChannelTest(false)
|
||||
ChannelForm(index, parent), ui(new Ui::outputChannelForm), m_inChannelTest(false), m_updateChannelRangeEnabled(true)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@ -110,15 +111,26 @@ void OutputChannelForm::enableChannelTest(bool state)
|
||||
ui->actuatorMin->setEnabled(false);
|
||||
ui->actuatorMax->setEnabled(false);
|
||||
ui->actuatorRev->setEnabled(false);
|
||||
} else if (m_mixerType != "Disabled") {
|
||||
} else if (!isDisabledOutput()) {
|
||||
ui->actuatorMin->setEnabled(true);
|
||||
ui->actuatorMax->setEnabled(true);
|
||||
if (m_mixerType != "Motor") {
|
||||
if (!isNormalMotorOutput()) {
|
||||
ui->actuatorRev->setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable setChannelRange
|
||||
*/
|
||||
void OutputChannelForm::setChannelRangeEnabled(bool state)
|
||||
{
|
||||
if (m_updateChannelRangeEnabled == state) {
|
||||
return;
|
||||
}
|
||||
m_updateChannelRangeEnabled = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the channel linked state for use in testing mode
|
||||
*/
|
||||
@ -212,6 +224,9 @@ void OutputChannelForm::setLimits(int actuatorMinMinimum, int actuatorMinMaximum
|
||||
ui->actuatorMax->setMaximum(actuatorMaxMaximum);
|
||||
ui->actuatorMin->setMinimum(actuatorMinMinimum);
|
||||
ui->actuatorMax->setMinimum(actuatorMaxMinimum);
|
||||
// Neutral slider limits
|
||||
ui->actuatorNeutral->setMinimum(actuatorMinMinimum);
|
||||
ui->actuatorNeutral->setMaximum(actuatorMaxMaximum);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -233,16 +248,32 @@ void OutputChannelForm::setRange(int minimum, int maximum)
|
||||
*/
|
||||
void OutputChannelForm::setChannelRange()
|
||||
{
|
||||
// Disable outputs not already set in MixerSettings
|
||||
if (isDisabledOutput()) {
|
||||
setLimits(1000, 1000, 1000, 1000);
|
||||
ui->actuatorMin->setValue(1000);
|
||||
ui->actuatorMax->setValue(1000);
|
||||
ui->actuatorRev->setChecked(false);
|
||||
ui->actuatorLink->setChecked(false);
|
||||
setControlsEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_updateChannelRangeEnabled) {
|
||||
// Nothing to do here
|
||||
return;
|
||||
}
|
||||
|
||||
setControlsEnabled(true);
|
||||
|
||||
int minValue = ui->actuatorMin->value();
|
||||
int maxValue = ui->actuatorMax->value();
|
||||
|
||||
int oldMini = ui->actuatorNeutral->minimum();
|
||||
int oldMaxi = ui->actuatorNeutral->maximum();
|
||||
|
||||
m_mixerType = outputMixerType();
|
||||
|
||||
// Red handle for Motors
|
||||
if ((m_mixerType == "Motor") || (m_mixerType == "ReversableMotor")) {
|
||||
if (isNormalMotorOutput() || isReversibleMotorOutput()) {
|
||||
ui->actuatorNeutral->setStyleSheet("QSlider::handle:horizontal { background: rgb(255, 100, 100); width: 18px; height: 28px;"
|
||||
"margin: -3px 0; border-radius: 3px; border: 1px solid #777; }");
|
||||
} else {
|
||||
@ -251,8 +282,8 @@ void OutputChannelForm::setChannelRange()
|
||||
}
|
||||
|
||||
// Normal motor will be *** never *** reversed : without arming a "Min" value (like 1900) can be applied !
|
||||
if (m_mixerType == "Motor") {
|
||||
if (minValue >= maxValue) {
|
||||
if (isNormalMotorOutput()) {
|
||||
if (minValue > maxValue) {
|
||||
// Keep old values
|
||||
ui->actuatorMin->setValue(oldMini);
|
||||
ui->actuatorMax->setValue(oldMaxi);
|
||||
@ -279,25 +310,6 @@ void OutputChannelForm::setChannelRange()
|
||||
if (ui->actuatorNeutral->value() == oldMini) {
|
||||
ui->actuatorNeutral->setValue(ui->actuatorNeutral->minimum());
|
||||
}
|
||||
|
||||
// Enable only outputs already set in mixer
|
||||
if (m_mixerType != "Disabled") {
|
||||
ui->actuatorMin->setEnabled(true);
|
||||
ui->actuatorMax->setEnabled(true);
|
||||
ui->actuatorNeutral->setEnabled(true);
|
||||
ui->actuatorValue->setEnabled(true);
|
||||
ui->actuatorLink->setEnabled(true);
|
||||
} else {
|
||||
ui->actuatorMin->setEnabled(false);
|
||||
ui->actuatorMax->setEnabled(false);
|
||||
ui->actuatorRev->setEnabled(false);
|
||||
ui->actuatorLink->setEnabled(false);
|
||||
ui->actuatorMin->setValue(1000);
|
||||
ui->actuatorMax->setValue(1000);
|
||||
ui->actuatorNeutral->setRange(minValue, maxValue);
|
||||
ui->actuatorNeutral->setValue(minValue);
|
||||
ui->actuatorValue->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -319,6 +331,28 @@ void OutputChannelForm::reverseChannel(bool state)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable UI controls
|
||||
*/
|
||||
void OutputChannelForm::setControlsEnabled(bool state)
|
||||
{
|
||||
if (isDisabledOutput()) {
|
||||
state = false;
|
||||
}
|
||||
ui->actuatorMin->setEnabled(state);
|
||||
ui->actuatorMax->setEnabled(state);
|
||||
ui->actuatorValue->setEnabled(state);
|
||||
ui->actuatorLink->setEnabled(state);
|
||||
// Reverse checkbox will be never checked
|
||||
// or enabled for normal motor
|
||||
if (isNormalMotorOutput()) {
|
||||
ui->actuatorRev->setChecked(false);
|
||||
ui->actuatorRev->setEnabled(false);
|
||||
} else {
|
||||
ui->actuatorRev->setEnabled(state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits the channel value which will be send to the UAV to move the servo.
|
||||
* Returns immediately if we are not in testing mode.
|
||||
@ -372,6 +406,15 @@ void OutputChannelForm::sendChannelTest(int value)
|
||||
emit channelChanged(index(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns current neutral value
|
||||
*/
|
||||
int OutputChannelForm::neutralValue()
|
||||
{
|
||||
return ui->actuatorNeutral->value();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns MixerType
|
||||
@ -389,3 +432,39 @@ QString OutputChannelForm::outputMixerType()
|
||||
|
||||
return mixerType;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns true if a servo output
|
||||
*/
|
||||
bool OutputChannelForm::isServoOutput()
|
||||
{
|
||||
return !isNormalMotorOutput() && !isReversibleMotorOutput() && !isDisabledOutput();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns true if output is a normal Motor
|
||||
*/
|
||||
bool OutputChannelForm::isNormalMotorOutput()
|
||||
{
|
||||
return outputMixerType() == "Motor";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns true if output is a reversible Motor
|
||||
*/
|
||||
bool OutputChannelForm::isReversibleMotorOutput()
|
||||
{
|
||||
return outputMixerType() == "ReversableMotor";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns true if output is disabled
|
||||
*/
|
||||
bool OutputChannelForm::isDisabledOutput()
|
||||
{
|
||||
return outputMixerType() == "Disabled";
|
||||
}
|
||||
|
@ -61,8 +61,17 @@ public slots:
|
||||
void setNeutral(int value);
|
||||
void setRange(int minimum, int maximum);
|
||||
void enableChannelTest(bool state);
|
||||
void setChannelRangeEnabled(bool state);
|
||||
void setControlsEnabled(bool state);
|
||||
QString outputMixerType();
|
||||
void setLimits(int actuatorMinMinimum, int actuatorMinMaximum, int actuatorMaxMinimum, int actuatorMaxMaximum);
|
||||
int neutralValue();
|
||||
|
||||
// output type helper methods
|
||||
bool isServoOutput();
|
||||
bool isNormalMotorOutput();
|
||||
bool isReversibleMotorOutput();
|
||||
bool isDisabledOutput();
|
||||
|
||||
signals:
|
||||
void channelChanged(int index, int value);
|
||||
@ -70,6 +79,7 @@ signals:
|
||||
private:
|
||||
Ui::outputChannelForm *ui;
|
||||
bool m_inChannelTest;
|
||||
bool m_updateChannelRangeEnabled;
|
||||
QString m_mixerType;
|
||||
|
||||
private slots:
|
||||
|
Loading…
x
Reference in New Issue
Block a user