mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-19 04:52:12 +01:00
Merge branch 'next' into laurent/OP-1337_15.02
This commit is contained in:
commit
4b187f0f2d
@ -60,10 +60,10 @@ QStringList ConfigGroundVehicleWidget::getChannelDescriptions()
|
|||||||
channelDesc[configData.ground.GroundVehicleSteering2 - 1] = QString("GroundSteering2");
|
channelDesc[configData.ground.GroundVehicleSteering2 - 1] = QString("GroundSteering2");
|
||||||
}
|
}
|
||||||
if (configData.ground.GroundVehicleThrottle1 > 0) {
|
if (configData.ground.GroundVehicleThrottle1 > 0) {
|
||||||
channelDesc[configData.ground.GroundVehicleThrottle1 - 1] = QString("GroundThrottle1");
|
channelDesc[configData.ground.GroundVehicleThrottle1 - 1] = QString("GroundMotor1");
|
||||||
}
|
}
|
||||||
if (configData.ground.GroundVehicleThrottle2 > 0) {
|
if (configData.ground.GroundVehicleThrottle2 > 0) {
|
||||||
channelDesc[configData.ground.GroundVehicleThrottle2 - 1] = QString("GroundThrottle2");
|
channelDesc[configData.ground.GroundVehicleThrottle2 - 1] = QString("GroundMotor2");
|
||||||
}
|
}
|
||||||
return channelDesc;
|
return channelDesc;
|
||||||
}
|
}
|
||||||
@ -116,6 +116,13 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType)
|
|||||||
m_aircraft->gvThrottleCurve1GroupBox->setEnabled(true);
|
m_aircraft->gvThrottleCurve1GroupBox->setEnabled(true);
|
||||||
m_aircraft->gvThrottleCurve2GroupBox->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)") {
|
if (frameType == "GroundVehicleDifferential" || frameType == "Differential (tank)") {
|
||||||
// Tank
|
// Tank
|
||||||
m_vehicleImg->setElementId("tank");
|
m_vehicleImg->setElementId("tank");
|
||||||
@ -159,9 +166,9 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType)
|
|||||||
// Motorcycle
|
// Motorcycle
|
||||||
m_vehicleImg->setElementId("motorbike");
|
m_vehicleImg->setElementId("motorbike");
|
||||||
setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Motorcycle"));
|
setComboCurrentIndex(m_aircraft->groundVehicleType, m_aircraft->groundVehicleType->findText("Motorcycle"));
|
||||||
m_aircraft->gvMotor1ChannelBox->setEnabled(false);
|
|
||||||
m_aircraft->gvMotor2ChannelBox->setEnabled(true);
|
m_aircraft->gvMotor1ChannelBox->setEnabled(true);
|
||||||
m_aircraft->gvThrottleCurve1GroupBox->setEnabled(false);
|
m_aircraft->gvMotor2ChannelBox->setEnabled(false);
|
||||||
|
|
||||||
m_aircraft->gvMotor2Label->setText("Rear motor");
|
m_aircraft->gvMotor2Label->setText("Rear motor");
|
||||||
|
|
||||||
@ -171,7 +178,11 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType)
|
|||||||
m_aircraft->gvSteering1Label->setText("Front steering");
|
m_aircraft->gvSteering1Label->setText("Front steering");
|
||||||
m_aircraft->gvSteering2Label->setText("Balancing");
|
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)
|
// Curve range 0 -> +1 (no reverse)
|
||||||
m_aircraft->groundVehicleThrottle2->setMixerType(MixerCurve::MIXERCURVE_THROTTLE);
|
m_aircraft->groundVehicleThrottle2->setMixerType(MixerCurve::MIXERCURVE_THROTTLE);
|
||||||
@ -201,19 +212,24 @@ void ConfigGroundVehicleWidget::setupUI(QString frameType)
|
|||||||
m_aircraft->gvSteering1Label->setText("Front steering");
|
m_aircraft->gvSteering1Label->setText("Front steering");
|
||||||
m_aircraft->gvSteering2Label->setText("Rear steering");
|
m_aircraft->gvSteering2Label->setText("Rear steering");
|
||||||
|
|
||||||
m_aircraft->gvThrottleCurve1GroupBox->setTitle("Front throttle curve");
|
// Curve2 for Car
|
||||||
m_aircraft->gvThrottleCurve2GroupBox->setTitle("Rear throttle curve");
|
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);
|
m_aircraft->groundVehicleThrottle1->setMixerType(MixerCurve::MIXERCURVE_THROTTLE);
|
||||||
|
|
||||||
initMixerCurves(frameType);
|
initMixerCurves(frameType);
|
||||||
|
|
||||||
// If new setup, set curves values
|
// If new setup, set curves values
|
||||||
if (frameTypeSaved->getValue().toString() != "GroundVehicleCar") {
|
if (frameTypeSaved->getValue().toString() != "GroundVehicleCar") {
|
||||||
// Curve range 0 -> +1 (no reverse)
|
|
||||||
m_aircraft->groundVehicleThrottle1->initLinearCurve(5, 1.0);
|
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
|
// no, init a straight curve
|
||||||
if (frameType == "GroundVehicleDifferential") {
|
if (frameType == "GroundVehicleDifferential") {
|
||||||
m_aircraft->groundVehicleThrottle2->initLinearCurve(curveValues.count(), 0.8, -0.8);
|
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 {
|
} else {
|
||||||
m_aircraft->groundVehicleThrottle2->initLinearCurve(curveValues.count(), 1.0);
|
m_aircraft->groundVehicleThrottle2->initLinearCurve(curveValues.count(), 1.0);
|
||||||
}
|
}
|
||||||
@ -388,7 +406,7 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleMotorcycle(QString airframeTyp
|
|||||||
|
|
||||||
// motor
|
// motor
|
||||||
int channel = m_aircraft->gvMotor2ChannelBox->currentIndex() - 1;
|
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_THROTTLECURVE1, 127);
|
||||||
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
|
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, 127);
|
||||||
|
|
||||||
@ -495,7 +513,7 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleCar(QString airframeType)
|
|||||||
|
|
||||||
channel = m_aircraft->gvMotor1ChannelBox->currentIndex() - 1;
|
channel = m_aircraft->gvMotor1ChannelBox->currentIndex() - 1;
|
||||||
setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_REVERSABLEMOTOR);
|
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;
|
channel = m_aircraft->gvMotor2ChannelBox->currentIndex() - 1;
|
||||||
setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_REVERSABLEMOTOR);
|
setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_REVERSABLEMOTOR);
|
||||||
|
@ -1698,12 +1698,31 @@ void ConfigInputWidget::resetChannelSettings()
|
|||||||
void ConfigInputWidget::resetActuatorSettings()
|
void ConfigInputWidget::resetActuatorSettings()
|
||||||
{
|
{
|
||||||
actuatorSettingsData = actuatorSettingsObj->getData();
|
actuatorSettingsData = actuatorSettingsObj->getData();
|
||||||
// Clear all output data : Min, max, neutral = 1500
|
|
||||||
// 1500 = servo middle, can be applied to all outputs because board is 'Alwaysdisarmed'
|
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||||
|
Q_ASSERT(mixer);
|
||||||
|
|
||||||
|
QString mixerType;
|
||||||
|
|
||||||
|
// Clear all output data : Min, max, neutral at same value
|
||||||
|
// 1000 for motors and 1500 for all others (Reversable motor included)
|
||||||
for (unsigned int output = 0; output < 12; output++) {
|
for (unsigned int output = 0; output < 12; output++) {
|
||||||
actuatorSettingsData.ChannelMax[output] = 1500;
|
QString mixerNumType = QString("Mixer%1Type").arg(output + 1);
|
||||||
actuatorSettingsData.ChannelMin[output] = 1000;
|
UAVObjectField *field = mixer->getField(mixerNumType);
|
||||||
actuatorSettingsData.ChannelNeutral[output] = 1500;
|
Q_ASSERT(field);
|
||||||
|
|
||||||
|
if (field) {
|
||||||
|
mixerType = field->getValue().toString();
|
||||||
|
}
|
||||||
|
if ((mixerType == "Motor") || (mixerType == "Disabled")) {
|
||||||
|
actuatorSettingsData.ChannelMax[output] = 1000;
|
||||||
|
actuatorSettingsData.ChannelMin[output] = 1000;
|
||||||
|
actuatorSettingsData.ChannelNeutral[output] = 1000;
|
||||||
|
} else {
|
||||||
|
actuatorSettingsData.ChannelMax[output] = 1500;
|
||||||
|
actuatorSettingsData.ChannelMin[output] = 1500;
|
||||||
|
actuatorSettingsData.ChannelNeutral[output] = 1500;
|
||||||
|
}
|
||||||
actuatorSettingsObj->setData(actuatorSettingsData);
|
actuatorSettingsObj->setData(actuatorSettingsData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "manualcontrolcommand.h"
|
#include "manualcontrolcommand.h"
|
||||||
#include "manualcontrolsettings.h"
|
#include "manualcontrolsettings.h"
|
||||||
#include "actuatorsettings.h"
|
#include "actuatorsettings.h"
|
||||||
|
#include "mixersettings.h"
|
||||||
#include "flightmodesettings.h"
|
#include "flightmodesettings.h"
|
||||||
#include "receiveractivity.h"
|
#include "receiveractivity.h"
|
||||||
#include <QGraphicsView>
|
#include <QGraphicsView>
|
||||||
|
@ -203,6 +203,15 @@ void ConfigOutputWidget::runChannelTests(bool state)
|
|||||||
if (state) {
|
if (state) {
|
||||||
sendAllChannelTests();
|
sendAllChannelTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add info at end
|
||||||
|
if (!state && isDirty()) {
|
||||||
|
QMessageBox mbox;
|
||||||
|
mbox.setText(QString(tr("You may want to save your neutral settings.")));
|
||||||
|
mbox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
mbox.setIcon(QMessageBox::Information);
|
||||||
|
mbox.exec();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputChannelForm *ConfigOutputWidget::getOutputChannelForm(const int index) const
|
OutputChannelForm *ConfigOutputWidget::getOutputChannelForm(const int index) const
|
||||||
|
@ -56,6 +56,15 @@ OutputChannelForm::OutputChannelForm(const int index, QWidget *parent) :
|
|||||||
ui.actuatorMax->setMinimum(MINOUTPUT_VALUE);
|
ui.actuatorMax->setMinimum(MINOUTPUT_VALUE);
|
||||||
ui.actuatorValue->setMinimum(MINOUTPUT_VALUE);
|
ui.actuatorValue->setMinimum(MINOUTPUT_VALUE);
|
||||||
|
|
||||||
|
// Remove keyboard focus
|
||||||
|
ui.actuatorMin->setFocusPolicy(Qt::ClickFocus);
|
||||||
|
ui.actuatorMax->setFocusPolicy(Qt::ClickFocus);
|
||||||
|
ui.actuatorRev->setFocusPolicy(Qt::ClickFocus);
|
||||||
|
ui.actuatorLink->setFocusPolicy(Qt::ClickFocus);
|
||||||
|
ui.actuatorValue->setFocusPolicy(Qt::NoFocus);
|
||||||
|
|
||||||
|
setChannelRange();
|
||||||
|
|
||||||
disableMouseWheelEvents();
|
disableMouseWheelEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,11 +129,12 @@ void OutputChannelForm::enableChannelTest(bool state)
|
|||||||
} else {
|
} else {
|
||||||
ui.actuatorMin->setEnabled(true);
|
ui.actuatorMin->setEnabled(true);
|
||||||
ui.actuatorMax->setEnabled(true);
|
ui.actuatorMax->setEnabled(true);
|
||||||
ui.actuatorRev->setEnabled(true);
|
if (m_mixerType != "Motor") {
|
||||||
|
ui.actuatorRev->setEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles the channel linked state for use in testing mode
|
* Toggles the channel linked state for use in testing mode
|
||||||
*/
|
*/
|
||||||
@ -139,7 +149,7 @@ void OutputChannelForm::linkToggled(bool state)
|
|||||||
if (!parent()) {
|
if (!parent()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int min = 10000;
|
int min = MAXOUTPUT_VALUE;
|
||||||
int linked_count = 0;
|
int linked_count = 0;
|
||||||
QList<OutputChannelForm *> outputChannelForms = parent()->findChildren<OutputChannelForm *>();
|
QList<OutputChannelForm *> outputChannelForms = parent()->findChildren<OutputChannelForm *>();
|
||||||
// set the linked channels of the parent widget to the same value
|
// set the linked channels of the parent widget to the same value
|
||||||
@ -179,7 +189,7 @@ int OutputChannelForm::max() const
|
|||||||
*/
|
*/
|
||||||
void OutputChannelForm::setMax(int maximum)
|
void OutputChannelForm::setMax(int maximum)
|
||||||
{
|
{
|
||||||
setRange(ui.actuatorMin->value(), maximum);
|
setRange(ui.actuatorMax->value(), maximum);
|
||||||
}
|
}
|
||||||
|
|
||||||
int OutputChannelForm::min() const
|
int OutputChannelForm::min() const
|
||||||
@ -192,7 +202,7 @@ int OutputChannelForm::min() const
|
|||||||
*/
|
*/
|
||||||
void OutputChannelForm::setMin(int minimum)
|
void OutputChannelForm::setMin(int minimum)
|
||||||
{
|
{
|
||||||
setRange(minimum, ui.actuatorMax->value());
|
setRange(minimum, ui.actuatorMin->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
int OutputChannelForm::neutral() const
|
int OutputChannelForm::neutral() const
|
||||||
@ -216,11 +226,6 @@ void OutputChannelForm::setRange(int minimum, int maximum)
|
|||||||
ui.actuatorMin->setValue(minimum);
|
ui.actuatorMin->setValue(minimum);
|
||||||
ui.actuatorMax->setValue(maximum);
|
ui.actuatorMax->setValue(maximum);
|
||||||
setChannelRange();
|
setChannelRange();
|
||||||
if (ui.actuatorMin->value() > ui.actuatorMax->value()) {
|
|
||||||
ui.actuatorRev->setChecked(true);
|
|
||||||
} else {
|
|
||||||
ui.actuatorRev->setChecked(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -232,39 +237,59 @@ void OutputChannelForm::setRange(int minimum, int maximum)
|
|||||||
*/
|
*/
|
||||||
void OutputChannelForm::setChannelRange()
|
void OutputChannelForm::setChannelRange()
|
||||||
{
|
{
|
||||||
int oldMini = ui.actuatorNeutral->minimum();
|
|
||||||
int minValue = ui.actuatorMin->value();
|
int minValue = ui.actuatorMin->value();
|
||||||
int maxValue = ui.actuatorMax->value();
|
int maxValue = ui.actuatorMax->value();
|
||||||
|
|
||||||
// int oldMaxi = ui.actuatorNeutral->maximum();
|
int oldMini = ui.actuatorNeutral->minimum();
|
||||||
|
int oldMaxi = ui.actuatorNeutral->maximum();
|
||||||
|
|
||||||
if (minValue <= maxValue) {
|
m_mixerType = outputMixerType();
|
||||||
ui.actuatorNeutral->setRange(ui.actuatorMin->value(), ui.actuatorMax->value());
|
|
||||||
ui.actuatorRev->setChecked(false);
|
// Red handle for Motors
|
||||||
|
if ((m_mixerType == "Motor") || (m_mixerType == "ReversableMotor")) {
|
||||||
|
ui.actuatorNeutral->setStyleSheet("QSlider::handle:horizontal { background: rgb(255, 100, 100); width: 18px; height: 28px;"
|
||||||
|
"margin: -3px 0; border-radius: 3px; border: 1px solid #777; }");
|
||||||
} else {
|
} else {
|
||||||
ui.actuatorNeutral->setRange(ui.actuatorMax->value(), ui.actuatorMin->value());
|
ui.actuatorNeutral->setStyleSheet("QSlider::handle:horizontal { background: rgb(196, 196, 196); width: 18px; height: 28px;"
|
||||||
ui.actuatorRev->setChecked(true);
|
"margin: -3px 0; border-radius: 3px; border: 1px solid #777; }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Normal motor will be *** never *** reversed : without arming a "Min" value (like 1900) can be applied !
|
||||||
|
if (m_mixerType == "Motor") {
|
||||||
|
if (minValue >= maxValue) {
|
||||||
|
// Keep old values
|
||||||
|
ui.actuatorMin->setValue(oldMini);
|
||||||
|
ui.actuatorMax->setValue(oldMaxi);
|
||||||
|
}
|
||||||
|
ui.actuatorRev->setChecked(false);
|
||||||
|
ui.actuatorRev->setEnabled(false);
|
||||||
|
ui.actuatorNeutral->setInvertedAppearance(false);
|
||||||
|
ui.actuatorNeutral->setRange(ui.actuatorMin->value(), ui.actuatorMax->value());
|
||||||
|
} else {
|
||||||
|
// Others output (!Motor)
|
||||||
|
// Auto check reverse checkbox SpinBox Min/Max changes
|
||||||
|
ui.actuatorRev->setEnabled(true);
|
||||||
|
if (minValue <= maxValue) {
|
||||||
|
ui.actuatorRev->setChecked(false);
|
||||||
|
ui.actuatorNeutral->setInvertedAppearance(false);
|
||||||
|
ui.actuatorNeutral->setRange(minValue, maxValue);
|
||||||
|
} else {
|
||||||
|
ui.actuatorRev->setChecked(true);
|
||||||
|
ui.actuatorNeutral->setInvertedAppearance(true);
|
||||||
|
ui.actuatorNeutral->setRange(maxValue, minValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If old neutral was Min, stay Min
|
||||||
if (ui.actuatorNeutral->value() == oldMini) {
|
if (ui.actuatorNeutral->value() == oldMini) {
|
||||||
ui.actuatorNeutral->setValue(ui.actuatorNeutral->minimum());
|
ui.actuatorNeutral->setValue(ui.actuatorNeutral->minimum());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable only outputs already set in mixer
|
// Enable only outputs already set in mixer
|
||||||
if (name() != "-") {
|
if (m_mixerType != "Disabled") {
|
||||||
ui.actuatorMin->setEnabled(true);
|
ui.actuatorMin->setEnabled(true);
|
||||||
ui.actuatorMax->setEnabled(true);
|
ui.actuatorMax->setEnabled(true);
|
||||||
ui.actuatorNeutral->setEnabled(true);
|
ui.actuatorNeutral->setEnabled(true);
|
||||||
ui.actuatorValue->setEnabled(true);
|
ui.actuatorValue->setEnabled(true);
|
||||||
|
|
||||||
// Enable checkboxes Rev and Link if some range
|
|
||||||
if (minValue != maxValue) {
|
|
||||||
ui.actuatorRev->setEnabled(true);
|
|
||||||
ui.actuatorLink->setEnabled(true);
|
|
||||||
} else {
|
|
||||||
ui.actuatorRev->setEnabled(false);
|
|
||||||
ui.actuatorLink->setEnabled(false);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ui.actuatorMin->setEnabled(false);
|
ui.actuatorMin->setEnabled(false);
|
||||||
ui.actuatorMax->setEnabled(false);
|
ui.actuatorMax->setEnabled(false);
|
||||||
@ -273,13 +298,9 @@ void OutputChannelForm::setChannelRange()
|
|||||||
ui.actuatorMin->setValue(1000);
|
ui.actuatorMin->setValue(1000);
|
||||||
ui.actuatorMax->setValue(1000);
|
ui.actuatorMax->setValue(1000);
|
||||||
ui.actuatorNeutral->setRange(minValue, maxValue);
|
ui.actuatorNeutral->setRange(minValue, maxValue);
|
||||||
ui.actuatorNeutral->setEnabled(false);
|
ui.actuatorNeutral->setValue(minValue);
|
||||||
ui.actuatorValue->setEnabled(false);
|
ui.actuatorValue->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (ui.actuatorNeutral->value() == oldMaxi)
|
|
||||||
// this can be dangerous if it happens to be controlling a motor at the time!
|
|
||||||
// ui.actuatorNeutral->setValue(ui.actuatorNeutral->maximum());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -287,30 +308,17 @@ void OutputChannelForm::setChannelRange()
|
|||||||
*/
|
*/
|
||||||
void OutputChannelForm::reverseChannel(bool state)
|
void OutputChannelForm::reverseChannel(bool state)
|
||||||
{
|
{
|
||||||
// Sanity check: if state became true, make sure the Maxvalue was higher than Minvalue
|
// if 'state' (reverse channel requested) apply only if not already reversed
|
||||||
// the situations below can happen!
|
if ((state && (ui.actuatorMax->value() > ui.actuatorMin->value()))
|
||||||
if (state && (ui.actuatorMax->value() < ui.actuatorMin->value())) {
|
|| (!state && (ui.actuatorMax->value() < ui.actuatorMin->value()))) {
|
||||||
return;
|
// Now, swap the min & max values (spin boxes)
|
||||||
}
|
int temp = ui.actuatorMax->value();
|
||||||
if (!state && (ui.actuatorMax->value() > ui.actuatorMin->value())) {
|
ui.actuatorMax->setValue(ui.actuatorMin->value());
|
||||||
return;
|
ui.actuatorMin->setValue(temp);
|
||||||
}
|
ui.actuatorNeutral->setInvertedAppearance(state);
|
||||||
|
|
||||||
// Now, swap the min & max values (only on the spinboxes, the slider does not change!)
|
setChannelRange();
|
||||||
int temp = ui.actuatorMax->value();
|
return;
|
||||||
ui.actuatorMax->setValue(ui.actuatorMin->value());
|
|
||||||
ui.actuatorMin->setValue(temp);
|
|
||||||
|
|
||||||
// Also update the channel value
|
|
||||||
// This is a trick to force the slider to update its value and
|
|
||||||
// emit the right signal itself, because our sendChannelTest(int) method
|
|
||||||
// relies on the object sender's identity.
|
|
||||||
if (ui.actuatorNeutral->value() < ui.actuatorNeutral->maximum()) {
|
|
||||||
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value() + 1);
|
|
||||||
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value() - 1);
|
|
||||||
} else {
|
|
||||||
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value() - 1);
|
|
||||||
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value() + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,10 +336,6 @@ void OutputChannelForm::sendChannelTest(int value)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ui.actuatorRev->isChecked()) {
|
|
||||||
// the channel is reversed
|
|
||||||
value = ui.actuatorMin->value() - value + ui.actuatorMax->value();
|
|
||||||
}
|
|
||||||
// update the label
|
// update the label
|
||||||
ui.actuatorValue->setValue(value);
|
ui.actuatorValue->setValue(value);
|
||||||
|
|
||||||
@ -370,3 +374,21 @@ void OutputChannelForm::sendChannelTest(int value)
|
|||||||
}
|
}
|
||||||
emit channelChanged(index(), value);
|
emit channelChanged(index(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Returns MixerType
|
||||||
|
*/
|
||||||
|
QString OutputChannelForm::outputMixerType()
|
||||||
|
{
|
||||||
|
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||||
|
|
||||||
|
Q_ASSERT(mixer);
|
||||||
|
|
||||||
|
QString mixerNumType = QString("Mixer%1Type").arg(index() + 1);
|
||||||
|
UAVObjectField *field = mixer->getField(mixerNumType);
|
||||||
|
Q_ASSERT(field);
|
||||||
|
QString mixerType = field->getValue().toString();
|
||||||
|
|
||||||
|
return mixerType;
|
||||||
|
}
|
||||||
|
@ -58,6 +58,7 @@ public slots:
|
|||||||
void setNeutral(int value);
|
void setNeutral(int value);
|
||||||
void setRange(int minimum, int maximum);
|
void setRange(int minimum, int maximum);
|
||||||
void enableChannelTest(bool state);
|
void enableChannelTest(bool state);
|
||||||
|
QString outputMixerType();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void channelChanged(int index, int value);
|
void channelChanged(int index, int value);
|
||||||
@ -65,6 +66,7 @@ signals:
|
|||||||
private:
|
private:
|
||||||
Ui::outputChannelForm ui;
|
Ui::outputChannelForm ui;
|
||||||
bool m_inChannelTest;
|
bool m_inChannelTest;
|
||||||
|
QString m_mixerType;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void linkToggled(bool state);
|
void linkToggled(bool state);
|
||||||
|
@ -104,6 +104,16 @@ void EscCalibrationPage::startButtonClicked()
|
|||||||
QString mixerTypePattern = "Mixer%1Type";
|
QString mixerTypePattern = "Mixer%1Type";
|
||||||
|
|
||||||
OutputCalibrationUtil::startOutputCalibration();
|
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++) {
|
for (quint32 i = 0; i < ActuatorSettings::CHANNELADDR_NUMELEM; i++) {
|
||||||
UAVObjectField *field = mSettings->getField(mixerTypePattern.arg(i + 1));
|
UAVObjectField *field = mSettings->getField(mixerTypePattern.arg(i + 1));
|
||||||
Q_ASSERT(field);
|
Q_ASSERT(field);
|
||||||
|
@ -54,6 +54,8 @@ OutputCalibrationPage::~OutputCalibrationPage()
|
|||||||
delete m_calibrationUtil;
|
delete m_calibrationUtil;
|
||||||
m_calibrationUtil = 0;
|
m_calibrationUtil = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OutputCalibrationUtil::stopOutputCalibration();
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,18 +72,32 @@ void OutputCalibrationPage::setupActuatorMinMaxAndNeutral(int motorChannelStart,
|
|||||||
// servos since a value out of range can actually destroy the
|
// servos since a value out of range can actually destroy the
|
||||||
// vehicle if unlucky.
|
// vehicle if unlucky.
|
||||||
// Motors are not that important. REMOVE propellers always!!
|
// Motors are not that important. REMOVE propellers always!!
|
||||||
|
OutputCalibrationUtil::startOutputCalibration();
|
||||||
|
|
||||||
for (int servoid = 0; servoid < 12; servoid++) {
|
for (int servoid = 0; servoid < 12; servoid++) {
|
||||||
if (servoid >= motorChannelStart && servoid <= motorChannelEnd) {
|
if (servoid >= motorChannelStart && servoid <= motorChannelEnd) {
|
||||||
// Set to motor safe values
|
// Set to motor safe values
|
||||||
m_actuatorSettings[servoid].channelMin = 1000;
|
m_actuatorSettings[servoid].channelMin = 1000;
|
||||||
m_actuatorSettings[servoid].channelNeutral = 1000;
|
m_actuatorSettings[servoid].channelNeutral = 1000;
|
||||||
m_actuatorSettings[servoid].channelMax = 1900;
|
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) {
|
} else if (servoid < totalUsedChannels) {
|
||||||
// Set to servo safe values
|
// Set to servo safe values
|
||||||
m_actuatorSettings[servoid].channelMin = 1500;
|
m_actuatorSettings[servoid].channelMin = 1500;
|
||||||
m_actuatorSettings[servoid].channelNeutral = 1500;
|
m_actuatorSettings[servoid].channelNeutral = 1500;
|
||||||
m_actuatorSettings[servoid].channelMax = 1500;
|
m_actuatorSettings[servoid].channelMax = 1500;
|
||||||
|
// Set initial servo output value
|
||||||
|
m_calibrationUtil->startChannelOutput(servoid, 1500);
|
||||||
|
m_calibrationUtil->stopChannelOutput();
|
||||||
} else {
|
} else {
|
||||||
// "Disable" these channels
|
// "Disable" these channels
|
||||||
m_actuatorSettings[servoid].channelMin = 1000;
|
m_actuatorSettings[servoid].channelMin = 1000;
|
||||||
@ -101,6 +117,8 @@ void OutputCalibrationPage::setupVehicle()
|
|||||||
m_currentWizardIndex = 0;
|
m_currentWizardIndex = 0;
|
||||||
m_vehicleScene->clear();
|
m_vehicleScene->clear();
|
||||||
|
|
||||||
|
resetOutputCalibrationUtil();
|
||||||
|
|
||||||
switch (getWizard()->getVehicleSubType()) {
|
switch (getWizard()->getVehicleSubType()) {
|
||||||
case SetupWizard::MULTI_ROTOR_TRI_Y:
|
case SetupWizard::MULTI_ROTOR_TRI_Y:
|
||||||
// Loads the SVG file resourse and sets the scene
|
// Loads the SVG file resourse and sets the scene
|
||||||
@ -120,7 +138,7 @@ void OutputCalibrationPage::setupVehicle()
|
|||||||
// The channel number to configure for each step.
|
// The channel number to configure for each step.
|
||||||
m_channelIndex << 0 << 0 << 1 << 2 << 3;
|
m_channelIndex << 0 << 0 << 1 << 2 << 3;
|
||||||
|
|
||||||
setupActuatorMinMaxAndNeutral(0, 2, 3);
|
setupActuatorMinMaxAndNeutral(0, 2, 4);
|
||||||
|
|
||||||
getWizard()->setActuatorSettings(m_actuatorSettings);
|
getWizard()->setActuatorSettings(m_actuatorSettings);
|
||||||
break;
|
break;
|
||||||
@ -180,7 +198,7 @@ void OutputCalibrationPage::setupVehicle()
|
|||||||
m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 5;
|
m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 5;
|
||||||
m_channelIndex << 0 << 2 << 0 << 5 << 1 << 3;
|
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);
|
getWizard()->setActuatorSettings(m_actuatorSettings);
|
||||||
break;
|
break;
|
||||||
@ -213,7 +231,7 @@ void OutputCalibrationPage::setupVehicle()
|
|||||||
m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 5;
|
m_vehicleHighlightElementIndexes << 0 << 1 << 2 << 3 << 4 << 5;
|
||||||
m_channelIndex << 0 << 2 << 0 << 5 << 3 << 1;
|
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);
|
getWizard()->setActuatorSettings(m_actuatorSettings);
|
||||||
break;
|
break;
|
||||||
@ -226,7 +244,7 @@ void OutputCalibrationPage::setupVehicle()
|
|||||||
m_vehicleHighlightElementIndexes << 0 << 1 << 2;
|
m_vehicleHighlightElementIndexes << 0 << 1 << 2;
|
||||||
m_channelIndex << 0 << 1 << 0;
|
m_channelIndex << 0 << 1 << 0;
|
||||||
|
|
||||||
setupActuatorMinMaxAndNeutral(0, 1, 2);
|
setupActuatorMinMaxAndNeutral(1, 1, 2);
|
||||||
|
|
||||||
getWizard()->setActuatorSettings(m_actuatorSettings);
|
getWizard()->setActuatorSettings(m_actuatorSettings);
|
||||||
break;
|
break;
|
||||||
@ -248,7 +266,7 @@ void OutputCalibrationPage::setupVehicle()
|
|||||||
m_vehicleHighlightElementIndexes << 0 << 1 << 2;
|
m_vehicleHighlightElementIndexes << 0 << 1 << 2;
|
||||||
m_channelIndex << 0 << 1 << 0;
|
m_channelIndex << 0 << 1 << 0;
|
||||||
|
|
||||||
setupActuatorMinMaxAndNeutral(0, 1, 2);
|
setupActuatorMinMaxAndNeutral(1, 1, 2);
|
||||||
|
|
||||||
getWizard()->setActuatorSettings(m_actuatorSettings);
|
getWizard()->setActuatorSettings(m_actuatorSettings);
|
||||||
break;
|
break;
|
||||||
@ -257,12 +275,6 @@ void OutputCalibrationPage::setupVehicle()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_calibrationUtil) {
|
|
||||||
delete m_calibrationUtil;
|
|
||||||
m_calibrationUtil = 0;
|
|
||||||
}
|
|
||||||
m_calibrationUtil = new OutputCalibrationUtil();
|
|
||||||
|
|
||||||
setupVehicleItems();
|
setupVehicleItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +338,15 @@ void OutputCalibrationPage::setWizardPage()
|
|||||||
if (currentChannel >= 0) {
|
if (currentChannel >= 0) {
|
||||||
if (currentPageIndex == 1) {
|
if (currentPageIndex == 1) {
|
||||||
ui->motorNeutralSlider->setValue(m_actuatorSettings[currentChannel].channelNeutral);
|
ui->motorNeutralSlider->setValue(m_actuatorSettings[currentChannel].channelNeutral);
|
||||||
|
ui->motorPWMValue->setText(QString(tr("Output value : <b>%1</b> µ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("<html><head/><body><p><span style=\" font-size:10pt;\">To find </span><span style=\" font-size:10pt; font-weight:600;\">the neutral rate for this reversable motor</span><span style=\" font-size:10pt;\">, 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. <br/><br/>When done press button again to stop.</span></p></body></html>"));
|
||||||
|
}
|
||||||
} else if (currentPageIndex == 2) {
|
} else if (currentPageIndex == 2) {
|
||||||
|
ui->servoPWMValue->setText(tr("Output value : <b>%1</b> µs").arg(m_actuatorSettings[currentChannel].channelNeutral));
|
||||||
if (m_actuatorSettings[currentChannel].channelMax < m_actuatorSettings[currentChannel].channelMin &&
|
if (m_actuatorSettings[currentChannel].channelMax < m_actuatorSettings[currentChannel].channelMin &&
|
||||||
!ui->reverseCheckbox->isChecked()) {
|
!ui->reverseCheckbox->isChecked()) {
|
||||||
ui->reverseCheckbox->setChecked(true);
|
ui->reverseCheckbox->setChecked(true);
|
||||||
@ -416,6 +436,11 @@ void OutputCalibrationPage::on_motorNeutralButton_toggled(bool checked)
|
|||||||
ui->motorNeutralSlider->setEnabled(checked);
|
ui->motorNeutralSlider->setEnabled(checked);
|
||||||
quint16 channel = getCurrentChannel();
|
quint16 channel = getCurrentChannel();
|
||||||
quint16 safeValue = m_actuatorSettings[channel].channelMin;
|
quint16 safeValue = m_actuatorSettings[channel].channelMin;
|
||||||
|
|
||||||
|
if (m_actuatorSettings[channel].isReversableMotor) {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +450,6 @@ void OutputCalibrationPage::onStartButtonToggle(QAbstractButton *button, quint16
|
|||||||
if (checkAlarms()) {
|
if (checkAlarms()) {
|
||||||
enableButtons(false);
|
enableButtons(false);
|
||||||
enableServoSliders(true);
|
enableServoSliders(true);
|
||||||
OutputCalibrationUtil::startOutputCalibration();
|
|
||||||
m_calibrationUtil->startChannelOutput(channel, safeValue);
|
m_calibrationUtil->startChannelOutput(channel, safeValue);
|
||||||
slider->setValue(value);
|
slider->setValue(value);
|
||||||
m_calibrationUtil->setChannelOutputValue(value);
|
m_calibrationUtil->setChannelOutputValue(value);
|
||||||
@ -433,8 +457,16 @@ void OutputCalibrationPage::onStartButtonToggle(QAbstractButton *button, quint16
|
|||||||
button->setChecked(false);
|
button->setChecked(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Servos and ReversableMotors
|
||||||
|
m_calibrationUtil->startChannelOutput(channel, m_actuatorSettings[channel].channelNeutral);
|
||||||
|
|
||||||
|
// Normal motor
|
||||||
|
if ((button == ui->motorNeutralButton) && !m_actuatorSettings[channel].isReversableMotor) {
|
||||||
|
m_calibrationUtil->startChannelOutput(channel, m_actuatorSettings[channel].channelMin);
|
||||||
|
}
|
||||||
|
|
||||||
m_calibrationUtil->stopChannelOutput();
|
m_calibrationUtil->stopChannelOutput();
|
||||||
OutputCalibrationUtil::stopOutputCalibration();
|
|
||||||
enableServoSliders(false);
|
enableServoSliders(false);
|
||||||
enableButtons(true);
|
enableButtons(true);
|
||||||
}
|
}
|
||||||
@ -492,6 +524,8 @@ void OutputCalibrationPage::debugLogChannelValues()
|
|||||||
void OutputCalibrationPage::on_motorNeutralSlider_valueChanged(int value)
|
void OutputCalibrationPage::on_motorNeutralSlider_valueChanged(int value)
|
||||||
{
|
{
|
||||||
Q_UNUSED(value);
|
Q_UNUSED(value);
|
||||||
|
ui->motorPWMValue->setText(tr("Output value : <b>%1</b> µs").arg(value));
|
||||||
|
|
||||||
if (ui->motorNeutralButton->isChecked()) {
|
if (ui->motorNeutralButton->isChecked()) {
|
||||||
quint16 value = ui->motorNeutralSlider->value();
|
quint16 value = ui->motorNeutralSlider->value();
|
||||||
m_calibrationUtil->setChannelOutputValue(value);
|
m_calibrationUtil->setChannelOutputValue(value);
|
||||||
@ -515,6 +549,7 @@ void OutputCalibrationPage::on_servoCenterAngleSlider_valueChanged(int position)
|
|||||||
m_calibrationUtil->setChannelOutputValue(value);
|
m_calibrationUtil->setChannelOutputValue(value);
|
||||||
quint16 channel = getCurrentChannel();
|
quint16 channel = getCurrentChannel();
|
||||||
m_actuatorSettings[channel].channelNeutral = value;
|
m_actuatorSettings[channel].channelNeutral = value;
|
||||||
|
ui->servoPWMValue->setText(tr("Output value : <b>%1</b> µs").arg(value));
|
||||||
|
|
||||||
// Adjust min and max
|
// Adjust min and max
|
||||||
if (ui->reverseCheckbox->isChecked()) {
|
if (ui->reverseCheckbox->isChecked()) {
|
||||||
@ -615,3 +650,12 @@ void OutputCalibrationPage::on_reverseCheckbox_toggled(bool checked)
|
|||||||
ui->servoMaxAngleSlider->setValue(m_actuatorSettings[getCurrentChannel()].channelMax);
|
ui->servoMaxAngleSlider->setValue(m_actuatorSettings[getCurrentChannel()].channelMax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OutputCalibrationPage::resetOutputCalibrationUtil()
|
||||||
|
{
|
||||||
|
if (m_calibrationUtil) {
|
||||||
|
delete m_calibrationUtil;
|
||||||
|
m_calibrationUtil = 0;
|
||||||
|
}
|
||||||
|
m_calibrationUtil = new OutputCalibrationUtil();
|
||||||
|
}
|
||||||
|
@ -100,6 +100,7 @@ private:
|
|||||||
QList<actuatorChannelSettings> m_actuatorSettings;
|
QList<actuatorChannelSettings> m_actuatorSettings;
|
||||||
|
|
||||||
OutputCalibrationUtil *m_calibrationUtil;
|
OutputCalibrationUtil *m_calibrationUtil;
|
||||||
|
void resetOutputCalibrationUtil();
|
||||||
|
|
||||||
static const QString MULTI_SVG_FILE;
|
static const QString MULTI_SVG_FILE;
|
||||||
static const QString FIXEDWING_SVG_FILE;
|
static const QString FIXEDWING_SVG_FILE;
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>600</width>
|
<width>776</width>
|
||||||
<height>400</height>
|
<height>505</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -94,8 +94,10 @@ p, li { white-space: pre-wrap; }
|
|||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In this step we will set the neutral rate for the motor highlighted in the illustration to the right. <br />Please pay attention to the details and in particular the motors position and its rotation direction. Ensure the motors are spinning in the correct direction as shown in the diagram. Swap any 2 motor wires to change the direction of a motor. </span></p>
|
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">In this step we will set the neutral rate for the motor highlighted in the illustration to the right. <br />Please pay attention to the details and in particular the motors position and its rotation direction. Ensure the motors are spinning in the correct direction as shown in the diagram. Swap any 2 motor wires to change the direction of a motor. </span></p></body></html></string>
|
||||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">To find </span><span style=" font-size:10pt; font-weight:600;">the neutral rate for this motor</span><span style=" font-size:10pt;">, press the Start button below and slide the slider to the right until the motor just starts to spin stable. <br /><br />When done press button again to stop.</span></p></body></html></string>
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::RichText</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
@ -105,6 +107,29 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="motorInfo">
|
||||||
|
<property name="text">
|
||||||
|
<string><html><head/><body><p><span style=" font-size:10pt;">To find </span><span style=" font-size:10pt; font-weight:600;">the neutral rate for this motor</span><span style=" font-size:10pt;">, press the Start button below and slide the slider to the right until the motor just starts to spin stable. <br/><br/>When done press button again to stop.</span></p></body></html></string>
|
||||||
|
</property>
|
||||||
|
<property name="textFormat">
|
||||||
|
<enum>Qt::RichText</enum>
|
||||||
|
</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="QLabel" name="motorPWMValue">
|
||||||
|
<property name="text">
|
||||||
|
<string>Output value: 1000µs</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSlider" name="motorNeutralSlider">
|
<widget class="QSlider" name="motorNeutralSlider">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
@ -184,6 +209,13 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="servoPWMValue">
|
||||||
|
<property name="text">
|
||||||
|
<string>Output value: 1000µs</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="widget" native="true">
|
<widget class="QWidget" name="widget" native="true">
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
@ -679,8 +679,10 @@ void VehicleConfigurationHelper::applyMixerConfiguration(mixerChannelSettings ch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default maxThrottle
|
// Default maxThrottle and minThrottle
|
||||||
float maxThrottle = 0.9;
|
float maxThrottle = 0.9;
|
||||||
|
float minThrottle = 0;
|
||||||
|
|
||||||
|
|
||||||
// Save mixer values for sliders
|
// Save mixer values for sliders
|
||||||
switch (m_configSource->getVehicleType()) {
|
switch (m_configSource->getVehicleType()) {
|
||||||
@ -737,17 +739,26 @@ void VehicleConfigurationHelper::applyMixerConfiguration(mixerChannelSettings ch
|
|||||||
{
|
{
|
||||||
switch (m_configSource->getVehicleSubType()) {
|
switch (m_configSource->getVehicleSubType()) {
|
||||||
case VehicleConfigurationSource::GROUNDVEHICLE_MOTORCYCLE:
|
case VehicleConfigurationSource::GROUNDVEHICLE_MOTORCYCLE:
|
||||||
case VehicleConfigurationSource::GROUNDVEHICLE_CAR:
|
|
||||||
mSettings->setMixerValueRoll(100);
|
mSettings->setMixerValueRoll(100);
|
||||||
mSettings->setMixerValuePitch(100);
|
mSettings->setMixerValuePitch(100);
|
||||||
mSettings->setMixerValueYaw(100);
|
mSettings->setMixerValueYaw(100);
|
||||||
maxThrottle = 1;
|
maxThrottle = 1;
|
||||||
break;
|
break;
|
||||||
|
case VehicleConfigurationSource::GROUNDVEHICLE_CAR:
|
||||||
|
mSettings->setMixerValueRoll(100);
|
||||||
|
mSettings->setMixerValuePitch(100);
|
||||||
|
mSettings->setMixerValueYaw(100);
|
||||||
|
// Set curve2 range from -0.926 to 1 : take in account 4% offset in Throttle input
|
||||||
|
// 0.5 / 0.54 = 0.926
|
||||||
|
maxThrottle = 1;
|
||||||
|
minThrottle = -0.926;
|
||||||
|
break;
|
||||||
case VehicleConfigurationSource::GROUNDVEHICLE_DIFFERENTIAL:
|
case VehicleConfigurationSource::GROUNDVEHICLE_DIFFERENTIAL:
|
||||||
mSettings->setMixerValueRoll(100);
|
mSettings->setMixerValueRoll(100);
|
||||||
mSettings->setMixerValuePitch(100);
|
mSettings->setMixerValuePitch(100);
|
||||||
mSettings->setMixerValueYaw(100);
|
mSettings->setMixerValueYaw(100);
|
||||||
maxThrottle = 0.8;
|
maxThrottle = 0.8;
|
||||||
|
minThrottle = -0.8;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -765,7 +776,7 @@ void VehicleConfigurationHelper::applyMixerConfiguration(mixerChannelSettings ch
|
|||||||
UAVObjectField *field = mSettings->getField(throttlePattern.arg(i));
|
UAVObjectField *field = mSettings->getField(throttlePattern.arg(i));
|
||||||
Q_ASSERT(field);
|
Q_ASSERT(field);
|
||||||
for (quint32 i = 0; i < field->getNumElements(); i++) {
|
for (quint32 i = 0; i < field->getNumElements(); i++) {
|
||||||
field->setValue(i * (maxThrottle / (field->getNumElements() - 1)), i);
|
field->setValue(minThrottle + (i * ((maxThrottle - minThrottle) / (field->getNumElements() - 1))), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2033,7 +2044,7 @@ void VehicleConfigurationHelper::setupCar()
|
|||||||
channels[0].yaw = 100;
|
channels[0].yaw = 100;
|
||||||
|
|
||||||
// Motor (Chan 2)
|
// Motor (Chan 2)
|
||||||
channels[1].type = MIXER_TYPE_MOTOR;
|
channels[1].type = MIXER_TYPE_REVERSABLEMOTOR;
|
||||||
channels[1].throttle1 = 0;
|
channels[1].throttle1 = 0;
|
||||||
channels[1].throttle2 = 100;
|
channels[1].throttle2 = 100;
|
||||||
channels[1].roll = 0;
|
channels[1].roll = 0;
|
||||||
@ -2058,7 +2069,7 @@ void VehicleConfigurationHelper::setupTank()
|
|||||||
GUIConfigDataUnion guiSettings = getGUIConfigData();
|
GUIConfigDataUnion guiSettings = getGUIConfigData();
|
||||||
|
|
||||||
// Left Motor (Chan 1)
|
// Left Motor (Chan 1)
|
||||||
channels[0].type = MIXER_TYPE_SERVO;
|
channels[0].type = MIXER_TYPE_REVERSABLEMOTOR;
|
||||||
channels[0].throttle1 = 0;
|
channels[0].throttle1 = 0;
|
||||||
channels[0].throttle2 = 100;
|
channels[0].throttle2 = 100;
|
||||||
channels[0].roll = 0;
|
channels[0].roll = 0;
|
||||||
@ -2066,7 +2077,7 @@ void VehicleConfigurationHelper::setupTank()
|
|||||||
channels[0].yaw = 100;
|
channels[0].yaw = 100;
|
||||||
|
|
||||||
// Right Motor (Chan 2)
|
// Right Motor (Chan 2)
|
||||||
channels[1].type = MIXER_TYPE_MOTOR;
|
channels[1].type = MIXER_TYPE_REVERSABLEMOTOR;
|
||||||
channels[1].throttle1 = 0;
|
channels[1].throttle1 = 0;
|
||||||
channels[1].throttle2 = 100;
|
channels[1].throttle2 = 100;
|
||||||
channels[1].roll = 0;
|
channels[1].roll = 0;
|
||||||
@ -2098,10 +2109,10 @@ void VehicleConfigurationHelper::setupMotorcycle()
|
|||||||
channels[0].pitch = 0;
|
channels[0].pitch = 0;
|
||||||
channels[0].yaw = 100;
|
channels[0].yaw = 100;
|
||||||
|
|
||||||
// Motor (Chan 2)
|
// Motor (Chan 2) : Curve1, no reverse
|
||||||
channels[1].type = MIXER_TYPE_MOTOR;
|
channels[1].type = MIXER_TYPE_MOTOR;
|
||||||
channels[1].throttle1 = 0;
|
channels[1].throttle1 = 100;
|
||||||
channels[1].throttle2 = 100;
|
channels[1].throttle2 = 0;
|
||||||
channels[1].roll = 0;
|
channels[1].roll = 0;
|
||||||
channels[1].pitch = 0;
|
channels[1].pitch = 0;
|
||||||
channels[1].yaw = 0;
|
channels[1].yaw = 0;
|
||||||
|
@ -46,9 +46,10 @@ struct actuatorChannelSettings {
|
|||||||
quint16 channelMin;
|
quint16 channelMin;
|
||||||
quint16 channelNeutral;
|
quint16 channelNeutral;
|
||||||
quint16 channelMax;
|
quint16 channelMax;
|
||||||
|
bool isReversableMotor;
|
||||||
|
|
||||||
// Default values
|
// Default values
|
||||||
actuatorChannelSettings() : channelMin(1000), channelNeutral(1000), channelMax(1900) {}
|
actuatorChannelSettings() : channelMin(1000), channelNeutral(1000), channelMax(1900), isReversableMotor(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user