diff --git a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp index 87dc480f6..338dcc874 100644 --- a/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/cfg_vehicletypes/configgroundvehiclewidget.cpp @@ -60,10 +60,10 @@ QStringList ConfigGroundVehicleWidget::getChannelDescriptions() channelDesc[configData.ground.GroundVehicleSteering2 - 1] = QString("GroundSteering2"); } if (configData.ground.GroundVehicleThrottle1 > 0) { - channelDesc[configData.ground.GroundVehicleThrottle1 - 1] = QString("GroundThrottle1"); + channelDesc[configData.ground.GroundVehicleThrottle1 - 1] = QString("GroundMotor1"); } if (configData.ground.GroundVehicleThrottle2 > 0) { - channelDesc[configData.ground.GroundVehicleThrottle2 - 1] = QString("GroundThrottle2"); + channelDesc[configData.ground.GroundVehicleThrottle2 - 1] = QString("GroundMotor2"); } return channelDesc; } @@ -116,6 +116,13 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType) m_aircraft->gvThrottleCurve1GroupBox->setEnabled(true); m_aircraft->gvThrottleCurve2GroupBox->setEnabled(true); + // Default Curve2 range -1 -> +1, allow forward/reverse (Car and Tank) + m_aircraft->groundVehicleThrottle1->setMixerType(MixerCurve::MIXERCURVE_THROTTLE); + m_aircraft->groundVehicleThrottle2->setMixerType(MixerCurve::MIXERCURVE_PITCH); + + initMixerCurves(frameType); + + if (frameType == "GroundVehicleDifferential" || frameType == "Differential (tank)") { // Tank m_vehicleImg->setElementId("tank"); @@ -159,9 +166,9 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType) // Motorcycle m_vehicleImg->setElementId("motorbike"); setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Motorcycle")); - m_aircraft->gvMotor1ChannelBox->setEnabled(false); - m_aircraft->gvMotor2ChannelBox->setEnabled(true); - m_aircraft->gvThrottleCurve1GroupBox->setEnabled(false); + + m_aircraft->gvMotor1ChannelBox->setEnabled(true); + m_aircraft->gvMotor2ChannelBox->setEnabled(false); m_aircraft->gvMotor2Label->setText("Rear motor"); @@ -171,7 +178,11 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType) m_aircraft->gvSteering1Label->setText("Front steering"); m_aircraft->gvSteering2Label->setText("Balancing"); - m_aircraft->gvThrottleCurve2GroupBox->setTitle("Rear throttle curve"); + // Curve1 for Motorcyle + m_aircraft->gvThrottleCurve1GroupBox->setTitle("Rear throttle curve"); + m_aircraft->gvThrottleCurve1GroupBox->setEnabled(true); + m_aircraft->gvThrottleCurve2GroupBox->setTitle(""); + m_aircraft->gvThrottleCurve2GroupBox->setEnabled(false); // Curve range 0 -> +1 (no reverse) m_aircraft->groundVehicleThrottle2->setMixerType(MixerCurve::MIXERCURVE_THROTTLE); @@ -201,19 +212,24 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType) m_aircraft->gvSteering1Label->setText("Front steering"); m_aircraft->gvSteering2Label->setText("Rear steering"); - m_aircraft->gvThrottleCurve1GroupBox->setTitle("Front throttle curve"); - m_aircraft->gvThrottleCurve2GroupBox->setTitle("Rear throttle curve"); + // Curve2 for Car + m_aircraft->gvThrottleCurve2GroupBox->setTitle("Throttle curve"); + m_aircraft->gvThrottleCurve2GroupBox->setEnabled(true); + m_aircraft->gvThrottleCurve1GroupBox->setTitle(""); + m_aircraft->gvThrottleCurve1GroupBox->setEnabled(false); - m_aircraft->groundVehicleThrottle2->setMixerType(MixerCurve::MIXERCURVE_THROTTLE); + m_aircraft->groundVehicleThrottle2->setMixerType(MixerCurve::MIXERCURVE_PITCH); m_aircraft->groundVehicleThrottle1->setMixerType(MixerCurve::MIXERCURVE_THROTTLE); initMixerCurves(frameType); // If new setup, set curves values if (frameTypeSaved->getValue().toString() != "GroundVehicleCar") { - // Curve range 0 -> +1 (no reverse) m_aircraft->groundVehicleThrottle1->initLinearCurve(5, 1.0); - m_aircraft->groundVehicleThrottle2->initLinearCurve(5, 1.0); + // Set curve2 range from -0.926 to 1 (forward / reverse) + // Take in account 4% offset in Throttle input after calibration + // 0.5 / 0.54 = 0.926 + m_aircraft->groundVehicleThrottle2->initLinearCurve(5, 1.0, -0.926); } } @@ -321,6 +337,8 @@ void ConfigGroundVehicleWidget::initMixerCurves(QString frameType) // no, init a straight curve if (frameType == "GroundVehicleDifferential") { m_aircraft->groundVehicleThrottle2->initLinearCurve(curveValues.count(), 0.8, -0.8); + } else if (frameType == "GroundVehicleCar") { + m_aircraft->groundVehicleThrottle2->initLinearCurve(curveValues.count(), 1.0, -1.0); } else { m_aircraft->groundVehicleThrottle2->initLinearCurve(curveValues.count(), 1.0); } @@ -388,7 +406,7 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleMotorcycle(QString airframeTyp // motor int channel = m_aircraft->gvMotor2ChannelBox->currentIndex() - 1; - setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_REVERSABLEMOTOR); + setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_MOTOR); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127); @@ -495,7 +513,7 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleCar(QString airframeType) channel = m_aircraft->gvMotor1ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_REVERSABLEMOTOR); - setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE1, 127); + setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_THROTTLECURVE2, 127); channel = m_aircraft->gvMotor2ChannelBox->currentIndex() - 1; setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_REVERSABLEMOTOR); diff --git a/ground/openpilotgcs/src/plugins/setupwizard/pages/esccalibrationpage.cpp b/ground/openpilotgcs/src/plugins/setupwizard/pages/esccalibrationpage.cpp index 4936a2260..04888a5dd 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/pages/esccalibrationpage.cpp +++ b/ground/openpilotgcs/src/plugins/setupwizard/pages/esccalibrationpage.cpp @@ -104,6 +104,16 @@ void EscCalibrationPage::startButtonClicked() QString mixerTypePattern = "Mixer%1Type"; OutputCalibrationUtil::startOutputCalibration(); + // First check if any servo and set his value to 1500 (like Tricopter) + for (quint32 i = 0; i < ActuatorSettings::CHANNELADDR_NUMELEM; i++) { + UAVObjectField *field = mSettings->getField(mixerTypePattern.arg(i + 1)); + Q_ASSERT(field); + if (field->getValue().toString() == field->getOptions().at(VehicleConfigurationHelper::MIXER_TYPE_SERVO)) { + m_outputUtil.startChannelOutput(i, 1500); + m_outputUtil.stopChannelOutput(); + } + } + // Find motors and start Esc procedure for (quint32 i = 0; i < ActuatorSettings::CHANNELADDR_NUMELEM; i++) { UAVObjectField *field = mSettings->getField(mixerTypePattern.arg(i + 1)); Q_ASSERT(field); diff --git a/ground/openpilotgcs/src/plugins/setupwizard/pages/outputcalibrationpage.cpp b/ground/openpilotgcs/src/plugins/setupwizard/pages/outputcalibrationpage.cpp index cdf95e5c1..fb4775aa9 100644 --- a/ground/openpilotgcs/src/plugins/setupwizard/pages/outputcalibrationpage.cpp +++ b/ground/openpilotgcs/src/plugins/setupwizard/pages/outputcalibrationpage.cpp @@ -54,6 +54,8 @@ OutputCalibrationPage::~OutputCalibrationPage() delete m_calibrationUtil; m_calibrationUtil = 0; } + + OutputCalibrationUtil::stopOutputCalibration(); delete ui; } @@ -70,18 +72,32 @@ void OutputCalibrationPage::setupActuatorMinMaxAndNeutral(int motorChannelStart, // servos since a value out of range can actually destroy the // vehicle if unlucky. // Motors are not that important. REMOVE propellers always!! + OutputCalibrationUtil::startOutputCalibration(); for (int servoid = 0; servoid < 12; servoid++) { if (servoid >= motorChannelStart && servoid <= motorChannelEnd) { // Set to motor safe values - m_actuatorSettings[servoid].channelMin = 1000; - m_actuatorSettings[servoid].channelNeutral = 1000; - m_actuatorSettings[servoid].channelMax = 1900; + m_actuatorSettings[servoid].channelMin = 1000; + m_actuatorSettings[servoid].channelNeutral = 1000; + m_actuatorSettings[servoid].channelMax = 1900; + m_actuatorSettings[servoid].isReversableMotor = false; + // Car and Tank should use reversable Esc/motors + if ((getWizard()->getVehicleSubType() == SetupWizard::GROUNDVEHICLE_CAR) + || (getWizard()->getVehicleSubType() == SetupWizard::GROUNDVEHICLE_DIFFERENTIAL)) { + m_actuatorSettings[servoid].channelNeutral = 1500; + m_actuatorSettings[servoid].isReversableMotor = true; + // Set initial output value + m_calibrationUtil->startChannelOutput(servoid, 1500); + m_calibrationUtil->stopChannelOutput(); + } } else if (servoid < totalUsedChannels) { // Set to servo safe values m_actuatorSettings[servoid].channelMin = 1500; m_actuatorSettings[servoid].channelNeutral = 1500; m_actuatorSettings[servoid].channelMax = 1500; + // Set initial servo output value + m_calibrationUtil->startChannelOutput(servoid, 1500); + m_calibrationUtil->stopChannelOutput(); } else { // "Disable" these channels m_actuatorSettings[servoid].channelMin = 1000; @@ -101,6 +117,8 @@ void OutputCalibrationPage::setupVehicle() m_currentWizardIndex = 0; m_vehicleScene->clear(); + resetOutputCalibrationUtil(); + switch (getWizard()->getVehicleSubType()) { case SetupWizard::MULTI_ROTOR_TRI_Y: // Loads the SVG file resourse and sets the scene @@ -120,7 +138,7 @@ void OutputCalibrationPage::setupVehicle() // The channel number to configure for each step. m_channelIndex << 0 << 0 << 1 << 2 << 3; - setupActuatorMinMaxAndNeutral(0, 2, 3); + setupActuatorMinMaxAndNeutral(0, 2, 4); getWizard()->setActuatorSettings(m_actuatorSettings); break; @@ -180,7 +198,7 @@ void OutputCalibrationPage::setupVehicle() m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 5; m_channelIndex << 0 << 2 << 0 << 5 << 1 << 3; - setupActuatorMinMaxAndNeutral(2, 2, 5); + setupActuatorMinMaxAndNeutral(2, 2, 6); // should be 5 instead 6 but output 5 is not used getWizard()->setActuatorSettings(m_actuatorSettings); break; @@ -213,7 +231,7 @@ void OutputCalibrationPage::setupVehicle() m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 5; m_channelIndex << 0 << 2 << 0 << 5 << 3 << 1; - setupActuatorMinMaxAndNeutral(2, 2, 5); + setupActuatorMinMaxAndNeutral(2, 2, 6); // should be 5 instead 6 but output 5 is not used getWizard()->setActuatorSettings(m_actuatorSettings); break; @@ -226,7 +244,7 @@ void OutputCalibrationPage::setupVehicle() m_vehicleHighlightElementIndexes << 0 << 1 << 2; m_channelIndex << 0 << 1 << 0; - setupActuatorMinMaxAndNeutral(0, 1, 2); + setupActuatorMinMaxAndNeutral(1, 1, 2); getWizard()->setActuatorSettings(m_actuatorSettings); break; @@ -248,7 +266,7 @@ void OutputCalibrationPage::setupVehicle() m_vehicleHighlightElementIndexes << 0 << 1 << 2; m_channelIndex << 0 << 1 << 0; - setupActuatorMinMaxAndNeutral(0, 1, 2); + setupActuatorMinMaxAndNeutral(1, 1, 2); getWizard()->setActuatorSettings(m_actuatorSettings); break; @@ -257,12 +275,6 @@ void OutputCalibrationPage::setupVehicle() break; } - if (m_calibrationUtil) { - delete m_calibrationUtil; - m_calibrationUtil = 0; - } - m_calibrationUtil = new OutputCalibrationUtil(); - setupVehicleItems(); } @@ -326,7 +338,15 @@ void OutputCalibrationPage::setWizardPage() if (currentChannel >= 0) { if (currentPageIndex == 1) { ui->motorNeutralSlider->setValue(m_actuatorSettings[currentChannel].channelNeutral); + ui->motorPWMValue->setText(QString(tr("Output value : %1 µs")).arg(m_actuatorSettings[currentChannel].channelNeutral)); + // Reversable motor found + if (m_actuatorSettings[currentChannel].isReversableMotor) { + ui->motorNeutralSlider->setMinimum(m_actuatorSettings[currentChannel].channelMin); + ui->motorNeutralSlider->setMaximum(m_actuatorSettings[currentChannel].channelMax); + ui->motorInfo->setText(tr("
To find the neutral rate for this reversable motor, press the Start button below and slide the slider to the right or left until you find the value where the motor doesn't start.
When done press button again to stop.