29 #include "ui_outputcalibrationpage.h"
30 #include "systemalarms.h"
36 , m_vehicleBoundsItem(nullptr)
37 , m_currentWizardIndex(-1)
38 , m_calibrationUtil(nullptr)
42 m_vehicleRenderer =
new QSvgRenderer();
43 if (QFile::exists(QString(
":/setupwizard/resources/multirotor-shapes.svg"))
44 && m_vehicleRenderer->load(QString(
":/setupwizard/resources/multirotor-shapes.svg"))
45 && m_vehicleRenderer->isValid()) {
46 m_vehicleScene =
new QGraphicsScene(
this);
47 ui->vehicleView->setScene(m_vehicleScene);
53 if (m_calibrationUtil) {
54 delete m_calibrationUtil;
55 m_calibrationUtil =
nullptr;
60 void OutputCalibrationPage::setupVehicle()
63 m_wizardIndexes.clear();
64 m_vehicleElementIds.clear();
65 m_vehicleHighlightElementIndexes.clear();
66 m_channelIndex.clear();
67 m_currentWizardIndex = 0;
68 m_vehicleScene->clear();
69 switch (
getWizard()->getVehicleSubType()) {
71 m_wizardIndexes << 0 << 1 << 1 << 1 << 2 << 3 << 4;
72 m_vehicleElementIds <<
"tri"
78 m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 4 << 4;
79 m_channelIndex << 0 << 0 << 1 << 2 << 3 << 3 << 3;
80 m_actuatorSettings[3].channelMin = 1500;
81 m_actuatorSettings[3].channelNeutral = 1500;
82 m_actuatorSettings[3].channelMax = 1500;
86 m_wizardIndexes << 0 << 1 << 1 << 1 << 1;
87 m_vehicleElementIds <<
"quad-x"
93 m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4;
94 m_channelIndex << 0 << 0 << 1 << 2 << 3;
97 m_wizardIndexes << 0 << 1 << 1 << 1 << 1;
98 m_vehicleElementIds <<
"quad-p"
104 m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4;
105 m_channelIndex << 0 << 0 << 1 << 2 << 3;
108 m_wizardIndexes << 0 << 1 << 1 << 1 << 1 << 1 << 1;
109 m_vehicleElementIds <<
"hexa"
117 m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 5 << 6;
118 m_channelIndex << 0 << 0 << 1 << 2 << 3 << 4 << 5;
121 m_wizardIndexes << 0 << 1 << 1 << 1 << 1 << 1 << 1;
122 m_vehicleElementIds <<
"hexa-y6"
130 m_vehicleHighlightElementIndexes << 0 << 2 << 1 << 4 << 3 << 6 << 5;
131 m_channelIndex << 0 << 0 << 1 << 2 << 3 << 4 << 5;
134 m_wizardIndexes << 0 << 1 << 1 << 1 << 1 << 1 << 1;
135 m_vehicleElementIds <<
"hexa-h"
143 m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 5 << 6;
144 m_channelIndex << 0 << 0 << 1 << 2 << 3 << 4 << 5;
151 helper.setupVehicle(
false);
153 if (m_calibrationUtil) {
154 delete m_calibrationUtil;
155 m_calibrationUtil =
nullptr;
162 void OutputCalibrationPage::setupVehicleItems()
164 m_vehicleItems.clear();
165 m_vehicleBoundsItem =
new QGraphicsSvgItem();
166 m_vehicleBoundsItem->setSharedRenderer(m_vehicleRenderer);
167 m_vehicleBoundsItem->setElementId(m_vehicleElementIds[0]);
168 m_vehicleBoundsItem->setZValue(-1);
169 m_vehicleBoundsItem->setOpacity(0);
170 m_vehicleScene->addItem(m_vehicleBoundsItem);
172 QRectF parentBounds = m_vehicleRenderer->boundsOnElement(m_vehicleElementIds[0]);
174 for (
int i = 1;
i < m_vehicleElementIds.size();
i++) {
175 QGraphicsSvgItem *item =
new QGraphicsSvgItem();
176 item->setSharedRenderer(m_vehicleRenderer);
177 item->setElementId(m_vehicleElementIds[
i]);
179 item->setOpacity(1.0);
181 QRectF itemBounds = m_vehicleRenderer->boundsOnElement(m_vehicleElementIds[i]);
182 item->setPos(itemBounds.x() - parentBounds.x(), itemBounds.y() - parentBounds.y());
184 m_vehicleScene->addItem(item);
185 m_vehicleItems << item;
189 void OutputCalibrationPage::startWizard()
191 ui->calibrationStack->setCurrentIndex(m_wizardIndexes[0]);
192 setupVehicleHighlightedPart();
194 QPointer<SetupWizard> wizard =
getWizard();
196 switch (wizard->getESCType()) {
198 ui->motorNeutralSlider->setRange(125, 152);
199 ui->motorNeutralSlider->setPageStep(1);
200 ui->motorNeutralSlider->setSingleStep(1);
203 ui->motorNeutralSlider->setRange(125 / 3, 152 / 3);
204 ui->motorNeutralSlider->setPageStep(1);
205 ui->motorNeutralSlider->setSingleStep(1);
211 ui->motorNeutralSlider->setRange(48, 400);
212 ui->motorNeutralSlider->setPageStep(1);
213 ui->motorNeutralSlider->setSingleStep(1);
220 void OutputCalibrationPage::setupVehicleHighlightedPart()
222 qreal dimOpaque = m_currentWizardIndex == 0 ? 1.0 : 0.3;
223 qreal highlightOpaque = 1.0;
224 int highlightedIndex = m_vehicleHighlightElementIndexes[m_currentWizardIndex];
226 for (
int i = 0; i < m_vehicleItems.size(); i++) {
227 QGraphicsSvgItem *item = m_vehicleItems[
i];
228 item->setOpacity((highlightedIndex == i) ? highlightOpaque : dimOpaque);
232 void OutputCalibrationPage::setWizardPage()
234 qDebug() <<
"Wizard index: " << m_currentWizardIndex;
237 QApplication::processEvents();
239 int currentPageIndex = m_wizardIndexes[m_currentWizardIndex];
240 qDebug() <<
"Current page: " << currentPageIndex;
241 ui->calibrationStack->setCurrentIndex(currentPageIndex);
243 int currentChannel = getCurrentChannel();
244 qDebug() <<
"Current channel: " << currentChannel;
245 if (currentChannel >= 0) {
246 if (currentPageIndex == 1) {
247 ui->motorNeutralSlider->setValue(m_actuatorSettings[currentChannel].channelNeutral);
248 }
else if (currentPageIndex == 2) {
249 ui->servoCenterSlider->setValue(m_actuatorSettings[currentChannel].channelNeutral);
250 }
else if (currentPageIndex == 3) {
251 ui->servoMinAngleSlider->setMaximum(m_actuatorSettings[currentChannel].channelNeutral);
252 ui->servoMinAngleSlider->setValue(m_actuatorSettings[currentChannel].channelMin);
253 }
else if (currentPageIndex == 4) {
254 ui->servoMaxAngleSlider->setMinimum(m_actuatorSettings[currentChannel].channelNeutral);
255 ui->servoMaxAngleSlider->setValue(m_actuatorSettings[currentChannel].channelMax);
258 setupVehicleHighlightedPart();
263 if (m_vehicleScene) {
275 m_currentWizardIndex++;
284 if (m_vehicleBoundsItem) {
285 ui->vehicleView->setSceneRect(m_vehicleBoundsItem->boundingRect());
286 ui->vehicleView->fitInView(m_vehicleBoundsItem, Qt::KeepAspectRatio);
293 if (m_vehicleBoundsItem) {
294 ui->vehicleView->setSceneRect(m_vehicleBoundsItem->boundingRect());
295 ui->vehicleView->fitInView(m_vehicleBoundsItem, Qt::KeepAspectRatio);
301 if (m_currentWizardIndex > 0) {
302 m_currentWizardIndex--;
309 quint16 OutputCalibrationPage::getCurrentChannel()
311 return m_channelIndex[m_currentWizardIndex];
314 void OutputCalibrationPage::enableButtons(
bool enable)
316 getWizard()->button(QWizard::NextButton)->setEnabled(enable);
317 getWizard()->button(QWizard::CustomButton1)->setEnabled(enable);
318 getWizard()->button(QWizard::CancelButton)->setEnabled(enable);
319 getWizard()->button(QWizard::BackButton)->setEnabled(enable);
320 QApplication::processEvents();
323 void OutputCalibrationPage::on_motorNeutralButton_toggled(
bool checked)
325 ui->motorNeutralButton->setText(checked ? tr(
"Stop") : tr(
"Start"));
326 quint16 channel = getCurrentChannel();
327 onStartButtonToggle(ui->motorNeutralButton, channel, m_actuatorSettings[channel].channelNeutral,
328 m_actuatorSettings[channel].channelMin, ui->motorNeutralSlider);
331 void OutputCalibrationPage::onStartButtonToggle(QAbstractButton *button, quint16 channel,
332 quint16 value, quint16 safeValue, QSlider *slider)
334 if (button->isChecked()) {
336 enableButtons(
false);
338 slider->setValue(value);
341 button->setChecked(
false);
347 debugLogChannelValues();
350 bool OutputCalibrationPage::checkAlarms()
355 Q_ASSERT(uavObjectManager);
356 SystemAlarms *systemAlarms = SystemAlarms::GetInstance(uavObjectManager);
357 Q_ASSERT(systemAlarms);
358 SystemAlarms::DataFields
data = systemAlarms->getData();
360 if (data.Alarm[SystemAlarms::ALARM_ACTUATOR] != SystemAlarms::ALARM_OK) {
361 QMessageBox mbox(
this);
362 mbox.setText(QString(tr(
"The actuator module is in an error state.\n\n"
363 "Please make sure the correct firmware version is used then "
364 "restart the wizard and try again. If the problem persists please "
365 "consult the openpilot.org support forum.")));
366 mbox.setStandardButtons(QMessageBox::Ok);
367 mbox.setIcon(QMessageBox::Critical);
374 getWizard()->setWindowIcon(qApp->windowIcon());
381 void OutputCalibrationPage::debugLogChannelValues()
383 quint16 channel = getCurrentChannel();
385 qDebug() <<
"ChannelMin : " << m_actuatorSettings[channel].channelMin;
386 qDebug() <<
"ChannelNeutral: " << m_actuatorSettings[channel].channelNeutral;
387 qDebug() <<
"ChannelMax : " << m_actuatorSettings[channel].channelMax;
390 void OutputCalibrationPage::on_motorNeutralSlider_valueChanged(
int value)
393 if (ui->motorNeutralButton->isChecked()) {
394 quint16 value = ui->motorNeutralSlider->value();
396 m_actuatorSettings[getCurrentChannel()].channelNeutral = value;
397 debugLogChannelValues();
401 void OutputCalibrationPage::on_servoCenterButton_toggled(
bool checked)
403 ui->servoCenterButton->setText(checked ? tr(
"Stop") : tr(
"Start"));
404 quint16 channel = getCurrentChannel();
405 quint16 safeValue = m_actuatorSettings[channel].channelNeutral;
406 onStartButtonToggle(ui->servoCenterButton, channel, safeValue, safeValue,
407 ui->servoCenterSlider);
410 void OutputCalibrationPage::on_servoCenterSlider_valueChanged(
int position)
413 if (ui->servoCenterButton->isChecked()) {
414 quint16 value = ui->servoCenterSlider->value();
416 quint16 channel = getCurrentChannel();
417 m_actuatorSettings[channel].channelNeutral = value;
420 if (value < m_actuatorSettings[channel].channelMin) {
421 m_actuatorSettings[channel].channelMin = value;
423 if (value > m_actuatorSettings[channel].channelMax) {
424 m_actuatorSettings[channel].channelMax = value;
426 debugLogChannelValues();
430 void OutputCalibrationPage::on_servoMinAngleButton_toggled(
bool checked)
432 ui->servoMinAngleButton->setText(checked ? tr(
"Stop") : tr(
"Start"));
433 quint16 channel = getCurrentChannel();
434 quint16 safeValue = m_actuatorSettings[channel].channelNeutral;
435 onStartButtonToggle(ui->servoMinAngleButton, channel, m_actuatorSettings[channel].channelMin,
436 safeValue, ui->servoMinAngleSlider);
439 void OutputCalibrationPage::on_servoMinAngleSlider_valueChanged(
int position)
442 if (ui->servoMinAngleButton->isChecked()) {
443 quint16 value = ui->servoMinAngleSlider->value();
445 m_actuatorSettings[getCurrentChannel()].channelMin = value;
446 debugLogChannelValues();
450 void OutputCalibrationPage::on_servoMaxAngleButton_toggled(
bool checked)
452 ui->servoMaxAngleButton->setText(checked ? tr(
"Stop") : tr(
"Start"));
453 quint16 channel = getCurrentChannel();
454 quint16 safeValue = m_actuatorSettings[channel].channelNeutral;
455 onStartButtonToggle(ui->servoMaxAngleButton, channel, m_actuatorSettings[channel].channelMax,
456 safeValue, ui->servoMaxAngleSlider);
459 void OutputCalibrationPage::on_servoMaxAngleSlider_valueChanged(
int position)
462 if (ui->servoMaxAngleButton->isChecked()) {
463 quint16 value = ui->servoMaxAngleSlider->value();
465 m_actuatorSettings[getCurrentChannel()].channelMax = value;
466 debugLogChannelValues();
OutputCalibrationPage(SetupWizard *wizard, QWidget *parent=nullptr)
void showEvent(QShowEvent *event)
The SetupWizard class is the main interface to the setup wizard. It provides selects the sequence of ...
SetupWizard * getWizard() const
Core plugin system that manages the plugins, their life cycle and their registered objects...
void resizeEvent(QResizeEvent *event)
void setActuatorSettings(QList< actuatorChannelSettings > actuatorSettings)
void setChannelOutputValue(quint16 value)
QList< actuatorChannelSettings > getActuatorSettings() const
void startChannelOutput(quint16 channel, quint16 safeValue)
The VehicleConfigurationHelper class provides an interface between the settings selected in the wizar...