1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

LP-551 setLimits() only set limits - Added checkChannelConfig() and checkOutputConfig() functions.

This commit is contained in:
Laurent Lalanne 2018-01-13 21:34:40 +01:00
parent e69a7ad238
commit b68c130bc4
3 changed files with 230 additions and 88 deletions

View File

@ -60,6 +60,7 @@
#define DEFAULT_MINOUTPUT_VALUE 1000
#define REVMOTOR_NEUTRAL_TARGET_VALUE 1500
#define REVMOTOR_NEUTRAL_DIFF_VALUE 150
#define MOTOR_NEUTRAL_DIFF_VALUE 200
// Servo settings
#define SERVO_MAXOUTPUT_RANGE 2500
@ -68,8 +69,6 @@
#define SERVO_MINOUTPUT_VALUE 1000
#define SERVO_NEUTRAL_VALUE 1500
#define OUTPUT_WARNING_DISABLED -1
ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(parent)
{
m_ui = new Ui_OutputWidget();
@ -80,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>();
@ -144,7 +144,7 @@ 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 *)));
// TODO why do we do that ?
disconnect(this, SLOT(refreshWidgetsValues(UAVObject *)));
@ -154,7 +154,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()));
}
@ -446,6 +446,7 @@ void ConfigOutputWidget::refreshWidgetsValuesImpl(UAVObject *obj)
}
updateSpinStabilizeCheckComboBoxes();
checkOutputConfig();
}
/**
@ -527,15 +528,9 @@ void ConfigOutputWidget::setChannelLimits(OutputChannelForm *channelForm, Output
case ActuatorSettings::BANKMODE_DSHOT:
// 0 - 2000 UI limits, DShot min value is fixed to zero
if (channelForm->isServoOutput()) {
// Driving a servo using DShot do not make sense: break
bank_mode_servo_warning = ActuatorSettings::BANKMODE_DSHOT;
// Driving a servo using DShot doest not make sense so break
break;
}
if (channelForm->isReversableMotor()) {
// Bi-directional DShot not yet supported: apply normal settings
reversable_motor_warning = ActuatorSettings::BANKMODE_DSHOT;
}
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);
@ -543,13 +538,9 @@ void ConfigOutputWidget::setChannelLimits(OutputChannelForm *channelForm, Output
case ActuatorSettings::BANKMODE_PWMSYNC:
// 900 - 1900 UI limits
// Default values 1000 - 1900
currentNeutralValue = channelForm->getNeutralValue();
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->isReversableMotor() && (reversable_motor_warning == OUTPUT_WARNING_DISABLED)) {
reversable_motor_warning = ActuatorSettings::BANKMODE_PWMSYNC;
}
if (channelForm->isServoOutput()) {
// Servo: Some of them can handle PWMSync, 500 - 1900 UI limits
// Default values 1000 - 1900 + neutral 1500
@ -558,10 +549,6 @@ void ConfigOutputWidget::setChannelLimits(OutputChannelForm *channelForm, Output
}
break;
case ActuatorSettings::BANKMODE_PWM:
// PWM motor outputs fall to default
if (channelForm->isReversableMotor() && (reversable_motor_warning == OUTPUT_WARNING_DISABLED)) {
reversable_motor_warning = ActuatorSettings::BANKMODE_PWM;
}
if (channelForm->isServoOutput()) {
// Servo: 500 - 2500 UI limits
// Default values 1000 - 2000 + neutral 1500
@ -570,57 +557,88 @@ void ConfigOutputWidget::setChannelLimits(OutputChannelForm *channelForm, Output
channelForm->setNeutral(SERVO_NEUTRAL_VALUE);
break;
}
// PWM motor outputs fall to default
case ActuatorSettings::BANKMODE_ONESHOT125:
if (channelForm->isServoOutput()) {
bank_mode_servo_warning = ActuatorSettings::BANKMODE_ONESHOT125;
break;
}
if (channelForm->isReversableMotor() && (reversable_motor_warning == OUTPUT_WARNING_DISABLED)) {
reversable_motor_warning = ActuatorSettings::BANKMODE_ONESHOT125;
}
case ActuatorSettings::BANKMODE_ONESHOT42:
if (channelForm->isServoOutput()) {
bank_mode_servo_warning = ActuatorSettings::BANKMODE_ONESHOT42;
break;
}
if (channelForm->isReversableMotor() && (reversable_motor_warning == OUTPUT_WARNING_DISABLED)) {
reversable_motor_warning = ActuatorSettings::BANKMODE_ONESHOT42;
}
case ActuatorSettings::BANKMODE_MULTISHOT:
if (channelForm->isServoOutput()) {
bank_mode_servo_warning = ActuatorSettings::BANKMODE_MULTISHOT;
// Driving a servo using this mode does not make sense so break
break;
}
if (channelForm->isReversableMotor() && (reversable_motor_warning == OUTPUT_WARNING_DISABLED)) {
reversable_motor_warning = ActuatorSettings::BANKMODE_MULTISHOT;
}
default:
// Motors 900 - 2000 UI limits
// Default values 1000 - 2000, neutral set to min
// This settings are used for PWM, OneShot125, OneShot42 and MultiShot
currentNeutralValue = channelForm->getNeutralValue();
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;
}
}
// TODO: Implement bi-directional DShot
if (channelForm->isReversableMotor() && (bankControls->modeCombo()->currentIndex() != ActuatorSettings::BANKMODE_DSHOT)) {
ConfigOutputWidget::ChannelConfigWarning ConfigOutputWidget::checkChannelConfig(OutputChannelForm *channelForm, OutputBankControls *bankControls)
{
ChannelConfigWarning warning = None;
int currentNeutralValue = channelForm->getNeutralValue();
// Check if RevMotor has neutral value around center
if (channelForm->isReversableMotor()) {
warning = IsReversibleMotorCheckNeutral;
int neutralDiff = qAbs(REVMOTOR_NEUTRAL_TARGET_VALUE - currentNeutralValue);
if (neutralDiff < REVMOTOR_NEUTRAL_DIFF_VALUE) {
// Reset warning
reversable_motor_warning = OUTPUT_WARNING_DISABLED;
warning = None;
}
}
// Check if NormalMotor neutral is not too high
if (channelForm->isNormalMotor()) {
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()) {
warning = CannotDriveServo;
// Driving a servo using DShot doest not make sense so break
break;
}
if (channelForm->isReversableMotor()) {
// Bi-directional DShot not yet supported
warning = BiDirectionalDShotNotSupported;
}
break;
case ActuatorSettings::BANKMODE_PWMSYNC:
break;
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
break;
}
default:
break;
}
return warning;
}
void ConfigOutputWidget::onBankTypeChange()
{
QComboBox *bankModeCombo = qobject_cast<QComboBox *>(sender());
bank_mode_servo_warning = OUTPUT_WARNING_DISABLED;
reversable_motor_warning = OUTPUT_WARNING_DISABLED;
ChannelConfigWarning current_warning = None;
ChannelConfigWarning warning_found = None;
if (bankModeCombo != NULL) {
int bankNumber = 1;
@ -633,6 +651,10 @@ void ConfigOutputWidget::onBankTypeChange()
foreach(OutputChannelForm * outputChannelForm, outputChannelForms) {
if (outputChannelForm->bank().toInt() == bankNumber) {
setChannelLimits(outputChannelForm, &controls);
current_warning = checkChannelConfig(outputChannelForm, &controls);
if (current_warning > None) {
warning_found = current_warning;
}
}
}
break;
@ -641,6 +663,39 @@ void ConfigOutputWidget::onBankTypeChange()
bankNumber++;
}
}
updateChannelConfigWarning(warning_found);
}
bool ConfigOutputWidget::checkOutputConfig()
{
ChannelConfigWarning current_warning = None;
ChannelConfigWarning warning_found = 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)) {
current_warning = checkChannelConfig(outputChannelForm, &controls);
if (current_warning > None) {
warning_found = current_warning;
}
}
}
bankNumber++;
}
updateChannelConfigWarning(warning_found);
if (warning_found > None) {
return false;
}
return true;
}
void ConfigOutputWidget::stopTests()
@ -648,7 +703,7 @@ void ConfigOutputWidget::stopTests()
m_ui->channelOutTest->setChecked(false);
}
void ConfigOutputWidget::updateWarnings(UAVObject *)
void ConfigOutputWidget::updateBoardWarnings(UAVObject *)
{
SystemAlarms *systemAlarmsObj = SystemAlarms::GetInstance(getObjectManager());
SystemAlarms::DataFields systemAlarms = systemAlarmsObj->getData();
@ -656,45 +711,56 @@ 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;
}
}
if (reversable_motor_warning > OUTPUT_WARNING_DISABLED) {
QString revmotor_warning_str;
if (reversable_motor_warning == ActuatorSettings::BANKMODE_DSHOT) {
// TODO: Implement bi-directional DShot
revmotor_warning_str = "There is at least one reversable motor using <b>DShot</b> in your configuration."
"<p>Bi-directional DShot is not currently supported, you should use PWM, OneShotXXX or MultiShot.</p>";
} else {
revmotor_warning_str = QString("There is at least one reversable motor using <b>%1</b> in your configuration.</b>"
"<p>Be sure you set the appropriate neutral value before saving and applying power to the vehicule.</p>").arg(bankModeName(reversable_motor_warning));
}
setWarning(revmotor_warning_str);
return;
}
if (bank_mode_servo_warning > OUTPUT_WARNING_DISABLED) {
QString servo_warning_str = QString("Bank using <b>%1</b> cannot drive a <b>servo output!</b>"
"<p>You must use PWM for this bank or move the servo output to another compatible bank.</p>").arg(bankModeName(bank_mode_servo_warning));
setWarning(servo_warning_str);
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 at least <b>one reversable motor using DShot</b> in your configuration.<br>"
"Bi-directional DShot is not currently supported, you should use PWM, OneShotXXX or MultiShot.";
}
if (warning == IsNormalMotorCheckNeutral) {
warning_str = "Seems there is at least one pretty <b>high neutral value</b> set in your configuration.<br>"
"Be sure all Esc are calibrated and no mechanical stress in all motors.";
}
if (warning == IsReversibleMotorCheckNeutral) {
warning_str = "There is at least one <b>reversable motor</b> in your configuration.<br>"
"Be sure you set a appropriate neutral value 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::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);
}
QString ConfigOutputWidget::bankModeName(int index)

View File

@ -85,9 +85,12 @@ public:
ConfigOutputWidget(QWidget *parent = 0);
~ConfigOutputWidget();
bool checkOutputConfig();
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,20 +101,20 @@ private:
int m_mccDataRate;
UAVObject::Metadata m_accInitialData;
QList<OutputBankControls> m_banks;
int bank_mode_servo_warning;
int reversable_motor_warning;
int currentNeutralValue;
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);
void updateChannelConfigWarning(ChannelConfigWarning warning);
QString bankModeName(int index);
private slots:
void updateWarnings(UAVObject *);
void updateBoardWarnings(UAVObject *);
void updateSpinStabilizeCheckComboBoxes();
void updateAlwaysStabilizeStatus();
void stopTests();

View File

@ -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>