You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
828 lines
28 KiB
828 lines
28 KiB
10 years ago
|
/*=====================================================================
|
||
|
|
||
|
QGroundControl Open Source Ground Control Station
|
||
|
|
||
|
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||
|
|
||
|
This file is part of the QGROUNDCONTROL project
|
||
|
|
||
|
QGROUNDCONTROL is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
QGROUNDCONTROL is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
======================================================================*/
|
||
|
|
||
|
/// @file
|
||
|
/// @author Don Gagne <don@thegagnes.com>
|
||
|
|
||
9 years ago
|
#include "PX4AdvancedFlightModesController.h"
|
||
10 years ago
|
#include "QGCMAVLink.h"
|
||
|
#include "AutoPilotPluginManager.h"
|
||
|
|
||
|
#include <QVariant>
|
||
|
#include <QQmlProperty>
|
||
|
|
||
9 years ago
|
PX4AdvancedFlightModesController::PX4AdvancedFlightModesController(void) :
|
||
10 years ago
|
_validConfiguration(false),
|
||
10 years ago
|
_channelCount(18),
|
||
|
_manualModeSelected(false),
|
||
|
_assistModeSelected(false),
|
||
|
_autoModeSelected(false),
|
||
|
_acroModeSelected(false),
|
||
|
_altCtlModeSelected(false),
|
||
|
_posCtlModeSelected(false),
|
||
|
_missionModeSelected(false),
|
||
|
_loiterModeSelected(false),
|
||
|
_returnModeSelected(false),
|
||
|
_offboardModeSelected(false)
|
||
10 years ago
|
{
|
||
10 years ago
|
QStringList usedParams;
|
||
10 years ago
|
usedParams << "RC_MAP_THROTTLE" << "RC_MAP_YAW" << "RC_MAP_PITCH" << "RC_MAP_ROLL" << "RC_MAP_FLAPS" << "RC_MAP_AUX1" << "RC_MAP_AUX2" <<
|
||
|
"RC_MAP_MODE_SW" << "RC_MAP_RETURN_SW" << "RC_MAP_LOITER_SW" << "RC_MAP_POSCTL_SW" << "RC_MAP_OFFB_SW" << "RC_MAP_ACRO_SW";
|
||
10 years ago
|
if (!_allParametersExists(FactSystem::defaultComponentId, usedParams)) {
|
||
|
return;
|
||
|
}
|
||
10 years ago
|
|
||
|
_init();
|
||
10 years ago
|
_validateConfiguration();
|
||
10 years ago
|
|
||
9 years ago
|
connect(_vehicle, &Vehicle::rcChannelsChanged, this, &PX4AdvancedFlightModesController::_rcChannelsChanged);
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::_init(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
// FIXME: What about VTOL? That confuses the whole Flight Mode naming scheme
|
||
10 years ago
|
_fixedWing = _vehicle->vehicleType() == MAV_TYPE_FIXED_WING;
|
||
10 years ago
|
|
||
|
// We need to know min and max for channel in order to calculate percentage range
|
||
|
for (int channel=0; channel<_chanMax; channel++) {
|
||
|
QString rcMinParam, rcMaxParam, rcRevParam;
|
||
|
|
||
|
rcMinParam = QString("RC%1_MIN").arg(channel+1);
|
||
|
rcMaxParam = QString("RC%1_MAX").arg(channel+1);
|
||
|
rcRevParam = QString("RC%1_REV").arg(channel+1);
|
||
|
|
||
|
QVariant value;
|
||
|
|
||
10 years ago
|
_rgRCMin[channel] = getParameterFact(FactSystem::defaultComponentId, rcMinParam)->rawValue().toInt();
|
||
|
_rgRCMax[channel] = getParameterFact(FactSystem::defaultComponentId, rcMaxParam)->rawValue().toInt();
|
||
10 years ago
|
|
||
10 years ago
|
float floatReversed = getParameterFact(-1, rcRevParam)->rawValue().toFloat();
|
||
10 years ago
|
_rgRCReversed[channel] = floatReversed == -1.0f;
|
||
|
|
||
|
_rcValues[channel] = 0.0;
|
||
10 years ago
|
}
|
||
10 years ago
|
|
||
|
// RC_CHAN_CNT parameter is set by Radio Cal to specify the number of radio channels.
|
||
|
if (parameterExists(FactSystem::defaultComponentId, "RC_CHAN_CNT")) {
|
||
10 years ago
|
_channelCount = getParameterFact(FactSystem::defaultComponentId, "RC_CHAN_CNT")->rawValue().toInt();
|
||
10 years ago
|
} else {
|
||
|
_channelCount =_chanMax;
|
||
|
}
|
||
|
if (_channelCount <= 0 || _channelCount > _chanMax) {
|
||
|
// Parameter exists, but has not yet been set or is invalid. Use default
|
||
|
_channelCount = _chanMax;
|
||
|
}
|
||
|
|
||
10 years ago
|
int modeChannel = getParameterFact(-1, "RC_MAP_MODE_SW")->rawValue().toInt();
|
||
|
int posCtlChannel = getParameterFact(-1, "RC_MAP_POSCTL_SW")->rawValue().toInt();
|
||
|
int loiterChannel = getParameterFact(-1, "RC_MAP_LOITER_SW")->rawValue().toInt();
|
||
10 years ago
|
|
||
|
if (posCtlChannel == 0) {
|
||
|
// PosCtl disabled so AltCtl must move back to main Mode switch
|
||
|
_assistModeVisible = false;
|
||
|
} else {
|
||
|
// Assist mode is visible if AltCtl/PosCtl are on seperate channel from main Mode switch
|
||
|
_assistModeVisible = posCtlChannel != modeChannel;
|
||
|
}
|
||
|
|
||
|
if (loiterChannel == 0) {
|
||
|
// Loiter disabled so Mission must move back to main Mode switch
|
||
|
_autoModeVisible = false;
|
||
|
} else {
|
||
|
// Auto mode is visible if Mission/Loiter are on seperate channel from main Mode switch
|
||
|
_autoModeVisible = loiterChannel != modeChannel;
|
||
|
}
|
||
|
|
||
|
// Setup the channel combobox model
|
||
|
|
||
|
QList<int> usedChannels;
|
||
|
QStringList attitudeParams;
|
||
|
|
||
|
attitudeParams << "RC_MAP_THROTTLE" << "RC_MAP_YAW" << "RC_MAP_PITCH" << "RC_MAP_ROLL" << "RC_MAP_FLAPS" << "RC_MAP_AUX1" << "RC_MAP_AUX2";
|
||
10 years ago
|
foreach(const QString &attitudeParam, attitudeParams) {
|
||
10 years ago
|
int channel = getParameterFact(-1, attitudeParam)->rawValue().toInt();
|
||
10 years ago
|
if (channel != 0) {
|
||
|
usedChannels << channel;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_channelListModel << "Disabled";
|
||
|
_channelListModelChannel << 0;
|
||
10 years ago
|
for (int channel=1; channel<=_channelCount; channel++) {
|
||
10 years ago
|
if (!usedChannels.contains(channel)) {
|
||
|
_channelListModel << QString("Channel %1").arg(channel);
|
||
|
_channelListModelChannel << channel;
|
||
|
}
|
||
|
}
|
||
|
|
||
10 years ago
|
// Setup reserved channels string for ui
|
||
|
|
||
|
bool first = true;
|
||
|
foreach (int usedChannel, usedChannels) {
|
||
|
if (!first) {
|
||
|
_reservedChannels += ", ";
|
||
|
}
|
||
|
_reservedChannels += QString("%1").arg(usedChannel);
|
||
|
first = false;
|
||
|
}
|
||
|
|
||
10 years ago
|
_recalcModeRows();
|
||
10 years ago
|
}
|
||
|
|
||
|
/// This will look for parameter settings which would cause the config to not run correctly.
|
||
|
/// It will set _validConfiguration and _configurationErrors as needed.
|
||
9 years ago
|
void PX4AdvancedFlightModesController::_validateConfiguration(void)
|
||
10 years ago
|
{
|
||
|
_validConfiguration = true;
|
||
|
|
||
|
// Make sure switches are valid and within channel range
|
||
|
|
||
10 years ago
|
QStringList switchParams;
|
||
10 years ago
|
QList<int> switchMappings;
|
||
|
|
||
10 years ago
|
switchParams << "RC_MAP_MODE_SW" << "RC_MAP_ACRO_SW" << "RC_MAP_POSCTL_SW" << "RC_MAP_LOITER_SW" << "RC_MAP_RETURN_SW" << "RC_MAP_OFFB_SW";
|
||
10 years ago
|
|
||
|
for(int i=0; i<switchParams.count(); i++) {
|
||
10 years ago
|
int map = getParameterFact(FactSystem::defaultComponentId, switchParams[i])->rawValue().toInt();
|
||
10 years ago
|
switchMappings << map;
|
||
|
|
||
|
if (map < 0 || map > _channelCount) {
|
||
|
_validConfiguration = false;
|
||
10 years ago
|
_configurationErrors += QString("%1 is set to %2. Mapping must between 0 and %3 (inclusive).\n").arg(switchParams[i]).arg(map).arg(_channelCount);
|
||
10 years ago
|
}
|
||
|
}
|
||
|
|
||
10 years ago
|
// Make sure mode switches are not double-mapped
|
||
10 years ago
|
|
||
10 years ago
|
QStringList attitudeParams;
|
||
10 years ago
|
|
||
10 years ago
|
attitudeParams << "RC_MAP_THROTTLE" << "RC_MAP_YAW" << "RC_MAP_PITCH" << "RC_MAP_ROLL" << "RC_MAP_FLAPS" << "RC_MAP_AUX1" << "RC_MAP_AUX2";
|
||
10 years ago
|
|
||
|
for (int i=0; i<attitudeParams.count(); i++) {
|
||
10 years ago
|
int map = getParameterFact(FactSystem::defaultComponentId, attitudeParams[i])->rawValue().toInt();
|
||
10 years ago
|
|
||
|
for (int j=0; j<switchParams.count(); j++) {
|
||
|
if (map != 0 && map == switchMappings[j]) {
|
||
|
_validConfiguration = false;
|
||
10 years ago
|
_configurationErrors += QString("%1 is set to same channel as %2.\n").arg(switchParams[j]).arg(attitudeParams[i]);
|
||
10 years ago
|
}
|
||
|
}
|
||
|
}
|
||
10 years ago
|
|
||
10 years ago
|
// Validate thresholds within range
|
||
10 years ago
|
|
||
10 years ago
|
QStringList thresholdParams;
|
||
10 years ago
|
|
||
10 years ago
|
thresholdParams << "RC_ASSIST_TH" << "RC_AUTO_TH" << "RC_ACRO_TH" << "RC_POSCTL_TH" << "RC_LOITER_TH" << "RC_RETURN_TH" << "RC_OFFB_TH";
|
||
10 years ago
|
|
||
10 years ago
|
foreach(const QString &thresholdParam, thresholdParams) {
|
||
10 years ago
|
float threshold = getParameterFact(-1, thresholdParam)->rawValue().toFloat();
|
||
10 years ago
|
if (threshold < 0.0f || threshold > 1.0f) {
|
||
|
_validConfiguration = false;
|
||
|
_configurationErrors += QString("%1 is set to %2. Threshold must between 0.0 and 1.0 (inclusive).\n").arg(thresholdParam).arg(threshold);
|
||
10 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
10 years ago
|
/// Connected to Vehicle::rcChannelsChanged signal
|
||
9 years ago
|
void PX4AdvancedFlightModesController::_rcChannelsChanged(int channelCount, int pwmValues[Vehicle::cMaxRcChannels])
|
||
10 years ago
|
{
|
||
10 years ago
|
for (int channel=0; channel<channelCount; channel++) {
|
||
|
int channelValue = pwmValues[channel];
|
||
|
|
||
|
if (channelValue != -1) {
|
||
|
if (channelValue < _rgRCMin[channel]) {
|
||
|
channelValue= _rgRCMin[channel];
|
||
|
}
|
||
|
if (channelValue > _rgRCMax[channel]) {
|
||
|
channelValue= _rgRCMax[channel];
|
||
|
}
|
||
|
|
||
|
float percentRange = (channelValue - _rgRCMin[channel]) / (float)(_rgRCMax[channel] - _rgRCMin[channel]);
|
||
|
if (_rgRCReversed[channel]) {
|
||
|
percentRange = 1.0 - percentRange;
|
||
|
}
|
||
|
|
||
|
_rcValues[channel] = percentRange;
|
||
|
}
|
||
10 years ago
|
}
|
||
|
|
||
10 years ago
|
_recalcModeSelections();
|
||
|
|
||
10 years ago
|
emit switchLiveRangeChanged();
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::_switchLiveRange(const QString& param)
|
||
10 years ago
|
{
|
||
|
QVariant value;
|
||
|
|
||
10 years ago
|
int channel = getParameterFact(-1, param)->rawValue().toInt();
|
||
10 years ago
|
if (channel == 0) {
|
||
10 years ago
|
return 0.0;
|
||
10 years ago
|
} else {
|
||
|
return _rcValues[channel - 1];
|
||
|
}
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::manualModeRcValue(void)
|
||
10 years ago
|
{
|
||
|
return _switchLiveRange("RC_MAP_MODE_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::assistModeRcValue(void)
|
||
10 years ago
|
{
|
||
|
return manualModeRcValue();
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::autoModeRcValue(void)
|
||
10 years ago
|
{
|
||
|
return manualModeRcValue();
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::acroModeRcValue(void)
|
||
10 years ago
|
{
|
||
|
return _switchLiveRange("RC_MAP_ACRO_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::altCtlModeRcValue(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
int posCtlSwitchChannel = getParameterFact(-1, "RC_MAP_POSCTL_SW")->rawValue().toInt();
|
||
10 years ago
|
|
||
|
if (posCtlSwitchChannel == 0) {
|
||
|
return _switchLiveRange("RC_MAP_MODE_SW");
|
||
|
} else {
|
||
|
return _switchLiveRange("RC_MAP_POSCTL_SW");
|
||
|
}
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::posCtlModeRcValue(void)
|
||
10 years ago
|
{
|
||
|
return _switchLiveRange("RC_MAP_POSCTL_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::missionModeRcValue(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
int returnSwitchChannel = getParameterFact(-1, "RC_MAP_RETURN_SW")->rawValue().toInt();
|
||
|
int loiterSwitchChannel = getParameterFact(-1, "RC_MAP_LOITER_SW")->rawValue().toInt();
|
||
10 years ago
|
|
||
|
const char* switchChannelParam = "RC_MAP_MODE_SW";
|
||
|
|
||
|
if (returnSwitchChannel == 0) {
|
||
|
if (loiterSwitchChannel != 0) {
|
||
|
switchChannelParam = "RC_MAP_LOITER_SW";
|
||
|
}
|
||
|
} else {
|
||
|
if (loiterSwitchChannel == 0) {
|
||
|
switchChannelParam = "RC_MAP_RETURN_SW";
|
||
|
} else {
|
||
|
switchChannelParam = "RC_MAP_LOITER_SW";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return _switchLiveRange(switchChannelParam);
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::loiterModeRcValue(void)
|
||
10 years ago
|
{
|
||
|
return _switchLiveRange("RC_MAP_LOITER_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::returnModeRcValue(void)
|
||
10 years ago
|
{
|
||
|
return _switchLiveRange("RC_MAP_RETURN_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::offboardModeRcValue(void)
|
||
10 years ago
|
{
|
||
|
return _switchLiveRange("RC_MAP_OFFB_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::_recalcModeSelections(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
_manualModeSelected = false;
|
||
|
_assistModeSelected = false;
|
||
|
_autoModeSelected = false;
|
||
|
_acroModeSelected = false;
|
||
|
_altCtlModeSelected = false;
|
||
|
_posCtlModeSelected = false;
|
||
|
_missionModeSelected = false;
|
||
|
_loiterModeSelected = false;
|
||
|
_returnModeSelected = false;
|
||
|
_offboardModeSelected = false;
|
||
|
|
||
|
// Convert channels to 0-based, -1 signals not mapped
|
||
10 years ago
|
int modeSwitchChannel = getParameterFact(-1, "RC_MAP_MODE_SW")->rawValue().toInt() - 1;
|
||
|
int acroSwitchChannel = getParameterFact(-1, "RC_MAP_ACRO_SW")->rawValue().toInt() - 1;
|
||
|
int posCtlSwitchChannel = getParameterFact(-1, "RC_MAP_POSCTL_SW")->rawValue().toInt() - 1;
|
||
|
int loiterSwitchChannel = getParameterFact(-1, "RC_MAP_LOITER_SW")->rawValue().toInt() - 1;
|
||
|
int returnSwitchChannel = getParameterFact(-1, "RC_MAP_RETURN_SW")->rawValue().toInt() - 1;
|
||
|
int offboardSwitchChannel = getParameterFact(-1, "RC_MAP_OFFB_SW")->rawValue().toInt() - 1;
|
||
|
|
||
|
double autoThreshold = getParameterFact(-1, "RC_AUTO_TH")->rawValue().toDouble();
|
||
|
double assistThreshold = getParameterFact(-1, "RC_ASSIST_TH")->rawValue().toDouble();
|
||
|
double acroThreshold = getParameterFact(-1, "RC_ACRO_TH")->rawValue().toDouble();
|
||
|
double posCtlThreshold = getParameterFact(-1, "RC_POSCTL_TH")->rawValue().toDouble();
|
||
|
double loiterThreshold = getParameterFact(-1, "RC_LOITER_TH")->rawValue().toDouble();
|
||
|
double returnThreshold = getParameterFact(-1, "RC_RETURN_TH")->rawValue().toDouble();
|
||
|
double offboardThreshold = getParameterFact(-1, "RC_OFFB_TH")->rawValue().toDouble();
|
||
10 years ago
|
|
||
|
if (modeSwitchChannel >= 0) {
|
||
|
if (offboardSwitchChannel >= 0 && _rcValues[offboardSwitchChannel] >= offboardThreshold) {
|
||
|
_offboardModeSelected = true;
|
||
|
} else if (returnSwitchChannel >= 0 && _rcValues[returnSwitchChannel] >= returnThreshold) {
|
||
|
_returnModeSelected = true;
|
||
|
} else {
|
||
|
if (_rcValues[modeSwitchChannel] >= autoThreshold) {
|
||
|
_autoModeSelected = true;
|
||
|
if (loiterSwitchChannel >= 0 && _rcValues[loiterSwitchChannel] >= loiterThreshold) {
|
||
|
_loiterModeSelected = true;
|
||
|
} else {
|
||
|
_missionModeSelected = true;
|
||
|
}
|
||
|
} else if (_rcValues[modeSwitchChannel] >= assistThreshold) {
|
||
|
_assistModeSelected = true;
|
||
|
if (posCtlSwitchChannel >= 0 && _rcValues[posCtlSwitchChannel] >= posCtlThreshold) {
|
||
|
_posCtlModeSelected = true;
|
||
|
} else {
|
||
|
_altCtlModeSelected = true;
|
||
|
}
|
||
|
} else if (acroSwitchChannel >= 0 && _rcValues[acroSwitchChannel] >= acroThreshold) {
|
||
|
_acroModeSelected = true;
|
||
|
} else {
|
||
|
_manualModeSelected = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
emit modesSelectedChanged();
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::_recalcModeRows(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
int modeSwitchChannel = getParameterFact(-1, "RC_MAP_MODE_SW")->rawValue().toInt();
|
||
|
int acroSwitchChannel = getParameterFact(-1, "RC_MAP_ACRO_SW")->rawValue().toInt();
|
||
|
int posCtlSwitchChannel = getParameterFact(-1, "RC_MAP_POSCTL_SW")->rawValue().toInt();
|
||
|
int loiterSwitchChannel = getParameterFact(-1, "RC_MAP_LOITER_SW")->rawValue().toInt();
|
||
|
int returnSwitchChannel = getParameterFact(-1, "RC_MAP_RETURN_SW")->rawValue().toInt();
|
||
|
int offboardSwitchChannel = getParameterFact(-1, "RC_MAP_OFFB_SW")->rawValue().toInt();
|
||
10 years ago
|
|
||
|
if (modeSwitchChannel == 0) {
|
||
|
_acroModeRow = 0;
|
||
|
_assistModeRow = 1;
|
||
|
_autoModeRow = 2;
|
||
|
_altCtlModeRow = 3;
|
||
|
_posCtlModeRow = 4;
|
||
|
_loiterModeRow = 5;
|
||
|
_missionModeRow = 6;
|
||
|
_returnModeRow = 7;
|
||
|
_offboardModeRow = 8;
|
||
|
} else {
|
||
|
int row = 0;
|
||
|
|
||
|
// First set is all switches on main mode channel
|
||
|
|
||
|
if (acroSwitchChannel == modeSwitchChannel) {
|
||
|
_acroModeRow = row++;
|
||
|
}
|
||
|
_assistModeRow = row++;
|
||
|
if (posCtlSwitchChannel == modeSwitchChannel) {
|
||
|
_altCtlModeRow = row++;
|
||
|
_posCtlModeRow = row++;
|
||
|
} else if (posCtlSwitchChannel == 0) {
|
||
|
_altCtlModeRow = row++;
|
||
|
}
|
||
|
_autoModeRow = row++;
|
||
|
if (loiterSwitchChannel == modeSwitchChannel) {
|
||
|
_missionModeRow = row++;
|
||
|
_loiterModeRow = row++;
|
||
|
} else if (loiterSwitchChannel == 0) {
|
||
|
_missionModeRow = row++;
|
||
|
}
|
||
|
if (returnSwitchChannel == modeSwitchChannel) {
|
||
|
_returnModeRow = row++;
|
||
|
}
|
||
|
if (offboardSwitchChannel == modeSwitchChannel) {
|
||
|
_offboardModeRow = row++;
|
||
|
}
|
||
|
|
||
|
// Now individual enabled switches not on main mode channel
|
||
|
|
||
|
if (acroSwitchChannel != 0 && acroSwitchChannel != modeSwitchChannel) {
|
||
|
_acroModeRow = row++;
|
||
|
}
|
||
|
if (posCtlSwitchChannel != 0 && posCtlSwitchChannel != modeSwitchChannel) {
|
||
|
_altCtlModeRow = row++;
|
||
|
_posCtlModeRow = row++;
|
||
|
}
|
||
|
if (loiterSwitchChannel != 0 && loiterSwitchChannel != modeSwitchChannel) {
|
||
|
_missionModeRow = row++;
|
||
|
_loiterModeRow = row++;
|
||
|
}
|
||
|
if (returnSwitchChannel != 0 && returnSwitchChannel != modeSwitchChannel) {
|
||
|
_returnModeRow = row++;
|
||
|
}
|
||
|
if (offboardSwitchChannel != 0 && offboardSwitchChannel != modeSwitchChannel) {
|
||
|
_offboardModeRow = row++;
|
||
|
}
|
||
|
|
||
|
// Now disabled switches
|
||
|
|
||
|
if (acroSwitchChannel == 0) {
|
||
|
_acroModeRow = row++;
|
||
|
}
|
||
|
if (posCtlSwitchChannel == 0) {
|
||
|
_posCtlModeRow = row++;
|
||
|
}
|
||
|
if (loiterSwitchChannel == 0) {
|
||
|
_loiterModeRow = row++;
|
||
|
}
|
||
|
if (returnSwitchChannel == 0) {
|
||
|
_returnModeRow = row++;
|
||
|
}
|
||
|
if (offboardSwitchChannel == 0) {
|
||
|
_offboardModeRow = row++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
emit modeRowsChanged();
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::manualModeThreshold(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
return 0.0;
|
||
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::assistModeThreshold(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
return getParameterFact(-1, "RC_ASSIST_TH")->rawValue().toDouble();
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::autoModeThreshold(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
return getParameterFact(-1, "RC_AUTO_TH")->rawValue().toDouble();
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::acroModeThreshold(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
return getParameterFact(-1, "RC_ACRO_TH")->rawValue().toDouble();
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::altCtlModeThreshold(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
return _assistModeVisible ? 0.0 : getParameterFact(-1, "RC_ASSIST_TH")->rawValue().toDouble();
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::posCtlModeThreshold(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
return getParameterFact(-1, "RC_POSCTL_TH")->rawValue().toDouble();
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::missionModeThreshold(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
return _autoModeVisible ? 0.0 : getParameterFact(-1, "RC_AUTO_TH")->rawValue().toDouble();
|
||
10 years ago
|
}
|
||
|
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::loiterModeThreshold(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
return getParameterFact(-1, "RC_LOITER_TH")->rawValue().toDouble();
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::returnModeThreshold(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
return getParameterFact(-1, "RC_RETURN_TH")->rawValue().toDouble();
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
double PX4AdvancedFlightModesController::offboardModeThreshold(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
return getParameterFact(-1, "RC_OFFB_TH")->rawValue().toDouble();
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setAssistModeThreshold(double threshold)
|
||
10 years ago
|
{
|
||
10 years ago
|
getParameterFact(-1, "RC_ASSIST_TH")->setRawValue(threshold);
|
||
10 years ago
|
_recalcModeSelections();
|
||
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setAutoModeThreshold(double threshold)
|
||
10 years ago
|
{
|
||
10 years ago
|
getParameterFact(-1, "RC_AUTO_TH")->setRawValue(threshold);
|
||
10 years ago
|
_recalcModeSelections();
|
||
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setAcroModeThreshold(double threshold)
|
||
10 years ago
|
{
|
||
10 years ago
|
getParameterFact(-1, "RC_ACRO_TH")->setRawValue(threshold);
|
||
10 years ago
|
_recalcModeSelections();
|
||
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setAltCtlModeThreshold(double threshold)
|
||
10 years ago
|
{
|
||
|
setAssistModeThreshold(threshold);
|
||
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setPosCtlModeThreshold(double threshold)
|
||
10 years ago
|
{
|
||
10 years ago
|
getParameterFact(-1, "RC_POSCTL_TH")->setRawValue(threshold);
|
||
10 years ago
|
_recalcModeSelections();
|
||
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setMissionModeThreshold(double threshold)
|
||
10 years ago
|
{
|
||
|
setAutoModeThreshold(threshold);
|
||
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setLoiterModeThreshold(double threshold)
|
||
10 years ago
|
{
|
||
10 years ago
|
getParameterFact(-1, "RC_LOITER_TH")->setRawValue(threshold);
|
||
10 years ago
|
_recalcModeSelections();
|
||
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setReturnModeThreshold(double threshold)
|
||
10 years ago
|
{
|
||
10 years ago
|
getParameterFact(-1, "RC_RETURN_TH")->setRawValue(threshold);
|
||
10 years ago
|
_recalcModeSelections();
|
||
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setOffboardModeThreshold(double threshold)
|
||
10 years ago
|
{
|
||
10 years ago
|
getParameterFact(-1, "RC_OFFB_TH")->setRawValue(threshold);
|
||
10 years ago
|
_recalcModeSelections();
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::_channelToChannelIndex(int channel)
|
||
10 years ago
|
{
|
||
|
return _channelListModelChannel.lastIndexOf(channel);
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::_channelToChannelIndex(const QString& channelParam)
|
||
10 years ago
|
{
|
||
10 years ago
|
return _channelToChannelIndex(getParameterFact(-1, channelParam)->rawValue().toInt());
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::manualModeChannelIndex(void)
|
||
10 years ago
|
{
|
||
|
return _channelToChannelIndex("RC_MAP_MODE_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::assistModeChannelIndex(void)
|
||
10 years ago
|
{
|
||
|
return _channelToChannelIndex("RC_MAP_MODE_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::autoModeChannelIndex(void)
|
||
10 years ago
|
{
|
||
|
return _channelToChannelIndex("RC_MAP_MODE_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::acroModeChannelIndex(void)
|
||
10 years ago
|
{
|
||
|
return _channelToChannelIndex("RC_MAP_ACRO_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::altCtlModeChannelIndex(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
int posCtlSwitchChannel = getParameterFact(-1, "RC_MAP_POSCTL_SW")->rawValue().toInt();
|
||
10 years ago
|
|
||
|
if (posCtlSwitchChannel == 0) {
|
||
|
return _channelToChannelIndex("RC_MAP_MODE_SW");
|
||
|
} else {
|
||
|
return _channelToChannelIndex(posCtlSwitchChannel);
|
||
|
}
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::posCtlModeChannelIndex(void)
|
||
10 years ago
|
{
|
||
|
return _channelToChannelIndex("RC_MAP_POSCTL_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::loiterModeChannelIndex(void)
|
||
10 years ago
|
{
|
||
|
return _channelToChannelIndex("RC_MAP_LOITER_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::missionModeChannelIndex(void)
|
||
10 years ago
|
{
|
||
10 years ago
|
int loiterSwitchChannel = getParameterFact(-1, "RC_MAP_LOITER_SW")->rawValue().toInt();
|
||
10 years ago
|
|
||
|
if (loiterSwitchChannel == 0) {
|
||
|
return _channelToChannelIndex("RC_MAP_MODE_SW");
|
||
|
} else {
|
||
|
return _channelToChannelIndex(loiterSwitchChannel);
|
||
|
}
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::returnModeChannelIndex(void)
|
||
10 years ago
|
{
|
||
|
return _channelToChannelIndex("RC_MAP_RETURN_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::offboardModeChannelIndex(void)
|
||
10 years ago
|
{
|
||
|
return _channelToChannelIndex("RC_MAP_OFFB_SW");
|
||
|
}
|
||
|
|
||
9 years ago
|
int PX4AdvancedFlightModesController::_channelIndexToChannel(int index)
|
||
10 years ago
|
{
|
||
|
return _channelListModelChannel[index];
|
||
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setManualModeChannelIndex(int index)
|
||
10 years ago
|
{
|
||
10 years ago
|
getParameterFact(-1, "RC_MAP_MODE_SW")->setRawValue(_channelIndexToChannel(index));
|
||
10 years ago
|
|
||
|
_recalcModeSelections();
|
||
|
_recalcModeRows();
|
||
10 years ago
|
emit channelIndicesChanged();
|
||
|
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setAcroModeChannelIndex(int index)
|
||
10 years ago
|
{
|
||
10 years ago
|
getParameterFact(-1, "RC_MAP_ACRO_SW")->setRawValue(_channelIndexToChannel(index));
|
||
10 years ago
|
|
||
|
_recalcModeSelections();
|
||
|
_recalcModeRows();
|
||
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setPosCtlModeChannelIndex(int index)
|
||
10 years ago
|
{
|
||
|
int channel = _channelIndexToChannel(index);
|
||
|
|
||
10 years ago
|
getParameterFact(-1, "RC_MAP_POSCTL_SW")->setRawValue(channel);
|
||
10 years ago
|
|
||
|
if (channel == 0) {
|
||
|
// PosCtl disabled so AltCtl must move back to main Mode switch
|
||
|
_assistModeVisible = false;
|
||
|
} else {
|
||
|
// Assist mode is visible if AltCtl/PosCtl are on seperate channel from main Mode switch
|
||
10 years ago
|
_assistModeVisible = channel != getParameterFact(-1, "RC_MAP_MODE_SW")->rawValue().toInt();
|
||
10 years ago
|
}
|
||
|
|
||
|
emit modesVisibleChanged();
|
||
|
|
||
|
_recalcModeSelections();
|
||
|
_recalcModeRows();
|
||
10 years ago
|
emit channelIndicesChanged();
|
||
|
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setLoiterModeChannelIndex(int index)
|
||
10 years ago
|
{
|
||
|
int channel = _channelIndexToChannel(index);
|
||
|
|
||
10 years ago
|
getParameterFact(-1, "RC_MAP_LOITER_SW")->setRawValue(channel);
|
||
10 years ago
|
|
||
|
if (channel == 0) {
|
||
|
// Loiter disabled so Mission must move back to main Mode switch
|
||
|
_autoModeVisible = false;
|
||
|
} else {
|
||
|
// Auto mode is visible if Mission/Loiter are on seperate channel from main Mode switch
|
||
10 years ago
|
_autoModeVisible = channel != getParameterFact(-1, "RC_MAP_MODE_SW")->rawValue().toInt();
|
||
10 years ago
|
}
|
||
|
|
||
|
emit modesVisibleChanged();
|
||
|
|
||
|
_recalcModeSelections();
|
||
|
_recalcModeRows();
|
||
10 years ago
|
emit channelIndicesChanged();
|
||
|
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setReturnModeChannelIndex(int index)
|
||
10 years ago
|
{
|
||
10 years ago
|
getParameterFact(-1, "RC_MAP_RETURN_SW")->setRawValue(_channelIndexToChannel(index));
|
||
10 years ago
|
_recalcModeSelections();
|
||
|
_recalcModeRows();
|
||
10 years ago
|
emit channelIndicesChanged();
|
||
|
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::setOffboardModeChannelIndex(int index)
|
||
10 years ago
|
{
|
||
10 years ago
|
getParameterFact(-1, "RC_MAP_OFFB_SW")->setRawValue(_channelIndexToChannel(index));
|
||
10 years ago
|
_recalcModeSelections();
|
||
|
_recalcModeRows();
|
||
10 years ago
|
emit channelIndicesChanged();
|
||
|
|
||
10 years ago
|
}
|
||
|
|
||
9 years ago
|
void PX4AdvancedFlightModesController::generateThresholds(void)
|
||
10 years ago
|
{
|
||
|
// Reset all thresholds to 0.0
|
||
|
|
||
|
QStringList thresholdParams;
|
||
|
|
||
|
thresholdParams << "RC_ASSIST_TH" << "RC_AUTO_TH" << "RC_ACRO_TH" << "RC_POSCTL_TH" << "RC_LOITER_TH" << "RC_RETURN_TH" << "RC_OFFB_TH";
|
||
|
|
||
10 years ago
|
foreach(const QString &thresholdParam, thresholdParams) {
|
||
10 years ago
|
getParameterFact(-1, thresholdParam)->setRawValue(0.0f);
|
||
10 years ago
|
}
|
||
|
|
||
|
// Redistribute
|
||
|
|
||
10 years ago
|
int modeChannel = getParameterFact(-1, "RC_MAP_MODE_SW")->rawValue().toInt();
|
||
|
int acroChannel = getParameterFact(-1, "RC_MAP_ACRO_SW")->rawValue().toInt();
|
||
|
int posCtlChannel = getParameterFact(-1, "RC_MAP_POSCTL_SW")->rawValue().toInt();
|
||
|
int loiterChannel = getParameterFact(-1, "RC_MAP_LOITER_SW")->rawValue().toInt();
|
||
|
int returnChannel = getParameterFact(-1, "RC_MAP_RETURN_SW")->rawValue().toInt();
|
||
|
int offboardChannel = getParameterFact(-1, "RC_MAP_OFFB_SW")->rawValue().toInt();
|
||
10 years ago
|
|
||
|
if (modeChannel != 0) {
|
||
|
int positions = 3; // Manual/Assist/Auto always exist
|
||
|
|
||
|
bool acroOnModeSwitch = modeChannel == acroChannel;
|
||
|
bool posCtlOnModeSwitch = modeChannel == posCtlChannel;
|
||
|
bool loiterOnModeSwitch = modeChannel == loiterChannel;
|
||
|
bool returnOnModeSwitch = modeChannel == returnChannel;
|
||
|
bool offboardOnModeSwitch = modeChannel == offboardChannel;
|
||
|
|
||
|
positions += acroOnModeSwitch ? 1 : 0;
|
||
|
positions += posCtlOnModeSwitch ? 1 : 0;
|
||
|
positions += loiterOnModeSwitch ? 1 : 0;
|
||
|
positions += returnOnModeSwitch ? 1 : 0;
|
||
|
positions += offboardOnModeSwitch ? 1 : 0;
|
||
|
|
||
|
float increment = 1.0f / positions;
|
||
|
float currentThreshold = 0.0f;
|
||
|
|
||
|
if (acroOnModeSwitch) {
|
||
|
currentThreshold += increment;
|
||
10 years ago
|
getParameterFact(-1, "RC_ACRO_TH")->setRawValue(currentThreshold);
|
||
10 years ago
|
acroChannel = 0;
|
||
|
}
|
||
|
|
||
|
currentThreshold += increment;
|
||
10 years ago
|
getParameterFact(-1, "RC_ASSIST_TH")->setRawValue(currentThreshold);
|
||
10 years ago
|
if (posCtlOnModeSwitch) {
|
||
|
currentThreshold += increment;
|
||
10 years ago
|
getParameterFact(-1, "RC_POSCTL_TH")->setRawValue(currentThreshold);
|
||
10 years ago
|
posCtlChannel = 0;
|
||
|
}
|
||
|
|
||
|
currentThreshold += increment;
|
||
10 years ago
|
getParameterFact(-1, "RC_AUTO_TH")->setRawValue(currentThreshold);
|
||
10 years ago
|
if (loiterOnModeSwitch) {
|
||
|
currentThreshold += increment;
|
||
10 years ago
|
getParameterFact(-1, "RC_LOITER_TH")->setRawValue(currentThreshold);
|
||
10 years ago
|
loiterChannel = 0;
|
||
|
}
|
||
|
|
||
|
if (returnOnModeSwitch) {
|
||
|
currentThreshold += increment;
|
||
10 years ago
|
getParameterFact(-1, "RC_RETURN_TH")->setRawValue(currentThreshold);
|
||
10 years ago
|
returnChannel = 0;
|
||
|
}
|
||
|
|
||
|
if (offboardOnModeSwitch) {
|
||
|
currentThreshold += increment;
|
||
10 years ago
|
getParameterFact(-1, "RC_OFFB_TH")->setRawValue(currentThreshold);
|
||
10 years ago
|
offboardChannel = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (acroChannel != 0) {
|
||
|
// If only two positions don't set threshold at midrange. Setting to 0.25
|
||
|
// allows for this channel to work with either a two or three position switch
|
||
10 years ago
|
getParameterFact(-1, "RC_ACRO_TH")->setRawValue(0.25f);
|
||
10 years ago
|
}
|
||
|
|
||
|
if (posCtlChannel != 0) {
|
||
10 years ago
|
getParameterFact(-1, "RC_POSCTL_TH")->setRawValue(0.25f);
|
||
10 years ago
|
}
|
||
|
|
||
|
if (loiterChannel != 0) {
|
||
10 years ago
|
getParameterFact(-1, "RC_LOITER_TH")->setRawValue(0.25f);
|
||
10 years ago
|
}
|
||
|
|
||
|
if (returnChannel != 0) {
|
||
10 years ago
|
getParameterFact(-1, "RC_RETURN_TH")->setRawValue(0.25f);
|
||
10 years ago
|
}
|
||
|
|
||
|
if (offboardChannel != 0) {
|
||
10 years ago
|
getParameterFact(-1, "RC_OFFB_TH")->setRawValue(0.25f);
|
||
10 years ago
|
}
|
||
|
|
||
|
emit thresholdsChanged();
|
||
10 years ago
|
}
|