28 #include "physical_constants.h"
31 #include <QStringList>
34 #include <QVBoxLayout>
35 #include <QPushButton>
38 #include <QMessageBox>
40 #include "actuatorcommand.h"
41 #include "mixersettings.h"
47 SwashLvlConfigurationInProgress = 0;
49 SwashLvlServoInterlock = 0;
50 updatingFromHardware =
false;
51 updatingToHardware =
false;
53 m_ccpm =
new Ui_CcpmWidget();
54 m_ccpm->setupUi(
this);
57 m_ccpm->SwashplateImage->setScene(
new QGraphicsScene(
this));
59 m_ccpm->SwashLvlSwashplateImage->setScene(m_ccpm->SwashplateImage->scene());
60 m_ccpm->SwashLvlSwashplateImage->setSceneRect(-50, -50, 500, 500);
64 m_ccpm->SwashplateImage->setSceneRect(-50, -30, 500, 500);
67 QSvgRenderer *renderer =
new QSvgRenderer();
68 renderer->load(QString(
":/configgadget/images/ccpm_setup.svg"));
70 SwashplateImg =
new QGraphicsSvgItem();
71 SwashplateImg->setSharedRenderer(renderer);
72 SwashplateImg->setElementId(
"Swashplate");
73 SwashplateImg->setObjectName(
"Swashplate");
75 m_ccpm->SwashplateImage->scene()->addItem(SwashplateImg);
77 QFont serifFont(
"Times", 24, QFont::Bold);
80 pen.setStyle(Qt::DotLine);
82 pen.setBrush(Qt::gray);
83 pen.setCapStyle(Qt::RoundCap);
84 pen.setJoinStyle(Qt::RoundJoin);
86 QBrush brush(Qt::darkBlue);
91 pen2.setBrush(Qt::blue);
98 ServoNames <<
"ServoW"
103 for (i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) {
105 m_ccpm->SwashLvlSwashplateImage->scene()->addLine(0, 0, 100 * i, i * i * 100, pen);
107 Servos[
i] =
new QGraphicsSvgItem();
108 Servos[
i]->setSharedRenderer(renderer);
109 Servos[
i]->setElementId(ServoNames.at(i));
110 m_ccpm->SwashplateImage->scene()->addItem(Servos[i]);
112 ServosText[
i] =
new QGraphicsTextItem();
113 ServosText[
i]->setDefaultTextColor(Qt::yellow);
114 ServosText[
i]->setPlainText(QString(
"-"));
115 ServosText[
i]->setFont(serifFont);
117 ServosTextCircles[
i] =
new QGraphicsEllipseItem(1, 1, 30, 30);
118 ServosTextCircles[
i]->setBrush(brush);
119 ServosTextCircles[
i]->setPen(pen2);
120 m_ccpm->SwashplateImage->scene()->addItem(ServosTextCircles[i]);
121 m_ccpm->SwashplateImage->scene()->addItem(ServosText[i]);
123 SwashLvlSpinBoxes[
i] =
new QSpinBox;
124 m_ccpm->SwashLvlSwashplateImage->scene()->addWidget(SwashLvlSpinBoxes[i]);
125 SwashLvlSpinBoxes[
i]->setMaximum(10000);
126 SwashLvlSpinBoxes[
i]->setMinimum(0);
127 SwashLvlSpinBoxes[
i]->setValue(0);
134 m_ccpm->ccpmEngineChannel->setCurrentIndex(0);
136 m_ccpm->ccpmTailChannel->setCurrentIndex(0);
138 m_ccpm->ccpmServoWChannel->setCurrentIndex(0);
140 m_ccpm->ccpmServoXChannel->setCurrentIndex(0);
142 m_ccpm->ccpmServoYChannel->setCurrentIndex(0);
144 m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
147 Types << QString::fromUtf8(
"CCPM 2 Servo 90º") << QString::fromUtf8(
"CCPM 3 Servo 90º")
148 << QString::fromUtf8(
"CCPM 4 Servo 90º") << QString::fromUtf8(
"CCPM 3 Servo 120º")
149 << QString::fromUtf8(
"CCPM 3 Servo 140º") << QString::fromUtf8(
"FP 2 Servo 90º")
150 << QString::fromUtf8(
"Coax 2 Servo 90º") << QString::fromUtf8(
"Custom - User Angles")
151 << QString::fromUtf8(
"Custom - Advanced Settings");
152 m_ccpm->ccpmType->addItems(Types);
156 m_ccpm->ccpmType->setCurrentIndex(
157 m_ccpm->ccpmType->findText(QString::fromUtf8(
"CCPM 3 Servo 120º")));
164 refreshAirframeWidgetsValues(SystemSettings::AIRFRAMETYPE_HELICP);
171 m_ccpm->PitchCurve->initLinearCurve(5, 1.0, -1.0);
175 connect(m_ccpm->ccpmAngleW, SIGNAL(valueChanged(
double)),
this, SLOT(ccpmSwashplateUpdate()));
176 connect(m_ccpm->ccpmAngleX, SIGNAL(valueChanged(
double)),
this, SLOT(ccpmSwashplateUpdate()));
177 connect(m_ccpm->ccpmAngleY, SIGNAL(valueChanged(
double)),
this, SLOT(ccpmSwashplateUpdate()));
178 connect(m_ccpm->ccpmAngleZ, SIGNAL(valueChanged(
double)),
this, SLOT(ccpmSwashplateUpdate()));
179 connect(m_ccpm->ccpmCorrectionAngle, SIGNAL(valueChanged(
double)),
this,
180 SLOT(ccpmSwashplateUpdate()));
181 connect(m_ccpm->ccpmServoWChannel, SIGNAL(currentIndexChanged(
int)),
this,
182 SLOT(ccpmSwashplateUpdate()));
183 connect(m_ccpm->ccpmServoXChannel, SIGNAL(currentIndexChanged(
int)),
this,
184 SLOT(ccpmSwashplateUpdate()));
185 connect(m_ccpm->ccpmServoYChannel, SIGNAL(currentIndexChanged(
int)),
this,
186 SLOT(ccpmSwashplateUpdate()));
187 connect(m_ccpm->ccpmServoZChannel, SIGNAL(currentIndexChanged(
int)),
this,
188 SLOT(ccpmSwashplateUpdate()));
189 connect(m_ccpm->ccpmEngineChannel, SIGNAL(currentIndexChanged(
int)),
this, SLOT(UpdateMixer()));
190 connect(m_ccpm->ccpmTailChannel, SIGNAL(currentIndexChanged(
int)),
this, SLOT(UpdateMixer()));
191 connect(m_ccpm->ccpmRevoSlider, SIGNAL(valueChanged(
int)),
this, SLOT(UpdateMixer()));
192 connect(m_ccpm->ccpmREVOspinBox, SIGNAL(valueChanged(
int)),
this, SLOT(UpdateMixer()));
193 connect(m_ccpm->ccpmCollectiveSlider, SIGNAL(valueChanged(
int)),
this, SLOT(UpdateMixer()));
194 connect(m_ccpm->ccpmCollectivespinBox, SIGNAL(valueChanged(
int)),
this, SLOT(UpdateMixer()));
195 connect(m_ccpm->ccpmType, SIGNAL(currentIndexChanged(
int)),
this, SLOT(UpdateType()));
196 connect(m_ccpm->ccpmSingleServo, SIGNAL(currentIndexChanged(
int)),
this, SLOT(UpdateType()));
198 connect(m_ccpm->SwashLvlStartButton, SIGNAL(clicked()),
this,
199 SLOT(SwashLvlStartButtonPressed()));
200 connect(m_ccpm->SwashLvlNextButton, SIGNAL(clicked()),
this, SLOT(SwashLvlNextButtonPressed()));
201 connect(m_ccpm->SwashLvlCancelButton, SIGNAL(clicked()),
this,
202 SLOT(SwashLvlCancelButtonPressed()));
203 connect(m_ccpm->SwashLvlFinishButton, SIGNAL(clicked()),
this,
204 SLOT(SwashLvlFinishButtonPressed()));
206 connect(m_ccpm->ccpmCollectivePassthrough, SIGNAL(clicked()),
this,
207 SLOT(SetUIComponentVisibilities()));
208 connect(m_ccpm->ccpmLinkCyclic, SIGNAL(clicked()),
this, SLOT(SetUIComponentVisibilities()));
209 connect(m_ccpm->ccpmLinkRoll, SIGNAL(clicked()),
this, SLOT(SetUIComponentVisibilities()));
211 ccpmSwashplateRedraw();
219 void ConfigCcpmWidget::setupUI(SystemSettings::AirframeTypeOptions frameType)
226 configData->
heli.Throttle = 0;
227 configData->
heli.Tail = 0;
228 configData->
heli.ServoIndexW = 0;
229 configData->
heli.ServoIndexX = 0;
230 configData->
heli.ServoIndexY = 0;
231 configData->
heli.ServoIndexZ = 0;
234 QStringList ConfigCcpmWidget::getChannelDescriptions()
237 QStringList channelDesc;
240 for (i = 0; i < (int)(ActuatorCommand::CHANNEL_NUMELEM); i++) {
241 channelDesc.append(QString(
"-"));
246 heliGUISettingsStruct heli = configData.
heli;
248 if (heli.Throttle > 0)
249 channelDesc[heli.Throttle - 1] = QString(
"Throttle");
251 channelDesc[heli.Tail - 1] = QString(
"Tail");
253 switch (heli.FirstServoIndex) {
255 if (heli.ServoIndexW > 0)
256 channelDesc[heli.ServoIndexW - 1] = QString(
"Elevator");
257 if (heli.ServoIndexX > 0)
258 channelDesc[heli.ServoIndexX - 1] = QString(
"Roll1");
259 if (heli.ServoIndexY > 0)
260 channelDesc[heli.ServoIndexY - 1] = QString(
"Roll2");
264 if (heli.ServoIndexW > 0)
265 channelDesc[heli.ServoIndexW - 1] = QString(
"ServoW");
266 if (heli.ServoIndexX > 0)
267 channelDesc[heli.ServoIndexX - 1] = QString(
"ServoX");
268 if (heli.ServoIndexY > 0)
269 channelDesc[heli.ServoIndexY - 1] = QString(
"ServoY");
273 if (heli.ServoIndexW > 0)
274 channelDesc[heli.ServoIndexW - 1] = QString(
"Elevator");
275 if (heli.ServoIndexX > 0)
276 channelDesc[heli.ServoIndexX - 1] = QString(
"Roll1");
277 if (heli.ServoIndexY > 0)
278 channelDesc[heli.ServoIndexY - 1] = QString(
"Roll2");
282 if (heli.ServoIndexW > 0)
283 channelDesc[heli.ServoIndexW - 1] = QString(
"ServoW");
284 if (heli.ServoIndexX > 0)
285 channelDesc[heli.ServoIndexX - 1] = QString(
"ServoX");
286 if (heli.ServoIndexY > 0)
287 channelDesc[heli.ServoIndexY - 1] = QString(
"ServoY");
290 if (heli.ServoIndexZ > 0)
291 channelDesc[heli.ServoIndexZ - 1] = QString(
"ServoZ");
296 void ConfigCcpmWidget::UpdateType()
298 int TypeInt, SingleServoIndex, NumServosDefined;
299 double AdjustmentAngle = 0;
301 SetUIComponentVisibilities();
303 TypeInt = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex() - 1;
304 TypeText = m_ccpm->ccpmType->currentText();
305 SingleServoIndex = m_ccpm->ccpmSingleServo->currentIndex();
308 m_ccpm->ccpmAdvancedSettingsTable->setEnabled(TypeInt == 0);
309 m_ccpm->ccpmAdvancedSettingsTable->clearFocus();
312 m_ccpm->ccpmAngleW->setEnabled(TypeInt == 1);
313 m_ccpm->ccpmAngleX->setEnabled(TypeInt == 1);
314 m_ccpm->ccpmAngleY->setEnabled(TypeInt == 1);
315 m_ccpm->ccpmAngleZ->setEnabled(TypeInt == 1);
316 m_ccpm->ccpmCorrectionAngle->setEnabled(TypeInt != 0);
318 m_ccpm->ccpmServoWChannel->setEnabled(TypeInt > 0);
319 m_ccpm->ccpmServoXChannel->setEnabled(TypeInt > 0);
320 m_ccpm->ccpmServoYChannel->setEnabled(TypeInt > 0);
321 m_ccpm->ccpmServoZChannel->setEnabled(TypeInt > 0);
322 m_ccpm->ccpmSingleServo->setEnabled(TypeInt > 1);
324 m_ccpm->ccpmEngineChannel->setEnabled(TypeInt > 0);
325 m_ccpm->ccpmTailChannel->setEnabled(TypeInt > 0);
326 m_ccpm->ccpmCollectiveSlider->setEnabled(TypeInt > 0);
327 m_ccpm->ccpmCollectivespinBox->setEnabled(TypeInt > 0);
328 m_ccpm->ccpmRevoSlider->setEnabled(TypeInt > 0);
329 m_ccpm->ccpmREVOspinBox->setEnabled(TypeInt > 0);
331 AdjustmentAngle = SingleServoIndex * 90;
333 m_ccpm->PitchCurve->setVisible(1);
335 NumServosDefined = 4;
337 if (TypeText.compare(QString::fromUtf8(
"CCPM 2 Servo 90º"), Qt::CaseInsensitive) == 0) {
338 m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0);
339 m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90, 360));
340 m_ccpm->ccpmAngleY->setValue(0);
341 m_ccpm->ccpmAngleZ->setValue(0);
342 m_ccpm->ccpmAngleY->setEnabled(0);
343 m_ccpm->ccpmAngleZ->setEnabled(0);
344 m_ccpm->ccpmServoYChannel->setCurrentIndex(0);
345 m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
346 m_ccpm->ccpmServoYChannel->setEnabled(0);
347 m_ccpm->ccpmServoZChannel->setEnabled(0);
348 NumServosDefined = 2;
350 }
else if (TypeText.compare(QString::fromUtf8(
"CCPM 3 Servo 90º"), Qt::CaseInsensitive) == 0) {
351 m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0);
352 m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90, 360));
353 m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 180, 360));
354 m_ccpm->ccpmAngleZ->setValue(0);
355 m_ccpm->ccpmAngleZ->setEnabled(0);
356 m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
357 m_ccpm->ccpmServoZChannel->setEnabled(0);
358 NumServosDefined = 3;
360 }
else if (TypeText.compare(QString::fromUtf8(
"CCPM 4 Servo 90º"), Qt::CaseInsensitive) == 0) {
361 m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0);
362 m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90, 360));
363 m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 180, 360));
364 m_ccpm->ccpmAngleZ->setValue(fmod(AdjustmentAngle + 270, 360));
365 m_ccpm->ccpmSingleServo->setEnabled(0);
366 m_ccpm->ccpmSingleServo->setCurrentIndex(0);
367 NumServosDefined = 4;
369 }
else if (TypeText.compare(QString::fromUtf8(
"CCPM 3 Servo 120º"), Qt::CaseInsensitive) == 0) {
370 m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0);
371 m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 120, 360));
372 m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 240, 360));
373 m_ccpm->ccpmAngleZ->setValue(0);
374 m_ccpm->ccpmAngleZ->setEnabled(0);
375 m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
376 m_ccpm->ccpmServoZChannel->setEnabled(0);
377 NumServosDefined = 3;
379 }
else if (TypeText.compare(QString::fromUtf8(
"CCPM 3 Servo 140º"), Qt::CaseInsensitive) == 0) {
380 m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0);
381 m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 140, 360));
382 m_ccpm->ccpmAngleY->setValue(fmod(AdjustmentAngle + 220, 360));
383 m_ccpm->ccpmAngleZ->setValue(0);
384 m_ccpm->ccpmAngleZ->setEnabled(0);
385 m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
386 m_ccpm->ccpmServoZChannel->setEnabled(0);
387 NumServosDefined = 3;
389 }
else if (TypeText.compare(QString::fromUtf8(
"FP 2 Servo 90º"), Qt::CaseInsensitive) == 0) {
390 m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0);
391 m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90, 360));
392 m_ccpm->ccpmAngleY->setValue(0);
393 m_ccpm->ccpmAngleZ->setValue(0);
394 m_ccpm->ccpmAngleY->setEnabled(0);
395 m_ccpm->ccpmAngleZ->setEnabled(0);
396 m_ccpm->ccpmServoYChannel->setCurrentIndex(0);
397 m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
398 m_ccpm->ccpmServoYChannel->setEnabled(0);
399 m_ccpm->ccpmServoZChannel->setEnabled(0);
401 m_ccpm->ccpmCollectivespinBox->setEnabled(0);
402 m_ccpm->ccpmCollectiveSlider->setEnabled(0);
403 m_ccpm->ccpmCollectivespinBox->setValue(0);
404 m_ccpm->ccpmCollectiveSlider->setValue(0);
405 m_ccpm->PitchCurve->setVisible(0);
406 NumServosDefined = 2;
407 }
else if (TypeText.compare(QString::fromUtf8(
"Coax 2 Servo 90º"), Qt::CaseInsensitive) == 0) {
408 m_ccpm->ccpmAngleW->setValue(AdjustmentAngle + 0);
409 m_ccpm->ccpmAngleX->setValue(fmod(AdjustmentAngle + 90, 360));
410 m_ccpm->ccpmAngleY->setValue(0);
411 m_ccpm->ccpmAngleZ->setValue(0);
412 m_ccpm->ccpmAngleY->setEnabled(0);
413 m_ccpm->ccpmAngleZ->setEnabled(0);
414 m_ccpm->ccpmServoYChannel->setCurrentIndex(0);
415 m_ccpm->ccpmServoZChannel->setCurrentIndex(0);
416 m_ccpm->ccpmServoYChannel->setEnabled(0);
417 m_ccpm->ccpmServoZChannel->setEnabled(0);
419 m_ccpm->ccpmCollectivespinBox->setEnabled(0);
420 m_ccpm->ccpmCollectiveSlider->setEnabled(0);
421 m_ccpm->ccpmCollectivespinBox->setValue(0);
422 m_ccpm->ccpmCollectiveSlider->setValue(0);
423 m_ccpm->PitchCurve->setVisible(0);
424 NumServosDefined = 2;
428 if (TypeText.compare(QString::fromUtf8(
"Coax 2 Servo 90º"), Qt::CaseInsensitive) == 0) {
429 m_ccpm->ccpmEngineLabel->setText(
"CW motor");
430 m_ccpm->ccpmTailLabel->setText(
"CCW motor");
432 m_ccpm->ccpmEngineLabel->setText(
"Engine");
433 m_ccpm->ccpmTailLabel->setText(
"Tail rotor");
437 m_ccpm->ccpmServoWLabel->setVisible(NumServosDefined >= 1);
438 m_ccpm->ccpmServoXLabel->setVisible(NumServosDefined >= 2);
439 m_ccpm->ccpmServoYLabel->setVisible(NumServosDefined >= 3);
440 m_ccpm->ccpmServoZLabel->setVisible(NumServosDefined >= 4);
441 m_ccpm->ccpmServoWChannel->setVisible(NumServosDefined >= 1);
442 m_ccpm->ccpmServoXChannel->setVisible(NumServosDefined >= 2);
443 m_ccpm->ccpmServoYChannel->setVisible(NumServosDefined >= 3);
444 m_ccpm->ccpmServoZChannel->setVisible(NumServosDefined >= 4);
447 m_ccpm->ccpmServoWLabel_2->setVisible(NumServosDefined >= 1);
448 m_ccpm->ccpmServoXLabel_2->setVisible(NumServosDefined >= 2);
449 m_ccpm->ccpmServoYLabel_2->setVisible(NumServosDefined >= 3);
450 m_ccpm->ccpmServoZLabel_2->setVisible(NumServosDefined >= 4);
451 m_ccpm->ccpmAngleW->setVisible(NumServosDefined >= 1);
452 m_ccpm->ccpmAngleX->setVisible(NumServosDefined >= 2);
453 m_ccpm->ccpmAngleY->setVisible(NumServosDefined >= 3);
454 m_ccpm->ccpmAngleZ->setVisible(NumServosDefined >= 4);
456 m_ccpm->ccpmAdvancedSettingsTable->resizeColumnsToContents();
457 for (
int i = 0; i < 6; i++) {
458 m_ccpm->ccpmAdvancedSettingsTable->setColumnWidth(
460 (m_ccpm->ccpmAdvancedSettingsTable->width()
461 - m_ccpm->ccpmAdvancedSettingsTable->verticalHeader()->width())
466 ccpmSwashplateUpdate();
469 void ConfigCcpmWidget::ccpmSwashplateRedraw()
471 double angle[CCPM_MAX_SWASH_SERVOS], CorrectionAngle,
x,
y, w,
h, radius, CenterX, CenterY;
472 int used[CCPM_MAX_SWASH_SERVOS], defined[CCPM_MAX_SWASH_SERVOS],
i;
475 double scale, xscale, yscale;
477 size = m_ccpm->SwashplateImage->rect();
478 xscale = size.width();
479 yscale = size.height();
484 m_ccpm->SwashplateImage->resetTransform();
485 m_ccpm->SwashplateImage->scale(scale, scale);
487 size = m_ccpm->SwashLvlSwashplateImage->rect();
488 xscale = size.width();
489 yscale = size.height();
494 m_ccpm->SwashLvlSwashplateImage->resetTransform();
495 m_ccpm->SwashLvlSwashplateImage->scale(scale, scale);
497 CorrectionAngle = m_ccpm->ccpmCorrectionAngle->value();
502 bounds = SwashplateImg->boundingRect();
504 SwashplateImg->setPos(CenterX - bounds.width() / 2, CenterY - bounds.height() / 2);
506 defined[0] = (m_ccpm->ccpmServoWChannel->isEnabled());
507 defined[1] = (m_ccpm->ccpmServoXChannel->isEnabled());
508 defined[2] = (m_ccpm->ccpmServoYChannel->isEnabled());
509 defined[3] = (m_ccpm->ccpmServoZChannel->isEnabled());
510 used[0] = ((m_ccpm->ccpmServoWChannel->currentIndex() > 0)
511 && (m_ccpm->ccpmServoWChannel->isEnabled()));
512 used[1] = ((m_ccpm->ccpmServoXChannel->currentIndex() > 0)
513 && (m_ccpm->ccpmServoXChannel->isEnabled()));
514 used[2] = ((m_ccpm->ccpmServoYChannel->currentIndex() > 0)
515 && (m_ccpm->ccpmServoYChannel->isEnabled()));
516 used[3] = ((m_ccpm->ccpmServoZChannel->currentIndex() > 0)
517 && (m_ccpm->ccpmServoZChannel->isEnabled()));
518 angle[0] = (CorrectionAngle + 180 + m_ccpm->ccpmAngleW->value()) *
DEG2RAD;
519 angle[1] = (CorrectionAngle + 180 + m_ccpm->ccpmAngleX->value()) *
DEG2RAD;
520 angle[2] = (CorrectionAngle + 180 + m_ccpm->ccpmAngleY->value()) *
DEG2RAD;
521 angle[3] = (CorrectionAngle + 180 + m_ccpm->ccpmAngleZ->value()) *
DEG2RAD;
523 for (i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) {
525 x = CenterX - (radius * sin(angle[i])) - 10.00;
526 y = CenterY + (radius * cos(angle[i])) - 10.00;
527 Servos[
i]->setPos(x, y);
528 Servos[
i]->setVisible(used[i] != 0);
531 bounds = ServosText[
i]->boundingRect();
532 x = CenterX - (radius * sin(angle[i])) - bounds.width() / 2;
533 y = CenterY + (radius * cos(angle[i])) - bounds.height() / 2;
535 ServosText[
i]->setPos(x, y);
536 ServosText[
i]->setVisible(used[i] != 0);
538 if (bounds.width() > bounds.height()) {
539 bounds.setHeight(bounds.width());
541 bounds.setWidth(bounds.height());
543 x = CenterX - (radius * sin(angle[i])) - bounds.width() / 2;
544 y = CenterY + (radius * cos(angle[i])) - bounds.height() / 2;
546 ServosTextCircles[
i]->setRect(bounds);
547 ServosTextCircles[
i]->setPos(x, y);
548 ServosTextCircles[
i]->setVisible(used[i] != 0);
550 w = SwashLvlSpinBoxes[
i]->width() / 2;
551 h = SwashLvlSpinBoxes[
i]->height() / 2;
552 radius = (215.00 + w +
h);
553 x = CenterX - (radius * sin(angle[i])) - w;
554 y = CenterY + (radius * cos(angle[i])) - h;
555 SwashLvlSpinBoxes[
i]->move(m_ccpm->SwashLvlSwashplateImage->mapFromScene(x, y));
556 SwashLvlSpinBoxes[
i]->setVisible(used[i] != 0);
559 x = CenterX - (radius * sin(angle[i]));
560 y = CenterY + (radius * cos(angle[i]));
561 ServoLines[
i]->setLine(CenterX, CenterY, x, y);
562 ServoLines[
i]->setVisible(defined[i] != 0);
570 void ConfigCcpmWidget::ccpmSwashplateUpdate()
572 ccpmSwashplateRedraw();
573 SetUIComponentVisibilities();
577 void ConfigCcpmWidget::UpdateMixer()
581 int i, j, ThisEnable[6];
582 float CollectiveConstant, PitchConstant, RollConstant, ThisAngle[6];
585 if (throwConfigError(SystemSettings::AIRFRAMETYPE_HELICP))
590 useCCPM = !(config.
heli.ccpmCollectivePassthroughState || !config.
heli.ccpmLinkCyclicState);
591 useCyclic = config.
heli.ccpmLinkRollState;
593 CollectiveConstant = (float)config.
heli.SliderValue0 / 100.00;
596 PitchConstant = 1 - CollectiveConstant;
597 RollConstant = PitchConstant;
599 PitchConstant = (float)config.
heli.SliderValue1 / 100.00;
602 RollConstant = PitchConstant;
604 RollConstant = (float)config.
heli.SliderValue2 / 100.00;
609 if (config.
heli.SwashplateType > 0) {
611 MixerChannelData[0] = m_ccpm->ccpmEngineChannel->currentIndex();
612 MixerChannelData[1] = m_ccpm->ccpmTailChannel->currentIndex();
613 MixerChannelData[2] = m_ccpm->ccpmServoWChannel->currentIndex();
614 MixerChannelData[3] = m_ccpm->ccpmServoXChannel->currentIndex();
615 MixerChannelData[4] = m_ccpm->ccpmServoYChannel->currentIndex();
616 MixerChannelData[5] = m_ccpm->ccpmServoZChannel->currentIndex();
619 ThisAngle[2] = m_ccpm->ccpmAngleW->value();
620 ThisAngle[3] = m_ccpm->ccpmAngleX->value();
621 ThisAngle[4] = m_ccpm->ccpmAngleY->value();
622 ThisAngle[5] = m_ccpm->ccpmAngleZ->value();
625 ThisEnable[2] = m_ccpm->ccpmServoWChannel->isEnabled();
626 ThisEnable[3] = m_ccpm->ccpmServoXChannel->isEnabled();
627 ThisEnable[4] = m_ccpm->ccpmServoYChannel->isEnabled();
628 ThisEnable[5] = m_ccpm->ccpmServoZChannel->isEnabled();
630 ServosText[0]->setPlainText(QString(
"%1").arg(MixerChannelData[2]));
631 ServosText[1]->setPlainText(QString(
"%1").arg(MixerChannelData[3]));
632 ServosText[2]->setPlainText(QString(
"%1").arg(MixerChannelData[4]));
633 ServosText[3]->setPlainText(QString(
"%1").arg(MixerChannelData[5]));
636 for (i = 0; i < 6; i++) {
637 if ((MixerChannelData[i] > 0) && ((ThisEnable[i]) || (i < 2))) {
638 m_ccpm->ccpmAdvancedSettingsTable->item(i, 0)->setText(
639 QString(
"%1").arg(MixerChannelData[i]));
643 m_ccpm->ccpmAdvancedSettingsTable->item(i, 1)->setText(
645 m_ccpm->ccpmAdvancedSettingsTable->item(i, 2)->setText(
646 QString(
"%1").arg(0));
647 m_ccpm->ccpmAdvancedSettingsTable->item(i, 3)->setText(
648 QString(
"%1").arg(0));
649 m_ccpm->ccpmAdvancedSettingsTable->item(i, 4)->setText(
650 QString(
"%1").arg(0));
652 if (TypeText.compare(QString::fromUtf8(
"Coax 2 Servo 90º"), Qt::CaseInsensitive)
654 m_ccpm->ccpmAdvancedSettingsTable->item(i, 5)->setText(
657 m_ccpm->ccpmAdvancedSettingsTable->item(i, 5)->setText(
658 QString(
"%1").arg(0));
661 if (TypeText.compare(QString::fromUtf8(
"Coax 2 Servo 90º"), Qt::CaseInsensitive)
663 m_ccpm->ccpmAdvancedSettingsTable->item(i, 1)->setText(
665 m_ccpm->ccpmAdvancedSettingsTable->item(i, 5)->setText(
668 m_ccpm->ccpmAdvancedSettingsTable->item(i, 1)->setText(
669 QString(
"%1").arg(0));
670 m_ccpm->ccpmAdvancedSettingsTable->item(i, 5)->setText(
674 m_ccpm->ccpmAdvancedSettingsTable->item(i, 2)->setText(
675 QString(
"%1").arg(0));
676 m_ccpm->ccpmAdvancedSettingsTable->item(i, 3)->setText(
677 QString(
"%1").arg(0));
678 m_ccpm->ccpmAdvancedSettingsTable->item(i, 4)->setText(
679 QString(
"%1").arg(0));
682 m_ccpm->ccpmAdvancedSettingsTable->item(i, 1)->setText(
683 QString(
"%1").arg(0));
684 m_ccpm->ccpmAdvancedSettingsTable->item(i, 2)->setText(QString(
"%1").arg(
686 m_ccpm->ccpmAdvancedSettingsTable->item(i, 3)->setText(QString(
"%1").arg(
688 * sin((180 + config.
heli.CorrectionAngle + ThisAngle[i])
690 m_ccpm->ccpmAdvancedSettingsTable->item(i, 4)->setText(
691 QString(
"%1").arg((
int)(
mixerScale * PitchConstant
692 * cos((config.
heli.CorrectionAngle + ThisAngle[i])
694 m_ccpm->ccpmAdvancedSettingsTable->item(i, 5)->setText(
695 QString(
"%1").arg(0));
698 for (j = 0; j < 6; j++)
699 m_ccpm->ccpmAdvancedSettingsTable->item(i, j)->setText(QString(
"-"));
703 for (i = 0; i < 6; i++) {
704 Channel = m_ccpm->ccpmAdvancedSettingsTable->item(i, 0)->text();
706 Channel = QString(
"9");
707 MixerChannelData[
i] = Channel.toInt();
712 SystemSettings::AirframeTypeOptions ConfigCcpmWidget::updateConfigObjects()
714 SystemSettings::AirframeTypeOptions airframeType = SystemSettings::AIRFRAMETYPE_HELICP;
719 if (updatingFromHardware ==
true)
722 updatingFromHardware =
true;
728 config.
heli.SwashplateType = m_ccpm->ccpmType->count() - m_ccpm->ccpmType->currentIndex() - 1;
729 config.
heli.FirstServoIndex = m_ccpm->ccpmSingleServo->currentIndex();
732 config.
heli.ccpmCollectivePassthroughState = m_ccpm->ccpmCollectivePassthrough->isChecked();
733 config.
heli.ccpmLinkCyclicState = m_ccpm->ccpmLinkCyclic->isChecked();
734 config.
heli.ccpmLinkRollState = m_ccpm->ccpmLinkRoll->isChecked();
735 useCCPM = !(config.
heli.ccpmCollectivePassthroughState || !config.
heli.ccpmLinkCyclicState);
736 useCyclic = config.
heli.ccpmLinkRollState;
739 config.
heli.CorrectionAngle = m_ccpm->ccpmCorrectionAngle->value();
743 config.
heli.SliderValue0 = m_ccpm->ccpmCollectiveSlider->value();
745 config.
heli.SliderValue0 = m_ccpm->ccpmCollectiveScale->value();
748 config.
heli.SliderValue1 = m_ccpm->ccpmCyclicScale->value();
750 config.
heli.SliderValue1 = m_ccpm->ccpmPitchScale->value();
752 config.
heli.SliderValue2 = m_ccpm->ccpmRollScale->value();
755 config.
heli.ServoIndexW = m_ccpm->ccpmServoWChannel->currentIndex();
756 config.
heli.ServoIndexX = m_ccpm->ccpmServoXChannel->currentIndex();
757 config.
heli.ServoIndexY = m_ccpm->ccpmServoYChannel->currentIndex();
758 config.
heli.ServoIndexZ = m_ccpm->ccpmServoZChannel->currentIndex();
761 config.
heli.Throttle = m_ccpm->ccpmEngineChannel->currentIndex();
763 config.
heli.Tail = m_ccpm->ccpmTailChannel->currentIndex();
767 updatingFromHardware =
false;
771 SystemSettings::AirframeTypeOptions
772 ConfigCcpmWidget::updateConfigObjectsFromWidgets()
774 SystemSettings::AirframeTypeOptions airframeType = updateConfigObjects();
781 void ConfigCcpmWidget::refreshAirframeWidgetsValues(
782 SystemSettings::AirframeTypeOptions frameType)
790 m_ccpm->ccpmType->count() - (config.
heli.SwashplateType + 1));
794 m_ccpm->ccpmCollectivePassthrough->setChecked(config.
heli.ccpmCollectivePassthroughState);
795 m_ccpm->ccpmLinkCyclic->setChecked(config.
heli.ccpmLinkCyclicState);
796 m_ccpm->ccpmLinkRoll->setChecked(config.
heli.ccpmLinkRollState);
799 m_ccpm->ccpmCorrectionAngle->setValue(config.
heli.CorrectionAngle);
802 m_ccpm->ccpmCollectiveScale->setValue(config.
heli.SliderValue0);
803 m_ccpm->ccpmCollectiveScaleBox->setValue(config.
heli.SliderValue0);
804 m_ccpm->ccpmCyclicScale->setValue(config.
heli.SliderValue1);
805 m_ccpm->ccpmCyclicScaleBox->setValue(config.
heli.SliderValue1);
806 m_ccpm->ccpmPitchScale->setValue(config.
heli.SliderValue1);
807 m_ccpm->ccpmPitchScaleBox->setValue(config.
heli.SliderValue1);
808 m_ccpm->ccpmRollScale->setValue(config.
heli.SliderValue2);
809 m_ccpm->ccpmRollScaleBox->setValue(config.
heli.SliderValue2);
810 m_ccpm->ccpmCollectiveSlider->setValue(config.
heli.SliderValue0);
811 m_ccpm->ccpmCollectivespinBox->setValue(config.
heli.SliderValue0);
827 void ConfigCcpmWidget::SetUIComponentVisibilities()
829 m_ccpm->ccpmRevoMixingBox->setVisible(0);
831 m_ccpm->ccpmPitchMixingBox->setVisible(!m_ccpm->ccpmCollectivePassthrough->isChecked()
832 && m_ccpm->ccpmLinkCyclic->isChecked());
834 m_ccpm->ccpmCollectiveScalingBox->setVisible(m_ccpm->ccpmCollectivePassthrough->isChecked()
835 || !m_ccpm->ccpmLinkCyclic->isChecked());
837 m_ccpm->ccpmLinkCyclic->setVisible(!m_ccpm->ccpmCollectivePassthrough->isChecked());
839 m_ccpm->ccpmCyclicScalingBox->setVisible(
840 (m_ccpm->ccpmCollectivePassthrough->isChecked() || !m_ccpm->ccpmLinkCyclic->isChecked())
841 && m_ccpm->ccpmLinkRoll->isChecked());
843 if (!m_ccpm->ccpmCollectivePassthrough->checkState() && m_ccpm->ccpmLinkCyclic->isChecked()) {
844 m_ccpm->ccpmPitchScalingBox->setVisible(0);
845 m_ccpm->ccpmRollScalingBox->setVisible(0);
846 m_ccpm->ccpmLinkRoll->setVisible(0);
849 m_ccpm->ccpmPitchScalingBox->setVisible(!m_ccpm->ccpmLinkRoll->isChecked());
850 m_ccpm->ccpmRollScalingBox->setVisible(!m_ccpm->ccpmLinkRoll->isChecked());
851 m_ccpm->ccpmLinkRoll->setVisible(1);
859 if (SwashLvlConfigurationInProgress)
861 if (updatingToHardware)
864 updatingFromHardware =
true;
866 MixerSettings *mixerSettings = MixerSettings::GetInstance(
getObjectManager());
867 Q_ASSERT(mixerSettings);
873 vconfig->getThrottleCurve(mixerSettings, MixerSettings::MIXER1VECTOR_THROTTLECURVE2,
876 if (vconfig->isValidThrottleCurve(&curveValues)) {
877 m_ccpm->PitchCurve->setCurve(&curveValues);
879 m_ccpm->PitchCurve->ResetCurve();
882 updatingFromHardware =
false;
884 ccpmSwashplateUpdate();
894 if (SwashLvlConfigurationInProgress)
896 if (updatingToHardware ==
true)
899 updatingToHardware =
true;
901 MixerSettings *mixerSettings = MixerSettings::GetInstance(
getObjectManager());
902 Q_ASSERT(mixerSettings);
903 MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
908 decltype(&mixerSettingsData.Mixer1Vector[0]) mixers[] = {
909 mixerSettingsData.Mixer1Vector, mixerSettingsData.Mixer2Vector,
910 mixerSettingsData.Mixer3Vector, mixerSettingsData.Mixer4Vector,
911 mixerSettingsData.Mixer5Vector, mixerSettingsData.Mixer6Vector,
912 mixerSettingsData.Mixer7Vector, mixerSettingsData.Mixer8Vector,
913 mixerSettingsData.Mixer9Vector, mixerSettingsData.Mixer10Vector
916 decltype(&mixerSettingsData.Mixer1Type)
mixerTypes[] = {
917 &mixerSettingsData.Mixer1Type, &mixerSettingsData.Mixer2Type, &mixerSettingsData.Mixer3Type,
918 &mixerSettingsData.Mixer4Type, &mixerSettingsData.Mixer5Type, &mixerSettingsData.Mixer6Type,
919 &mixerSettingsData.Mixer7Type, &mixerSettingsData.Mixer8Type, &mixerSettingsData.Mixer9Type,
920 &mixerSettingsData.Mixer10Type
924 for (i = 0; i < 8; i++)
928 for (i = 0; i < 6; i++) {
929 if (MixerChannelData[i] > 0
933 if (TypeText.compare(QString::fromUtf8(
"Coax 2 Servo 90º"), Qt::CaseInsensitive) == 0) {
935 i > 1 ? MixerSettings::MIXER1TYPE_SERVO : MixerSettings::MIXER1TYPE_MOTOR;
938 i > 0 ? MixerSettings::MIXER1TYPE_SERVO : MixerSettings::MIXER1TYPE_MOTOR;
942 for (j = 0; j < 5; j++)
943 mixers[MixerChannelData[i] - 1][j] =
944 m_ccpm->ccpmAdvancedSettingsTable->item(i, j + 1)
952 for (i = 0; i < 5; i++) {
953 mixerSettingsData.ThrottleCurve2[
i] = curve2.at(i);
960 if (m_ccpm->ccpmCollectivePassthrough->isChecked())
961 mixerSettingsData.Curve2Source = MixerSettings::CURVE2SOURCE_COLLECTIVE;
963 mixerSettingsData.Curve2Source = MixerSettings::CURVE2SOURCE_THROTTLE;
965 mixerSettings->setData(mixerSettingsData);
966 mixerSettings->updated();
967 updatingToHardware =
false;
975 if (SwashLvlConfigurationInProgress)
982 MixerSettings *mixerSettings = MixerSettings::GetInstance(
getObjectManager());
983 Q_ASSERT(mixerSettings);
992 m_ccpm->ccpmAdvancedSettingsTable->resizeColumnsToContents();
993 for (
int i = 0; i < 6; i++) {
994 m_ccpm->ccpmAdvancedSettingsTable->setColumnWidth(
996 (m_ccpm->ccpmAdvancedSettingsTable->width()
997 - m_ccpm->ccpmAdvancedSettingsTable->verticalHeader()->width())
1000 ccpmSwashplateRedraw();
1005 m_ccpm->ccpmAdvancedSettingsTable->resizeColumnsToContents();
1006 for (
int i = 0; i < 6; i++) {
1007 m_ccpm->ccpmAdvancedSettingsTable->setColumnWidth(
1009 (m_ccpm->ccpmAdvancedSettingsTable->width()
1010 - m_ccpm->ccpmAdvancedSettingsTable->verticalHeader()->width())
1013 ccpmSwashplateRedraw();
1016 void ConfigCcpmWidget::SwashLvlStartButtonPressed()
1018 QMessageBox msgBox(QMessageBox::Information, tr(
"Swashplate Leveling Routine"),
1019 tr(
"<b>You are about to start the Swashplate levelling routine.</b><p>This process will start "
1020 "by downloading the current configuration from the GCS to the OP hardware and will adjust "
1021 "your configuration at various stages.<p>The final state of your system should match the "
1022 "current configuration in the GCS config gadget.<p>Please ensure all ccpm settings in the "
1023 "GCS are correct before continuing.<p>If this process is interrupted, then the state of "
1024 "your OP board may not match the GCS configuration.<p><i>After completing this process, "
1025 "please check all settings before attempting to fly.</i><p><font color=red><b>Please "
1026 "disconnect your motor to ensure it will not spin up.</b></font><p><hr><i>Do you wish to "
1027 "proceed?</i>"), QMessageBox::Yes | QMessageBox::Cancel,
this);
1029 msgBox.setDefaultButton(QMessageBox::Cancel);
1030 int ret = msgBox.exec();
1040 case QMessageBox::Yes:
1044 enableSwashplateLevellingControl(
true);
1046 m_ccpm->SwashLvlStartButton->setEnabled(
false);
1047 m_ccpm->SwashLvlNextButton->setEnabled(
true);
1048 m_ccpm->SwashLvlCancelButton->setEnabled(
true);
1049 m_ccpm->SwashLvlFinishButton->setEnabled(
false);
1051 m_ccpm->SwashLvlStepList->item(0)->setCheckState(Qt::Unchecked);
1052 m_ccpm->SwashLvlStepList->item(1)->setCheckState(Qt::Unchecked);
1053 m_ccpm->SwashLvlStepList->item(2)->setCheckState(Qt::Unchecked);
1054 m_ccpm->SwashLvlStepList->item(3)->setCheckState(Qt::Unchecked);
1064 pm = ExtensionSystem::PluginManager::instance();
1071 MinField = obj->
getField(QString(
"ChannelMin"));
1072 NeutralField = obj->
getField(QString(
"ChannelNeutral"));
1073 MaxField = obj->
getField(QString(
"ChannelMax"));
1076 oldSwashLvlConfiguration.
ServoChannels[0] = m_ccpm->ccpmServoWChannel->currentIndex();
1077 oldSwashLvlConfiguration.
ServoChannels[1] = m_ccpm->ccpmServoXChannel->currentIndex();
1078 oldSwashLvlConfiguration.
ServoChannels[2] = m_ccpm->ccpmServoYChannel->currentIndex();
1079 oldSwashLvlConfiguration.
ServoChannels[3] = m_ccpm->ccpmServoZChannel->currentIndex();
1082 oldSwashLvlConfiguration.
Used[0] = (m_ccpm->ccpmServoWChannel->currentIndex() > 0);
1083 oldSwashLvlConfiguration.
Used[1] = (m_ccpm->ccpmServoXChannel->currentIndex() > 0);
1084 oldSwashLvlConfiguration.
Used[2] = (m_ccpm->ccpmServoYChannel->currentIndex() > 0);
1085 oldSwashLvlConfiguration.
Used[3] = (m_ccpm->ccpmServoZChannel->currentIndex() > 0);
1088 for (uint8_t i = 0; i < CCPM_MAX_SWASH_SERVOS; ++
i) {
1096 for (uint8_t i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) {
1097 oldSwashLvlConfiguration.
Min[
i] =
1099 oldSwashLvlConfiguration.
Neutral[
i] =
1101 oldSwashLvlConfiguration.
Max[
i] =
1106 memcpy(&newSwashLvlConfiguration, &oldSwashLvlConfiguration,
1110 SwashLvlNextButtonPressed();
1112 case QMessageBox::Cancel:
1116 enableSwashplateLevellingControl(
false);
1118 m_ccpm->SwashLvlStartButton->setEnabled(
true);
1119 m_ccpm->SwashLvlNextButton->setEnabled(
false);
1120 m_ccpm->SwashLvlCancelButton->setEnabled(
false);
1121 m_ccpm->SwashLvlFinishButton->setEnabled(
false);
1128 void ConfigCcpmWidget::SwashLvlNextButtonPressed()
1134 switch (SwashLvlState) {
1138 m_ccpm->SwashLvlStepList->setCurrentRow(0);
1140 setSwashplateLevel(50);
1142 m_ccpm->SwashLvlPositionSlider->setEnabled(
false);
1143 m_ccpm->SwashLvlPositionSpinBox->setEnabled(
false);
1145 m_ccpm->SwashLvlPositionSlider->setValue(50);
1146 m_ccpm->SwashLvlPositionSpinBox->setValue(50);
1148 for (i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) {
1149 connect(SwashLvlSpinBoxes[i], SIGNAL(valueChanged(
int)),
this,
1150 SLOT(SwashLvlSpinBoxChanged(
int)));
1151 SwashLvlSpinBoxes[
i]->setEnabled(
true);
1154 m_ccpm->SwashLvlStepInstruction->setHtml(
1155 "<h2>Neutral levelling</h2><p>Using adjustment of:<ul><li>servo horns<li>link lengths "
1156 "and<li>Neutral timing spinboxes to the right</ul><br>ensure that the swashplate is in "
1157 "the center of desired travel range and is level.");
1161 m_ccpm->SwashLvlStepList->item(0)->setCheckState(Qt::Checked);
1162 m_ccpm->SwashLvlStepList->setCurrentRow(1);
1164 setSwashplateLevel(100);
1166 m_ccpm->SwashLvlPositionSlider->setValue(100);
1167 m_ccpm->SwashLvlPositionSpinBox->setValue(100);
1169 m_ccpm->SwashLvlStepInstruction->setText(
"<h2>Max levelling</h2><p>Using adjustment "
1170 "of:<ul><li>Max timing spinboxes to the right "
1171 "ONLY</ul><br>ensure that the swashplate is at "
1172 "the top of desired travel range and is level.");
1176 m_ccpm->SwashLvlStepList->item(1)->setCheckState(Qt::Checked);
1177 m_ccpm->SwashLvlStepList->setCurrentRow(2);
1179 setSwashplateLevel(0);
1181 m_ccpm->SwashLvlPositionSlider->setValue(0);
1182 m_ccpm->SwashLvlPositionSpinBox->setValue(0);
1184 m_ccpm->SwashLvlStepInstruction->setText(
1185 "<h2>Min levelling</h2><p>Using adjustment of:<ul><li>Min timing spinboxes to the "
1186 "right ONLY</ul><br>ensure that the swashplate is at the bottom of desired travel "
1187 "range and is level.");
1191 m_ccpm->SwashLvlStepList->item(2)->setCheckState(Qt::Checked);
1192 m_ccpm->SwashLvlStepList->setCurrentRow(3);
1194 m_ccpm->SwashLvlPositionSlider->setEnabled(
true);
1195 m_ccpm->SwashLvlPositionSpinBox->setEnabled(
true);
1197 connect(m_ccpm->SwashLvlPositionSlider, SIGNAL(valueChanged(
int)),
this,
1198 SLOT(setSwashplateLevel(
int)));
1200 for (i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) {
1201 SwashLvlSpinBoxes[
i]->setEnabled(
false);
1205 m_ccpm->SwashLvlStepInstruction->setText(
"<h2>levelling verification</h2><p>Adjust the "
1206 "slider to the right over it's full range and "
1207 "observe the swashplate motion. It should remain "
1208 "level over the entire range of travel.");
1212 m_ccpm->SwashLvlStepList->item(3)->setCheckState(Qt::Checked);
1214 m_ccpm->SwashLvlStepInstruction->setText(
1215 "<h2>levelling complete</h2><p>Press the Finish button to save these settings to the "
1216 "SD card<p>Press the cancel button to return to the pre-levelling settings");
1218 m_ccpm->SwashLvlPositionSlider->setEnabled(
false);
1219 m_ccpm->SwashLvlPositionSpinBox->setEnabled(
false);
1221 disconnect(m_ccpm->SwashLvlPositionSlider, SIGNAL(valueChanged(
int)),
this,
1222 SLOT(setSwashplateLevel(
int)));
1223 for (i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) {
1224 disconnect(SwashLvlSpinBoxes[i], SIGNAL(valueChanged(
int)),
this,
1225 SLOT(SwashLvlSpinBoxChanged(
int)));
1228 m_ccpm->SwashLvlStartButton->setEnabled(
false);
1229 m_ccpm->SwashLvlNextButton->setEnabled(
false);
1230 m_ccpm->SwashLvlCancelButton->setEnabled(
true);
1231 m_ccpm->SwashLvlFinishButton->setEnabled(
true);
1242 void ConfigCcpmWidget::SwashLvlCancelButtonPressed()
1251 m_ccpm->SwashLvlStartButton->setEnabled(
true);
1252 m_ccpm->SwashLvlNextButton->setEnabled(
false);
1253 m_ccpm->SwashLvlCancelButton->setEnabled(
false);
1254 m_ccpm->SwashLvlFinishButton->setEnabled(
false);
1256 m_ccpm->SwashLvlStepList->item(0)->setCheckState(Qt::Unchecked);
1257 m_ccpm->SwashLvlStepList->item(1)->setCheckState(Qt::Unchecked);
1258 m_ccpm->SwashLvlStepList->item(2)->setCheckState(Qt::Unchecked);
1259 m_ccpm->SwashLvlStepList->item(3)->setCheckState(Qt::Unchecked);
1268 MinField = obj->getField(QString(
"ChannelMin"));
1269 NeutralField = obj->getField(QString(
"ChannelNeutral"));
1270 MaxField = obj->getField(QString(
"ChannelMax"));
1273 for (i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) {
1274 MinField->
setValue(oldSwashLvlConfiguration.
Min[i],
1278 MaxField->
setValue(oldSwashLvlConfiguration.
Max[i],
1285 enableSwashplateLevellingControl(
false);
1287 m_ccpm->SwashLvlStepInstruction->setText(
1288 "<h2>Levelling Cancelled</h2><p>Previous settings have been restored.");
1291 void ConfigCcpmWidget::SwashLvlFinishButtonPressed()
1299 m_ccpm->SwashLvlStartButton->setEnabled(
true);
1300 m_ccpm->SwashLvlNextButton->setEnabled(
false);
1301 m_ccpm->SwashLvlCancelButton->setEnabled(
false);
1302 m_ccpm->SwashLvlFinishButton->setEnabled(
false);
1311 MinField = obj->getField(QString(
"ChannelMin"));
1312 NeutralField = obj->getField(QString(
"ChannelNeutral"));
1313 MaxField = obj->getField(QString(
"ChannelMax"));
1316 for (i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) {
1317 MinField->
setValue(newSwashLvlConfiguration.
Min[i],
1321 MaxField->
setValue(newSwashLvlConfiguration.
Max[i],
1329 enableSwashplateLevellingControl(
false);
1331 m_ccpm->SwashLvlStepInstruction->setText(
1332 "<h2>Levelling Completed</h2><p>New settings have been saved to the SD card");
1338 int ConfigCcpmWidget::ShowDisclaimer(
int messageID)
1341 msgBox.setText(
"<font color=red><h1>Warning!!!</h2></font>");
1343 switch (messageID) {
1346 msgBox.setInformativeText(
"<h2>This code has many configurations.</h2><p>Please double "
1347 "check all settings before attempting flight!");
1348 msgBox.setStandardButtons(QMessageBox::Ok);
1349 msgBox.setDefaultButton(QMessageBox::Ok);
1350 msgBox.setIcon(QMessageBox::Information);
1351 ret = msgBox.exec();
1356 msgBox.setInformativeText(
"<h2>The CCPM mixer code needs more testing!</h2><p><font "
1357 "color=red>Use it at your own risk!</font><p>Do you wish to "
1359 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
1360 msgBox.setDefaultButton(QMessageBox::Cancel);
1361 msgBox.setIcon(QMessageBox::Warning);
1362 ret = msgBox.exec();
1364 case QMessageBox::Cancel:
1366 case QMessageBox::Yes:
1372 msgBox.setInformativeText(
"<h2>The CCPM swashplate levelling code is NOT "
1373 "complete!</h2><p><font color=red>DO NOT use it for "
1375 msgBox.setStandardButtons(QMessageBox::Ok);
1376 msgBox.setDefaultButton(QMessageBox::Ok);
1377 msgBox.setIcon(QMessageBox::Critical);
1378 ret = msgBox.exec();
1392 void ConfigCcpmWidget::enableSwashplateLevellingControl(
bool state)
1401 SwashLvlaccInitialData = mdata;
1406 mdata.gcsTelemetryUpdatePeriod = 100;
1407 SwashLvlConfigurationInProgress = 1;
1408 m_ccpm->TabObject->setTabEnabled(0, 0);
1409 m_ccpm->TabObject->setTabEnabled(2, 0);
1410 m_ccpm->TabObject->setTabEnabled(3, 0);
1411 m_ccpm->ccpmType->setEnabled(0);
1413 mdata = SwashLvlaccInitialData;
1414 SwashLvlConfigurationInProgress = 0;
1416 m_ccpm->TabObject->setTabEnabled(0, 1);
1417 m_ccpm->TabObject->setTabEnabled(2, 1);
1418 m_ccpm->TabObject->setTabEnabled(3, 1);
1419 m_ccpm->ccpmType->setEnabled(1);
1421 obj->setMetadata(mdata);
1429 void ConfigCcpmWidget::setSwashplateLevel(
int percent)
1435 if (SwashLvlConfigurationInProgress != 1)
1439 double level = ((double)percent / 50.00) - 1.00;
1441 SwashLvlServoInterlock = 1;
1443 ActuatorCommand *actuatorCommand = ActuatorCommand::GetInstance(
getObjectManager());
1444 ActuatorCommand::DataFields actuatorCommandData = actuatorCommand->getData();
1446 for (i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) {
1448 if (newSwashLvlConfiguration.
Used[i] == 0)
1452 value = newSwashLvlConfiguration.
Neutral[
i];
1454 value = (newSwashLvlConfiguration.
Max[
i] - newSwashLvlConfiguration.
Neutral[
i]) * level
1455 + newSwashLvlConfiguration.
Neutral[i];
1457 value = (newSwashLvlConfiguration.
Neutral[
i] - newSwashLvlConfiguration.
Min[
i]) * level
1458 + newSwashLvlConfiguration.
Neutral[i];
1460 actuatorCommandData.Channel[newSwashLvlConfiguration.
ServoChannels[i]] = value;
1461 SwashLvlSpinBoxes[i]->setValue(value);
1464 actuatorCommand->setData(actuatorCommandData);
1465 actuatorCommand->updated();
1467 SwashLvlServoInterlock = 0;
1472 void ConfigCcpmWidget::SwashLvlSpinBoxChanged(
int value)
1476 if (SwashLvlServoInterlock == 1)
1479 ActuatorCommand *actuatorCommand = ActuatorCommand::GetInstance(
getObjectManager());
1480 ActuatorCommand::DataFields actuatorCommandData = actuatorCommand->getData();
1482 for (i = 0; i < CCPM_MAX_SWASH_SERVOS; i++) {
1484 if (newSwashLvlConfiguration.
Used[i] == 0)
1487 value = SwashLvlSpinBoxes[
i]->value();
1489 switch (SwashLvlState) {
1491 newSwashLvlConfiguration.
Neutral[
i] = value;
1494 newSwashLvlConfiguration.
Max[
i] = value;
1497 newSwashLvlConfiguration.
Min[
i] = value;
1507 actuatorCommandData.Channel[newSwashLvlConfiguration.
ServoChannels[
i]] = value;
1510 actuatorCommand->setData(actuatorCommandData);
1511 actuatorCommand->updated();
1520 bool ConfigCcpmWidget::throwConfigError(SystemSettings::AirframeTypeOptions airframeType)
1522 Q_UNUSED(airframeType);
1526 if ((m_ccpm->ccpmServoWChannel->currentIndex() == 0)
1527 && (m_ccpm->ccpmServoWChannel->isEnabled())) {
1528 m_ccpm->ccpmServoWLabel->setText(
"<font color=red>" + m_ccpm->ccpmServoWLabel->text()
1532 m_ccpm->ccpmServoWLabel->setText(QTextEdit(m_ccpm->ccpmServoWLabel->text()).toPlainText());
1535 if ((m_ccpm->ccpmServoXChannel->currentIndex() == 0)
1536 && (m_ccpm->ccpmServoXChannel->isEnabled())) {
1537 m_ccpm->ccpmServoXLabel->setText(
"<font color=red>" + m_ccpm->ccpmServoXLabel->text()
1541 m_ccpm->ccpmServoXLabel->setText(QTextEdit(m_ccpm->ccpmServoXLabel->text()).toPlainText());
1544 if ((m_ccpm->ccpmServoYChannel->currentIndex() == 0)
1545 && (m_ccpm->ccpmServoYChannel->isEnabled())) {
1546 m_ccpm->ccpmServoYLabel->setText(
"<font color=red>" + m_ccpm->ccpmServoYLabel->text()
1550 m_ccpm->ccpmServoYLabel->setText(QTextEdit(m_ccpm->ccpmServoYLabel->text()).toPlainText());
1553 if ((m_ccpm->ccpmServoZChannel->currentIndex() == 0)
1554 && (m_ccpm->ccpmServoZChannel->isEnabled())) {
1555 m_ccpm->ccpmServoZLabel->setText(
"<font color=red>" + m_ccpm->ccpmServoZLabel->text()
1559 m_ccpm->ccpmServoZLabel->setText(QTextEdit(m_ccpm->ccpmServoZLabel->text()).toPlainText());
1562 if ((m_ccpm->ccpmEngineChannel->currentIndex() == 0)
1563 && (m_ccpm->ccpmEngineChannel->isEnabled())) {
1564 m_ccpm->ccpmEngineLabel->setText(
"<font color=red>" + m_ccpm->ccpmEngineLabel->text()
1567 m_ccpm->ccpmEngineLabel->setText(QTextEdit(m_ccpm->ccpmEngineLabel->text()).toPlainText());
1570 if ((m_ccpm->ccpmTailChannel->currentIndex() == 0) && (m_ccpm->ccpmTailChannel->isEnabled())) {
1571 m_ccpm->ccpmTailLabel->setText(
"<font color=red>" + m_ccpm->ccpmTailLabel->text()
1575 m_ccpm->ccpmTailLabel->setText(QTextEdit(m_ccpm->ccpmTailLabel->text()).toPlainText());
VehicleConfig(QWidget *parent=nullptr)
int Max[CCPM_MAX_SWASH_SERVOS]
int Used[CCPM_MAX_SWASH_SERVOS]
int Neutral[CCPM_MAX_SWASH_SERVOS]
ConfigCcpmWidget(QWidget *parent=nullptr)
static void SetFlightAccess(Metadata &meta, AccessMode mode)
static void SetConfigData(GUIConfigDataUnion configData, SystemSettings::AirframeTypeOptions vehicle)
static GUIConfigDataUnion GetConfigData()
int ServoChannels[CCPM_MAX_SWASH_SERVOS]
Core plugin system that manages the plugins, their life cycle and their registered objects...
QVariant getValue(int index=0) const
static void SetGcsTelemetryAcked(Metadata &meta, quint8 val)
void showEvent(QShowEvent *event)
static void SetFlightTelemetryUpdateMode(Metadata &meta, UpdateMode val)
void setValue(const QVariant &data, int index=0)
void resizeEvent(QResizeEvent *event)
heliGUISettingsStruct heli
else error('Your technical computing program does not support file choosers.Please input the file name in the argument. ') end elseif nargin >0 logfile
static void SetGcsTelemetryUpdateMode(Metadata &meta, UpdateMode val)
int Min[CCPM_MAX_SWASH_SERVOS]
UAVObject * getObject(const QString &name, quint32 instId=0)
UAVObjectField * getField(const QString &objName, const QString &fieldName, quint32 instId=0)
getField Get a UAV Object field Success is asserted so there is no need to do this again in the calle...
static const double mixerScale
static void setComboCurrentIndex(QComboBox *box, int index)