1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-03-16 08:29:15 +01:00

Merge branch 'thread/OP-1222_FW_Wizard' of ssh://git.openpilot.org/OpenPilot into fw_wiz

This commit is contained in:
Fredrik Larson 2014-08-26 11:54:57 +10:00
commit 9da2b07bee
9 changed files with 612 additions and 348 deletions

View File

@ -228,7 +228,11 @@ static void stabilizationOuterloopTask()
// That would be changed to Attitude mode max angle affecting Kp // That would be changed to Attitude mode max angle affecting Kp
// Also does not take dT into account // Also does not take dT into account
{ {
float rate_input = cast_struct_to_array(stabSettings.stabBank.ManualRate, stabSettings.stabBank.ManualRate.Roll)[t] * stabilizationDesiredAxis[t] / cast_struct_to_array(stabSettings.stabBank, stabSettings.stabBank.RollMax)[t]; float stickinput[3];
stickinput[0] = boundf(stabilizationDesiredAxis[0] / stabSettings.stabBank.RollMax, -1.0f, 1.0f);
stickinput[1] = boundf(stabilizationDesiredAxis[1] / stabSettings.stabBank.PitchMax, -1.0f, 1.0f);
stickinput[2] = boundf(stabilizationDesiredAxis[2] / stabSettings.stabBank.YawMax, -1.0f, 1.0f);
float rate_input = stickinput[t] * cast_struct_to_array(stabSettings.stabBank.ManualRate, stabSettings.stabBank.ManualRate.Roll)[t];
float weak_leveling = local_error[t] * stabSettings.settings.WeakLevelingKp; float weak_leveling = local_error[t] * stabSettings.settings.WeakLevelingKp;
weak_leveling = boundf(weak_leveling, -stabSettings.settings.MaxWeakLevelingRate, stabSettings.settings.MaxWeakLevelingRate); weak_leveling = boundf(weak_leveling, -stabSettings.settings.MaxWeakLevelingRate, stabSettings.settings.MaxWeakLevelingRate);

View File

@ -180,7 +180,7 @@ static void updatePIDs(UAVObjEvent *ev)
break; break;
case 2: case 2:
StabilizationSettingsBank2Get((StabilizationSettingsBank2Data *)&bank); StabilizationSettingsBank3Get((StabilizationSettingsBank3Data *)&bank);
break; break;
default: default:

View File

@ -425,7 +425,7 @@ void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType)
// get motor 2 value for Yaw and Roll // get motor 2 value for Yaw and Roll
channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
setYawMixLevel(-qRound(value / 1.27)); setYawMixLevel(qRound(value / 1.27));
// change channels // change channels
channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
@ -454,7 +454,7 @@ void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType)
// get motor 2 value for Yaw and Roll // get motor 2 value for Yaw and Roll
channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
setYawMixLevel(-qRound(value / 1.27)); setYawMixLevel(qRound(value / 1.27));
channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
@ -480,9 +480,9 @@ void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType)
m_aircraft->mrPitchMixLevel->setValue(qRound(value / 1.27)); m_aircraft->mrPitchMixLevel->setValue(qRound(value / 1.27));
// get motor 2 value for Yaw and Roll // get motor 2 value for Yaw and Roll
channel += 1; channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
setYawMixLevel(-qRound(value / 1.27)); setYawMixLevel(qRound(value / 1.27));
channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1; channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL); value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);

View File

@ -33,7 +33,6 @@ AirframeStabFixedwingPage::AirframeStabFixedwingPage(SetupWizard *wizard, QWidge
ui(new Ui::AirframeStabFixedwingPage) ui(new Ui::AirframeStabFixedwingPage)
{ {
ui->setupUi(this); ui->setupUi(this);
setFinalPage(true);
} }
AirframeStabFixedwingPage::~AirframeStabFixedwingPage() AirframeStabFixedwingPage::~AirframeStabFixedwingPage()

View File

@ -49,11 +49,11 @@ p, li { white-space: pre-wrap; }
</property> </property>
<item> <item>
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="minimumSize"> <property name="sizePolicy">
<size> <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<width>125</width> <horstretch>0</horstretch>
<height>36</height> <verstretch>0</verstretch>
</size> </sizepolicy>
</property> </property>
<property name="font"> <property name="font">
<font> <font>
@ -69,6 +69,12 @@ p, li { white-space: pre-wrap; }
</item> </item>
<item> <item>
<widget class="QComboBox" name="typeCombo"> <widget class="QComboBox" name="typeCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>125</width> <width>125</width>
@ -82,7 +88,7 @@ p, li { white-space: pre-wrap; }
<item> <item>
<widget class="QTextEdit" name="typeDescription"> <widget class="QTextEdit" name="typeDescription">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Expanding"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>

View File

@ -45,7 +45,6 @@ OutputCalibrationPage::OutputCalibrationPage(SetupWizard *wizard, QWidget *paren
// move the code that was here to setupVehicle() so we can determine which image to use. // move the code that was here to setupVehicle() so we can determine which image to use.
m_vehicleScene = new QGraphicsScene(this); m_vehicleScene = new QGraphicsScene(this);
ui->vehicleView->setScene(m_vehicleScene); ui->vehicleView->setScene(m_vehicleScene);
} }
OutputCalibrationPage::~OutputCalibrationPage() OutputCalibrationPage::~OutputCalibrationPage()
@ -108,17 +107,17 @@ void OutputCalibrationPage::setupVehicle()
// The m_wizardIndexes array contains the index of the QStackedWidget // The m_wizardIndexes array contains the index of the QStackedWidget
// in the page to use for each step. // in the page to use for each step.
m_wizardIndexes << 0 << 1 << 1 << 1 << 2 << 3 << 4; m_wizardIndexes << 0 << 1 << 1 << 1 << 2;
// All element ids to load from the svg file and manage. // All element ids to load from the svg file and manage.
m_vehicleElementIds << "tri" << "tri-frame" << "tri-m1" << "tri-m2" << "tri-m3" << "tri-s1"; m_vehicleElementIds << "tri" << "tri-frame" << "tri-m1" << "tri-m2" << "tri-m3" << "tri-s1";
// The index of the elementId to highlight ( not dim ) for each step // The index of the elementId to highlight ( not dim ) for each step
// this is the index in the m_vehicleElementIds - 1. // this is the index in the m_vehicleElementIds - 1.
m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 4 << 4; m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4;
// The channel number to configure for each step. // The channel number to configure for each step.
m_channelIndex << 0 << 0 << 1 << 2 << 3 << 3 << 3; m_channelIndex << 0 << 0 << 1 << 2 << 3;
setupActuatorMinMaxAndNeutral(0, 2, 3); setupActuatorMinMaxAndNeutral(0, 2, 3);
@ -174,34 +173,34 @@ void OutputCalibrationPage::setupVehicle()
// Fixed Wing // Fixed Wing
case SetupWizard::FIXED_WING_DUAL_AILERON: case SetupWizard::FIXED_WING_DUAL_AILERON:
loadSVGFile(FIXEDWING_SVG_FILE); loadSVGFile(FIXEDWING_SVG_FILE);
m_wizardIndexes << 0 << 1 << 2 << 3 << 4 << 2 << 3 << 4 << 2 << 3 << 4 << 2 << 3 << 4; m_wizardIndexes << 0 << 1 << 2 << 2 << 2 << 2;
m_vehicleElementIds << "aileron" << "aileron-frame" << "aileron-motor" << "aileron-ail-left" << "aileron-ail-right" << "aileron-rudder" << "aileron-elevator"; m_vehicleElementIds << "aileron" << "aileron-frame" << "aileron-motor" << "aileron-ail-left" << "aileron-ail-right" << "aileron-rudder" << "aileron-elevator";
m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 2 << 2 << 3 << 3 << 3 << 4 << 4 << 4 << 5 << 5 << 5; m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 5;
m_channelIndex << 0 << 2 << 0 << 0 << 0 << 1 << 1 << 1 << 3 << 3 << 3 << 4 << 4 << 4; m_channelIndex << 0 << 2 << 0 << 1 << 3 << 4;
setupActuatorMinMaxAndNeutral(3, 3, 5); setupActuatorMinMaxAndNeutral(2, 2, 5);
getWizard()->setActuatorSettings(m_actuatorSettings); getWizard()->setActuatorSettings(m_actuatorSettings);
break; break;
case SetupWizard::FIXED_WING_AILERON: case SetupWizard::FIXED_WING_AILERON:
loadSVGFile(FIXEDWING_SVG_FILE); loadSVGFile(FIXEDWING_SVG_FILE);
m_wizardIndexes << 0 << 1 << 2 << 3 << 4 << 2 << 3 << 4 << 2 << 3 << 4; m_wizardIndexes << 0 << 1 << 2 << 2 << 2;
m_vehicleElementIds << "aileron-single" << "ail2-frame" << "ail2-motor" << "ail2-aileron" << "ail2-rudder" << "ail2-elevator"; m_vehicleElementIds << "aileron-single" << "ail2-frame" << "ail2-motor" << "ail2-aileron" << "ail2-rudder" << "ail2-elevator";
m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 2 << 2 << 3 << 3 << 3 << 4 << 4 << 4; m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4;
m_channelIndex << 0 << 2 << 0 << 0 << 0 << 4 << 4 << 4 << 1 << 1 << 1; m_channelIndex << 0 << 2 << 0 << 4 << 1;
setupActuatorMinMaxAndNeutral(3, 3, 4); setupActuatorMinMaxAndNeutral(2, 2, 4);
getWizard()->setActuatorSettings(m_actuatorSettings); getWizard()->setActuatorSettings(m_actuatorSettings);
break; break;
case SetupWizard::FIXED_WING_ELEVON: case SetupWizard::FIXED_WING_ELEVON:
loadSVGFile(FIXEDWING_SVG_FILE); loadSVGFile(FIXEDWING_SVG_FILE);
m_wizardIndexes << 0 << 1 << 2 << 3 << 4 << 2 << 3 << 4; m_wizardIndexes << 0 << 1 << 2 << 2;
m_vehicleElementIds << "elevon" << "elevon-frame" << "elevon-motor" << "elevon-left" << "elevon-right"; m_vehicleElementIds << "elevon" << "elevon-frame" << "elevon-motor" << "elevon-left" << "elevon-right";
m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 2 << 2 << 3 << 3 << 3; m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3;
m_channelIndex << 0 << 2 << 0 << 0 << 0 << 1 << 1 << 1; m_channelIndex << 0 << 2 << 0 << 1;
setupActuatorMinMaxAndNeutral(3, 3, 3); setupActuatorMinMaxAndNeutral(2, 2, 3);
getWizard()->setActuatorSettings(m_actuatorSettings); getWizard()->setActuatorSettings(m_actuatorSettings);
break; break;
@ -283,13 +282,22 @@ void OutputCalibrationPage::setWizardPage()
if (currentPageIndex == 1) { if (currentPageIndex == 1) {
ui->motorNeutralSlider->setValue(m_actuatorSettings[currentChannel].channelNeutral); ui->motorNeutralSlider->setValue(m_actuatorSettings[currentChannel].channelNeutral);
} else if (currentPageIndex == 2) { } else if (currentPageIndex == 2) {
ui->servoCenterSlider->setValue(m_actuatorSettings[currentChannel].channelNeutral); if (m_actuatorSettings[currentChannel].channelMax < m_actuatorSettings[currentChannel].channelMin &&
} else if (currentPageIndex == 3) { !ui->reverseCheckbox->isChecked()) {
ui->servoMinAngleSlider->setMaximum(m_actuatorSettings[currentChannel].channelNeutral); ui->reverseCheckbox->setChecked(true);
ui->servoMinAngleSlider->setValue(m_actuatorSettings[currentChannel].channelMin); } else {
} else if (currentPageIndex == 4) { ui->reverseCheckbox->setChecked(false);
ui->servoMaxAngleSlider->setMinimum(m_actuatorSettings[currentChannel].channelNeutral); }
ui->servoMaxAngleSlider->setValue(m_actuatorSettings[currentChannel].channelMax); enableServoSliders(false);
if (ui->reverseCheckbox->isChecked()) {
ui->servoMaxAngleSlider->setValue(m_actuatorSettings[currentChannel].channelMax);
ui->servoCenterAngleSlider->setValue(m_actuatorSettings[currentChannel].channelNeutral);
ui->servoMinAngleSlider->setValue(m_actuatorSettings[currentChannel].channelMin);
} else {
ui->servoMinAngleSlider->setValue(m_actuatorSettings[currentChannel].channelMin);
ui->servoCenterAngleSlider->setValue(m_actuatorSettings[currentChannel].channelNeutral);
ui->servoMaxAngleSlider->setValue(m_actuatorSettings[currentChannel].channelMax);
}
} }
} }
setupVehicleHighlightedPart(); setupVehicleHighlightedPart();
@ -360,6 +368,7 @@ void OutputCalibrationPage::enableButtons(bool enable)
void OutputCalibrationPage::on_motorNeutralButton_toggled(bool checked) void OutputCalibrationPage::on_motorNeutralButton_toggled(bool checked)
{ {
ui->motorNeutralButton->setText(checked ? tr("Stop") : tr("Start")); ui->motorNeutralButton->setText(checked ? tr("Stop") : tr("Start"));
ui->motorNeutralSlider->setEnabled(checked);
quint16 channel = getCurrentChannel(); quint16 channel = getCurrentChannel();
quint16 safeValue = m_actuatorSettings[channel].channelNeutral; quint16 safeValue = m_actuatorSettings[channel].channelNeutral;
onStartButtonToggle(ui->motorNeutralButton, channel, m_actuatorSettings[channel].channelNeutral, safeValue, ui->motorNeutralSlider); onStartButtonToggle(ui->motorNeutralButton, channel, m_actuatorSettings[channel].channelNeutral, safeValue, ui->motorNeutralSlider);
@ -370,6 +379,7 @@ void OutputCalibrationPage::onStartButtonToggle(QAbstractButton *button, quint16
if (button->isChecked()) { if (button->isChecked()) {
if (checkAlarms()) { if (checkAlarms()) {
enableButtons(false); enableButtons(false);
enableServoSliders(true);
m_calibrationUtil->startChannelOutput(channel, safeValue); m_calibrationUtil->startChannelOutput(channel, safeValue);
slider->setValue(value); slider->setValue(value);
m_calibrationUtil->setChannelOutputValue(value); m_calibrationUtil->setChannelOutputValue(value);
@ -378,11 +388,20 @@ void OutputCalibrationPage::onStartButtonToggle(QAbstractButton *button, quint16
} }
} else { } else {
m_calibrationUtil->stopChannelOutput(); m_calibrationUtil->stopChannelOutput();
enableServoSliders(false);
enableButtons(true); enableButtons(true);
} }
debugLogChannelValues(); debugLogChannelValues();
} }
void OutputCalibrationPage::enableServoSliders(bool enabled)
{
ui->servoCenterAngleSlider->setEnabled(enabled);
ui->servoMinAngleSlider->setEnabled(enabled);
ui->servoMaxAngleSlider->setEnabled(enabled);
ui->reverseCheckbox->setEnabled(!enabled);
}
bool OutputCalibrationPage::checkAlarms() bool OutputCalibrationPage::checkAlarms()
{ {
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
@ -434,68 +453,118 @@ void OutputCalibrationPage::on_motorNeutralSlider_valueChanged(int value)
} }
} }
void OutputCalibrationPage::on_servoCenterButton_toggled(bool checked) void OutputCalibrationPage::on_servoButton_toggled(bool checked)
{ {
ui->servoCenterButton->setText(checked ? tr("Stop") : tr("Start")); ui->servoButton->setText(checked ? tr("Stop") : tr("Start"));
quint16 channel = getCurrentChannel(); quint16 channel = getCurrentChannel();
quint16 safeValue = m_actuatorSettings[channel].channelNeutral; quint16 safeValue = m_actuatorSettings[channel].channelNeutral;
onStartButtonToggle(ui->servoCenterButton, channel, safeValue, safeValue, ui->servoCenterSlider); onStartButtonToggle(ui->servoButton, channel, safeValue, safeValue, ui->servoCenterAngleSlider);
} }
void OutputCalibrationPage::on_servoCenterSlider_valueChanged(int position) void OutputCalibrationPage::on_servoCenterAngleSlider_valueChanged(int position)
{ {
Q_UNUSED(position); Q_UNUSED(position);
if (ui->servoCenterButton->isChecked()) { quint16 value = ui->servoCenterAngleSlider->value();
quint16 value = ui->servoCenterSlider->value(); m_calibrationUtil->setChannelOutputValue(value);
m_calibrationUtil->setChannelOutputValue(value); quint16 channel = getCurrentChannel();
quint16 channel = getCurrentChannel(); m_actuatorSettings[channel].channelNeutral = value;
m_actuatorSettings[channel].channelNeutral = value;
// Adjust min and max // Adjust min and max
if (value < m_actuatorSettings[channel].channelMin) { if (ui->reverseCheckbox->isChecked()) {
m_actuatorSettings[channel].channelMin = value; if (value >= m_actuatorSettings[channel].channelMin) {
ui->servoMinAngleSlider->setValue(value);
} }
if (value > m_actuatorSettings[channel].channelMax) { if (value <= m_actuatorSettings[channel].channelMax) {
m_actuatorSettings[channel].channelMax = value; ui->servoMaxAngleSlider->setValue(value);
}
} else {
if (value <= m_actuatorSettings[channel].channelMin) {
ui->servoMinAngleSlider->setValue(value);
}
if (value >= m_actuatorSettings[channel].channelMax) {
ui->servoMaxAngleSlider->setValue(value);
} }
debugLogChannelValues();
} }
} debugLogChannelValues();
void OutputCalibrationPage::on_servoMinAngleButton_toggled(bool checked)
{
ui->servoMinAngleButton->setText(checked ? tr("Stop") : tr("Start"));
quint16 channel = getCurrentChannel();
quint16 safeValue = m_actuatorSettings[channel].channelNeutral;
onStartButtonToggle(ui->servoMinAngleButton, channel, m_actuatorSettings[channel].channelMin, safeValue, ui->servoMinAngleSlider);
} }
void OutputCalibrationPage::on_servoMinAngleSlider_valueChanged(int position) void OutputCalibrationPage::on_servoMinAngleSlider_valueChanged(int position)
{ {
Q_UNUSED(position); Q_UNUSED(position);
if (ui->servoMinAngleButton->isChecked()) { quint16 value = ui->servoMinAngleSlider->value();
quint16 value = ui->servoMinAngleSlider->value(); m_calibrationUtil->setChannelOutputValue(value);
m_calibrationUtil->setChannelOutputValue(value); m_actuatorSettings[getCurrentChannel()].channelMin = value;
m_actuatorSettings[getCurrentChannel()].channelMin = value;
debugLogChannelValues();
}
}
void OutputCalibrationPage::on_servoMaxAngleButton_toggled(bool checked) // Adjust neutral and max
{ if (ui->reverseCheckbox->isChecked()) {
ui->servoMaxAngleButton->setText(checked ? tr("Stop") : tr("Start")); if(value <= m_actuatorSettings[getCurrentChannel()].channelNeutral) {
quint16 channel = getCurrentChannel(); ui->servoCenterAngleSlider->setValue(value);
quint16 safeValue = m_actuatorSettings[channel].channelNeutral; }
onStartButtonToggle(ui->servoMaxAngleButton, channel, m_actuatorSettings[channel].channelMax, safeValue, ui->servoMaxAngleSlider); if(value <= m_actuatorSettings[getCurrentChannel()].channelMax) {
ui->servoMaxAngleSlider->setValue(value);
}
} else {
if(value >= m_actuatorSettings[getCurrentChannel()].channelNeutral) {
ui->servoCenterAngleSlider->setValue(value);
}
if(value >= m_actuatorSettings[getCurrentChannel()].channelMax) {
ui->servoMaxAngleSlider->setValue(value);
}
}
debugLogChannelValues();
} }
void OutputCalibrationPage::on_servoMaxAngleSlider_valueChanged(int position) void OutputCalibrationPage::on_servoMaxAngleSlider_valueChanged(int position)
{ {
Q_UNUSED(position); Q_UNUSED(position);
if (ui->servoMaxAngleButton->isChecked()) { quint16 value = ui->servoMaxAngleSlider->value();
quint16 value = ui->servoMaxAngleSlider->value(); m_calibrationUtil->setChannelOutputValue(value);
m_calibrationUtil->setChannelOutputValue(value); m_actuatorSettings[getCurrentChannel()].channelMax = value;
m_actuatorSettings[getCurrentChannel()].channelMax = value;
debugLogChannelValues(); // Adjust neutral and min
if (ui->reverseCheckbox->isChecked()) {
if(value >= m_actuatorSettings[getCurrentChannel()].channelNeutral) {
ui->servoCenterAngleSlider->setValue(value);
}
if(value >= m_actuatorSettings[getCurrentChannel()].channelMin) {
ui->servoMinAngleSlider->setValue(value);
}
} else {
if(value <= m_actuatorSettings[getCurrentChannel()].channelNeutral) {
ui->servoCenterAngleSlider->setValue(value);
}
if(value <= m_actuatorSettings[getCurrentChannel()].channelMin) {
ui->servoMinAngleSlider->setValue(value);
}
}
debugLogChannelValues();
}
void OutputCalibrationPage::on_reverseCheckbox_toggled(bool checked)
{
if (checked && m_actuatorSettings[getCurrentChannel()].channelMax > m_actuatorSettings[getCurrentChannel()].channelMin) {
quint16 oldMax = m_actuatorSettings[getCurrentChannel()].channelMax;
m_actuatorSettings[getCurrentChannel()].channelMax = m_actuatorSettings[getCurrentChannel()].channelMin;
m_actuatorSettings[getCurrentChannel()].channelMin = oldMax;
} else if (!checked && m_actuatorSettings[getCurrentChannel()].channelMax < m_actuatorSettings[getCurrentChannel()].channelMin) {
quint16 oldMax = m_actuatorSettings[getCurrentChannel()].channelMax;
m_actuatorSettings[getCurrentChannel()].channelMax = m_actuatorSettings[getCurrentChannel()].channelMin;
m_actuatorSettings[getCurrentChannel()].channelMin = oldMax;
}
ui->servoCenterAngleSlider->setInvertedAppearance(checked);
ui->servoCenterAngleSlider->setInvertedControls(checked);
ui->servoMinAngleSlider->setInvertedAppearance(checked);
ui->servoMinAngleSlider->setInvertedControls(checked);
ui->servoMaxAngleSlider->setInvertedAppearance(checked);
ui->servoMaxAngleSlider->setInvertedControls(checked);
if (ui->reverseCheckbox->isChecked()) {
ui->servoMaxAngleSlider->setValue(m_actuatorSettings[getCurrentChannel()].channelMax);
ui->servoCenterAngleSlider->setValue(m_actuatorSettings[getCurrentChannel()].channelNeutral);
ui->servoMinAngleSlider->setValue(m_actuatorSettings[getCurrentChannel()].channelMin);
} else {
ui->servoMinAngleSlider->setValue(m_actuatorSettings[getCurrentChannel()].channelMin);
ui->servoCenterAngleSlider->setValue(m_actuatorSettings[getCurrentChannel()].channelNeutral);
ui->servoMaxAngleSlider->setValue(m_actuatorSettings[getCurrentChannel()].channelMax);
} }
} }

View File

@ -65,14 +65,11 @@ private slots:
void on_motorNeutralButton_toggled(bool checked); void on_motorNeutralButton_toggled(bool checked);
void on_motorNeutralSlider_valueChanged(int value); void on_motorNeutralSlider_valueChanged(int value);
void on_servoCenterButton_toggled(bool checked); void on_servoButton_toggled(bool checked);
void on_servoCenterSlider_valueChanged(int position); void on_servoCenterAngleSlider_valueChanged(int position);
void on_servoMinAngleButton_toggled(bool checked);
void on_servoMinAngleSlider_valueChanged(int position); void on_servoMinAngleSlider_valueChanged(int position);
void on_servoMaxAngleButton_toggled(bool checked);
void on_servoMaxAngleSlider_valueChanged(int position); void on_servoMaxAngleSlider_valueChanged(int position);
void on_reverseCheckbox_toggled(bool checked);
private: private:
void setupVehicle(); void setupVehicle();
@ -81,6 +78,7 @@ private:
void setupVehicleHighlightedPart(); void setupVehicleHighlightedPart();
void setWizardPage(); void setWizardPage();
void enableButtons(bool enable); void enableButtons(bool enable);
void enableServoSliders(bool enabled);
void onStartButtonToggle(QAbstractButton *button, quint16 channel, quint16 value, quint16 safeValue, QSlider *slider); void onStartButtonToggle(QAbstractButton *button, quint16 channel, quint16 value, quint16 safeValue, QSlider *slider);
bool checkAlarms(); bool checkAlarms();
void debugLogChannelValues(); void debugLogChannelValues();

View File

@ -31,10 +31,29 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1">
<widget class="QGraphicsView" name="vehicleView">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QStackedWidget" name="calibrationStack"> <widget class="QStackedWidget" name="calibrationStack">
<property name="currentIndex"> <property name="currentIndex">
<number>4</number> <number>2</number>
</property> </property>
<widget class="QWidget" name="intro"> <widget class="QWidget" name="intro">
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
@ -133,7 +152,7 @@ p, li { white-space: pre-wrap; }
<item> <item>
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This step calibrates&lt;span style=&quot; font-weight:600;&quot;&gt; the center position of the servo&lt;/span&gt;. To set the center position for this servo, press the Start button below and slide the slider to center the servo. &lt;/p&gt;&lt;p&gt;When done press button again to stop.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This step calibrates&lt;span style=&quot; font-weight:600;&quot;&gt; the minimum, center and maximum angle of the servo&lt;/span&gt;. To set the angles for this servo, press the Start button below and slide the slider for the angle to set. The servo will follow the sliders position. &lt;br/&gt;When done press button again to stop.&lt;/p&gt;&lt;p&gt;Check Reverse to reverse servo action.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
@ -144,47 +163,435 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QSlider" name="servoCenterSlider"> <spacer name="verticalSpacer">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimum">
<number>600</number>
</property>
<property name="maximum">
<number>2400</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="pageStep">
<number>10</number>
</property>
<property name="value">
<number>1500</number>
</property>
<property name="tracking">
<bool>true</bool>
</property>
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="invertedAppearance"> <property name="sizeHint" stdset="0">
<bool>false</bool> <size>
</property> <width>20</width>
<property name="invertedControls"> <height>40</height>
<bool>false</bool> </size>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>40</number>
</property> </property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QFormLayout" name="formLayout">
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>6</number>
</property>
<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 row="0" column="1">
<widget class="QSlider" name="servoMinAngleSlider">
<property name="styleSheet">
<string notr="true">QSlider::groove:horizontal {
border: 1px solid rgb(196, 196, 196);
background: white;
height: 6px;
border-radius: 2px;
margin 10px 10px;
}
QSlider::add-page:horizontal {
background: #fff;
border: 1px solid #777;
height: 1px;
border-radius: 4px;
}
QSlider::add-page:horizontal:disabled {
background: #eee;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::sub-page:horizontal {
background: rgb(78, 147, 246);
border: 1px solid #777;
height: 1px;
border-radius: 4px;
}
QSlider::sub-page:horizontal:disabled {
background: #ccc;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::handle:horizontal {
background: rgb(196, 196, 196);
width: 18px;
height: 28px;
margin: -2px 0;
border-radius: 3px;
border: 1px solid #777;
}
QSlider::groove:vertical {
border: 1px solid rgb(196, 196, 196);
background: white;
width: 6px;
border-radius: 2px;
margin 0px -10px;
margin-top: 5px;
margin-bottom: 5px;
}
QSlider::sub-page:vertical {
background: #fff;
border: 1px solid #777;
width: 1px;
border-radius: 4px;
}
QSlider::sub-page:vertical:disabled {
background: #eee;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::add-page:vertical {
background: rgb(78, 147, 246);
border: 1px solid #777;
width: 1px;
border-radius: 4px;
}
QSlider::add-page:vertical:disabled {
background: #ccc;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::handle:vertical {
background: rgb(196, 196, 196);
width: 18px;
margin: -6 -6;
border-radius: 3px;
border: 1px solid #777;
}
QSlider::handle:vertical:hover {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #fff, stop:1 #ddd);
border: 1px solid #444;
border-radius: 4px;
}
QSlider::handle:horizontal:hover {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #fff, stop:1 #ddd);
border: 1px solid #444;
border-radius: 4px;
}</string>
</property>
<property name="minimum">
<number>600</number>
</property>
<property name="maximum">
<number>2400</number>
</property>
<property name="value">
<number>1500</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="servoCenterAngleSlider">
<property name="styleSheet">
<string notr="true">QSlider::groove:horizontal {
border: 1px solid rgb(196, 196, 196);
background: white;
height: 6px;
border-radius: 2px;
margin 10px 10px;
}
QSlider::add-page:horizontal {
background: rgb(78, 147, 246);
border: 1px solid #777;
height: 1px;
border-radius: 4px;
}
QSlider::add-page:horizontal:disabled {
background: #eee;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::sub-page:horizontal {
background: rgb(78, 147, 246);
border: 1px solid #777;
height: 1px;
border-radius: 4px;
}
QSlider::sub-page:horizontal:disabled {
background: #eee;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::handle:horizontal {
background: rgb(196, 196, 196);
width: 18px;
height: 28px;
margin: -2px 0;
border-radius: 3px;
border: 1px solid #777;
}
QSlider::groove:vertical {
border: 1px solid rgb(196, 196, 196);
background: white;
width: 6px;
border-radius: 2px;
margin 0px -10px;
margin-top: 5px;
margin-bottom: 5px;
}
QSlider::sub-page:vertical {
background: #fff;
border: 1px solid #777;
width: 1px;
border-radius: 4px;
}
QSlider::sub-page:vertical:disabled {
background: #eee;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::add-page:vertical {
background: rgb(78, 147, 246);
border: 1px solid #777;
width: 1px;
border-radius: 4px;
}
QSlider::add-page:vertical:disabled {
background: #ccc;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::handle:vertical {
background: rgb(196, 196, 196);
width: 18px;
margin: -6 -6;
border-radius: 3px;
border: 1px solid #777;
}
QSlider::handle:vertical:hover {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #fff, stop:1 #ddd);
border: 1px solid #444;
border-radius: 4px;
}
QSlider::handle:horizontal:hover {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #fff, stop:1 #ddd);
border: 1px solid #444;
border-radius: 4px;
}</string>
</property>
<property name="minimum">
<number>600</number>
</property>
<property name="maximum">
<number>2400</number>
</property>
<property name="value">
<number>1500</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="servoMaxAngleSlider">
<property name="styleSheet">
<string notr="true">QSlider::groove:horizontal {
border: 1px solid rgb(196, 196, 196);
background: white;
height: 6px;
border-radius: 2px;
margin 10px 10px;
}
QSlider::sub-page:horizontal {
background: #fff;
border: 1px solid #777;
height: 1px;
border-radius: 4px;
}
QSlider::sub-page:horizontal:disabled {
background: #eee;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::add-page:horizontal {
background: rgb(78, 147, 246);
border: 1px solid #777;
height: 1px;
border-radius: 4px;
}
QSlider::add-page:horizontal:disabled {
background: #ccc;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::handle:horizontal {
background: rgb(196, 196, 196);
width: 18px;
height: 28px;
margin: -2px 0;
border-radius: 3px;
border: 1px solid #777;
}
QSlider::groove:vertical {
border: 1px solid rgb(196, 196, 196);
background: white;
width: 6px;
border-radius: 2px;
margin 0px -10px;
margin-top: 5px;
margin-bottom: 5px;
}
QSlider::sub-page:vertical {
background: #fff;
border: 1px solid #777;
width: 1px;
border-radius: 4px;
}
QSlider::sub-page:vertical:disabled {
background: #eee;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::add-page:vertical {
background: rgb(78, 147, 246);
border: 1px solid #777;
width: 1px;
border-radius: 4px;
}
QSlider::add-page:vertical:disabled {
background: #ccc;
border: 1px solid #999;
width: 1px;
border-radius: 4px;
}
QSlider::handle:vertical {
background: rgb(196, 196, 196);
width: 18px;
margin: -6 -6;
border-radius: 3px;
border: 1px solid #777;
}
QSlider::handle:vertical:hover {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #fff, stop:1 #ddd);
border: 1px solid #444;
border-radius: 4px;
}
QSlider::handle:horizontal:hover {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #fff, stop:1 #ddd);
border: 1px solid #444;
border-radius: 4px;
}</string>
</property>
<property name="minimum">
<number>600</number>
</property>
<property name="maximum">
<number>2400</number>
</property>
<property name="value">
<number>1500</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="reverseCheckbox">
<property name="text">
<string>Reverse</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Min</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Center</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Max</string>
</property>
</widget>
</item>
</layout>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="servoCenterButton"> <widget class="QPushButton" name="servoButton">
<property name="text"> <property name="text">
<string>Start</string> <string>Start</string>
</property> </property>
@ -198,234 +605,10 @@ p, li { white-space: pre-wrap; }
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="servoMin">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;To save the servo and other hardware from damage we have to set the max and min angles for the servo. &lt;/p&gt;&lt;p&gt;To set &lt;span style=&quot; font-weight:600;&quot;&gt;the minimum angle for the servo&lt;/span&gt;, press the Start button below and select the top slider and slide it to the left until min angle is reached.&lt;/p&gt;&lt;p&gt;When done press button again to stop.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="servoMinAngleSlider">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimum">
<number>600</number>
</property>
<property name="maximum">
<number>2400</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="pageStep">
<number>10</number>
</property>
<property name="value">
<number>1500</number>
</property>
<property name="tracking">
<bool>true</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>40</number>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="servoMinAngleButton">
<property name="text">
<string>Start</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="servoMax">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;To set &lt;span style=&quot; font-weight:600;&quot;&gt;the maximum angle for the servo&lt;/span&gt;, press the Start button below and select the top slider and slide it to the right until max angle is reached.&lt;/p&gt;&lt;p&gt;When done press button again to stop.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="servoMaxAngleSlider">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimum">
<number>600</number>
</property>
<property name="maximum">
<number>2400</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="pageStep">
<number>10</number>
</property>
<property name="value">
<number>1500</number>
</property>
<property name="tracking">
<bool>true</bool>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>40</number>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="servoMaxAngleButton">
<property name="text">
<string>Start</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="1" column="1">
<widget class="QGraphicsView" name="vehicleView">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>
<connections> <connections/>
<connection>
<sender>motorNeutralButton</sender>
<signal>toggled(bool)</signal>
<receiver>motorNeutralSlider</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>147</x>
<y>291</y>
</hint>
<hint type="destinationlabel">
<x>150</x>
<y>249</y>
</hint>
</hints>
</connection>
<connection>
<sender>servoMinAngleButton</sender>
<signal>toggled(bool)</signal>
<receiver>servoMinAngleSlider</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>147</x>
<y>291</y>
</hint>
<hint type="destinationlabel">
<x>150</x>
<y>249</y>
</hint>
</hints>
</connection>
<connection>
<sender>servoMaxAngleButton</sender>
<signal>toggled(bool)</signal>
<receiver>servoMaxAngleSlider</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>147</x>
<y>291</y>
</hint>
<hint type="destinationlabel">
<x>150</x>
<y>249</y>
</hint>
</hints>
</connection>
<connection>
<sender>servoCenterButton</sender>
<signal>toggled(bool)</signal>
<receiver>servoCenterSlider</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>147</x>
<y>291</y>
</hint>
<hint type="destinationlabel">
<x>150</x>
<y>249</y>
</hint>
</hints>
</connection>
</connections>
</ui> </ui>

View File

@ -1,7 +1,7 @@
# We use python to extract git version info and generate some other files, # We use python to extract git version info and generate some other files,
# but it may be installed locally. The expected python version should be # but it may be installed locally. The expected python version should be
# kept in sync with make/tools.mk. # kept in sync with make/tools.mk.
PYTHON_DIR = qt-5.3.1/Tools/mingw48_32/opt/bin PYTHON_DIR = qt-5.3.1/Tools/mingw482_32/opt/bin
ROOT_DIR = $$GCS_SOURCE_TREE/../.. ROOT_DIR = $$GCS_SOURCE_TREE/../..
@ -15,7 +15,12 @@ OPENPILOT_TOOLS_DIR = $$(OPENPILOT_TOOLS_DIR)
PYTHON = \"$$ROOT_DIR/tools/$$PYTHON_DIR/python\" PYTHON = \"$$ROOT_DIR/tools/$$PYTHON_DIR/python\"
} else { } else {
# not found, hope it's in the path... # not found, hope it's in the path...
PYTHON = \"$$(PYTHON)\" PYTHON_VER = "$$system(python --version 2>&1)"
contains(PYTHON_VER, "Python 2.*") {
PYTHON = \"python\"
} else {
PYTHON = \"python2\"
}
} }
} }