1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-30 15:52:12 +01:00

OP-1643 First commit : Add ground vehicle to setup wizard

This commit is contained in:
Laurent Lalanne 2014-12-07 04:26:09 +01:00 committed by Fredrik Larsson
parent 4f7fc1bac7
commit c213e923ca
16 changed files with 12918 additions and 33 deletions

View File

@ -240,7 +240,7 @@ void ConfigCustomWidget::refreshWidgetsValues(QString frameType)
if (MixerSettings * mxr = qobject_cast<MixerSettings *>(mixer)) {
MixerSettings::DataFields mixerSettingsData = mxr->getData();
if (mixerSettingsData.Curve2Source == MixerSettings::CURVE2SOURCE_THROTTLE && Throttle2CurveMin >= 0 ) {
if (mixerSettingsData.Curve2Source == MixerSettings::CURVE2SOURCE_THROTTLE && Throttle2CurveMin >= 0) {
m_aircraft->customThrottle2Curve->setMixerType(MixerCurve::MIXERCURVE_THROTTLE);
} else {
m_aircraft->customThrottle2Curve->setMixerType(MixerCurve::MIXERCURVE_PITCH);

View File

@ -32,6 +32,7 @@
const QString OutputCalibrationPage::MULTI_SVG_FILE = QString(":/setupwizard/resources/multirotor-shapes.svg");
const QString OutputCalibrationPage::FIXEDWING_SVG_FILE = QString(":/setupwizard/resources/fixedwing-shapes-wizard.svg");
const QString OutputCalibrationPage::GROUND_SVG_FILE = QString(":/setupwizard/resources/ground-shapes-wizard.svg");
OutputCalibrationPage::OutputCalibrationPage(SetupWizard *wizard, QWidget *parent) :
AbstractWizardPage(wizard, parent), ui(new Ui::OutputCalibrationPage), m_vehicleBoundsItem(0),
@ -216,6 +217,42 @@ void OutputCalibrationPage::setupVehicle()
getWizard()->setActuatorSettings(m_actuatorSettings);
break;
// Ground vehicles
case SetupWizard::GROUNDVEHICLE_CAR:
loadSVGFile(GROUND_SVG_FILE);
m_wizardIndexes << 0 << 1 << 2;
m_vehicleElementIds << "car" << "car-frame" << "car-motor" << "car-steering";
m_vehicleHighlightElementIndexes << 0 << 1 << 2;
m_channelIndex << 0 << 1 << 0;
setupActuatorMinMaxAndNeutral(0, 1, 2);
getWizard()->setActuatorSettings(m_actuatorSettings);
break;
case SetupWizard::GROUNDVEHICLE_DIFFERENTIAL:
loadSVGFile(GROUND_SVG_FILE);
m_wizardIndexes << 0 << 1 << 1;
m_vehicleElementIds << "tank" << "tank-frame" << "tank-left-motor" << "tank-right-motor";
m_vehicleHighlightElementIndexes << 0 << 1 << 2;
m_channelIndex << 0 << 1 << 0;
setupActuatorMinMaxAndNeutral(0, 1, 2);
getWizard()->setActuatorSettings(m_actuatorSettings);
break;
case SetupWizard::GROUNDVEHICLE_MOTORCYCLE:
loadSVGFile(GROUND_SVG_FILE);
m_wizardIndexes << 0 << 1 << 2;
m_vehicleElementIds << "motorbike" << "motorbike-frame" << "motorbike-motor" << "motorbike-steering";
m_vehicleHighlightElementIndexes << 0 << 1 << 2;
m_channelIndex << 0 << 1 << 0;
setupActuatorMinMaxAndNeutral(0, 1, 2);
getWizard()->setActuatorSettings(m_actuatorSettings);
break;
default:
break;
}

View File

@ -103,6 +103,7 @@ private:
static const QString MULTI_SVG_FILE;
static const QString FIXEDWING_SVG_FILE;
static const QString GROUND_SVG_FILE;
};
#endif // OUTPUTCALIBRATIONPAGE_H

View File

@ -1,11 +1,11 @@
/**
******************************************************************************
*
* @file multipage.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @file selectionpage.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
* @addtogroup
* @{
* @addtogroup MultiPage
* @addtogroup SelectionPage
* @{
* @brief
*****************************************************************************/

View File

@ -2,7 +2,7 @@
******************************************************************************
*
* @file surfacepage.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
* @addtogroup
* @{
* @addtogroup SurfacePage
@ -26,17 +26,47 @@
*/
#include "surfacepage.h"
#include "ui_surfacepage.h"
#include "setupwizard.h"
SurfacePage::SurfacePage(SetupWizard *wizard, QWidget *parent) :
AbstractWizardPage(wizard, parent),
ui(new Ui::SurfacePage)
{
ui->setupUi(this);
setFinalPage(true);
}
SelectionPage(wizard, QString(":/setupwizard/resources/ground-shapes-wizard-no-numbers.svg"), parent)
{}
SurfacePage::~SurfacePage()
{}
void SurfacePage::initializePage(VehicleConfigurationSource *settings)
{
delete ui;
Q_UNUSED(settings);
}
bool SurfacePage::validatePage(SelectionItem *selectedItem)
{
getWizard()->setVehicleSubType((SetupWizard::VEHICLE_SUB_TYPE)selectedItem->id());
return true;
}
void SurfacePage::setupSelection(Selection *selection)
{
selection->setTitle(tr("OpenPilot Ground Vehicle Configuration"));
selection->setText(tr("This part of the wizard will set up the OpenPilot controller for use with a ground "
"vehicle utilizing servos. The wizard supports the most common types of ground vehicle, "
"other variants can be configured by using customconfiguration options in the "
"Configuration plugin in the GCS.\n\n"
"Please select the type of ground vehicle you want to create a configuration for below:"));
selection->addItem(tr("Car"),
tr("This setup expects a traditional car a rear motor and a front streering servo"),
"car",
SetupWizard::GROUNDVEHICLE_CAR);
selection->addItem(tr("Tank"),
tr("This setup expects a traditional vehicle using only two motors and differential steering"),
"tank",
SetupWizard::GROUNDVEHICLE_DIFFERENTIAL);
selection->addItem(tr("Motorcycle"),
tr("This setup currently expects a motorcyle setup, using one motor and one servo for steering."),
"motorbike",
SetupWizard::GROUNDVEHICLE_MOTORCYCLE);
}

View File

@ -2,7 +2,7 @@
******************************************************************************
*
* @file surfacepage.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
* @addtogroup
* @{
* @addtogroup SurfacePage
@ -28,21 +28,19 @@
#ifndef SURFACEPAGE_H
#define SURFACEPAGE_H
#include "abstractwizardpage.h"
#include "selectionpage.h"
namespace Ui {
class SurfacePage;
}
class SurfacePage : public AbstractWizardPage {
class SurfacePage : public SelectionPage {
Q_OBJECT
public:
explicit SurfacePage(SetupWizard *wizard, QWidget *parent = 0);
~SurfacePage();
private:
Ui::SurfacePage *ui;
protected:
void initializePage(VehicleConfigurationSource *settings);
bool validatePage(SelectionItem *selectedItem);
void setupSelection(Selection *selection);
};
#endif // SURFACEPAGE_H

View File

@ -51,6 +51,7 @@ bool VehiclePage::validatePage()
getWizard()->setVehicleType(SetupWizard::VEHICLE_HELI);
} else if (ui->surfaceButton->isChecked()) {
getWizard()->setVehicleType(SetupWizard::VEHICLE_SURFACE);
getWizard()->setEscType(SetupWizard::ESC_STANDARD);
} else {
getWizard()->setVehicleType(SetupWizard::VEHICLE_UNKNOWN);
}

View File

@ -190,7 +190,7 @@ p, li { white-space: pre-wrap; }
<item>
<widget class="QToolButton" name="surfaceButton">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="font">
<font>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 216 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 431 KiB

View File

@ -131,7 +131,12 @@ int SetupWizard::nextId() const
return PAGE_ESC;
case PAGE_FIXEDWING:
case PAGE_SURFACE:
if (getVehicleSubType() == GROUNDVEHICLE_DIFFERENTIAL) {
return PAGE_ESC;
} else {
return PAGE_SERVO;
}
case PAGE_INPUT:
if (isRestartNeeded()) {
@ -333,6 +338,24 @@ QString SetupWizard::getSummaryText()
break;
case VEHICLE_SURFACE:
summary.append(tr("Surface vehicle"));
summary.append("<br>");
summary.append("<b>").append(tr("Vehicle sub type: ")).append("</b>");
switch (getVehicleSubType()) {
case SetupWizard::GROUNDVEHICLE_CAR:
summary.append(tr("Car"));
break;
case SetupWizard::GROUNDVEHICLE_DIFFERENTIAL:
summary.append(tr("Tank"));
break;
case SetupWizard::GROUNDVEHICLE_MOTORCYCLE:
summary.append(tr("Motorcycle"));
break;
default:
summary.append(tr("Unknown"));
break;
}
break;
default:
summary.append(tr("Unknown"));
@ -371,7 +394,8 @@ QString SetupWizard::getSummaryText()
}
// If Tricopter show tail servo speed
if (getVehicleSubType() == MULTI_ROTOR_TRI_Y || getVehicleType() == VEHICLE_FIXEDWING) {
if (getVehicleSubType() == MULTI_ROTOR_TRI_Y || getVehicleType() == VEHICLE_FIXEDWING
|| getVehicleSubType() == GROUNDVEHICLE_MOTORCYCLE || getVehicleSubType() == GROUNDVEHICLE_CAR) {
summary.append("<br>");
summary.append("<b>").append(tr("Servo type: ")).append("</b>");
switch (getServoType()) {

View File

@ -335,9 +335,25 @@ void VehicleConfigurationHelper::applyVehicleConfiguration()
case VehicleConfigurationSource::VEHICLE_HELI:
// TODO: Implement settings for Helis
break;
case VehicleConfigurationSource::VEHICLE_SURFACE:
// TODO: Implement settings for Surface
{
switch (m_configSource->getVehicleSubType()) {
case VehicleConfigurationSource::GROUNDVEHICLE_CAR:
setupCar();
break;
case VehicleConfigurationSource::GROUNDVEHICLE_DIFFERENTIAL:
setupTank();
break;
case VehicleConfigurationSource::GROUNDVEHICLE_MOTORCYCLE:
setupMotorcycle();
break;
default:
break;
}
break;
}
default:
break;
}
@ -475,8 +491,36 @@ void VehicleConfigurationHelper::applyActuatorConfiguration()
break;
case VehicleConfigurationSource::VEHICLE_SURFACE:
// TODO: Implement settings for ground vehicle types
{
ActuatorSettings::DataFields data = actSettings->getData();
QList<actuatorChannelSettings> actuatorSettings = m_configSource->getActuatorSettings();
for (quint16 i = 0; i < ActuatorSettings::CHANNELMAX_NUMELEM; i++) {
data.ChannelType[i] = ActuatorSettings::CHANNELTYPE_PWM;
data.ChannelAddr[i] = i;
data.ChannelMin[i] = actuatorSettings[i].channelMin;
data.ChannelNeutral[i] = actuatorSettings[i].channelNeutral;
data.ChannelMax[i] = actuatorSettings[i].channelMax;
}
for (quint16 i = 0; i < ActuatorSettings::CHANNELUPDATEFREQ_NUMELEM; i++) {
data.ChannelUpdateFreq[i] = servoFrequence;
if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_REVO) {
if (i == 1) {
data.ChannelUpdateFreq[i] = escFrequence;
}
} else if (m_configSource->getControllerType() == VehicleConfigurationSource::CONTROLLER_NANO) {
if (i == 2) {
data.ChannelUpdateFreq[i] = escFrequence;
}
}
}
actSettings->setData(data);
addModifiedObject(actSettings, tr("Writing actuator settings"));
break;
}
default:
break;
@ -635,6 +679,9 @@ void VehicleConfigurationHelper::applyMixerConfiguration(mixerChannelSettings ch
}
}
// Default maxThrottle
float maxThrottle = 0.9;
// Save mixer values for sliders
switch (m_configSource->getVehicleType()) {
case VehicleConfigurationSource::VEHICLE_MULTI:
@ -682,14 +729,45 @@ void VehicleConfigurationHelper::applyMixerConfiguration(mixerChannelSettings ch
mSettings->setMixerValueRoll(100);
mSettings->setMixerValuePitch(100);
mSettings->setMixerValueYaw(100);
maxThrottle = 1;
break;
case VehicleConfigurationSource::VEHICLE_HELI:
break;
case VehicleConfigurationSource::VEHICLE_SURFACE:
// TODO: Implement mixer / sliders settings for other vehicle types?
{
switch (m_configSource->getVehicleSubType()) {
case VehicleConfigurationSource::GROUNDVEHICLE_MOTORCYCLE:
case VehicleConfigurationSource::GROUNDVEHICLE_CAR:
mSettings->setMixerValueRoll(100);
mSettings->setMixerValuePitch(100);
mSettings->setMixerValueYaw(100);
maxThrottle = 1;
break;
case VehicleConfigurationSource::GROUNDVEHICLE_DIFFERENTIAL:
mSettings->setMixerValueRoll(100);
mSettings->setMixerValuePitch(100);
mSettings->setMixerValueYaw(100);
maxThrottle = 0.8;
break;
default:
break;
}
}
break;
default:
break;
}
// Apply Throttle curve max 90% for Multis, 100% for FixedWing/car/Motorbike, 80% for Tank
QString throttlePattern = "ThrottleCurve%1";
for (int i = 1; i <= 2; i++) {
UAVObjectField *field = mSettings->getField(throttlePattern.arg(i));
Q_ASSERT(field);
for (quint32 i = 0; i < field->getNumElements(); i++) {
field->setValue(i * (maxThrottle / (field->getNumElements() - 1)), i);
}
}
// Apply updates
mSettings->setData(mSettings->getData());
@ -891,7 +969,7 @@ void VehicleConfigurationHelper::resetVehicleConfig()
for (int i = 1; i <= 2; i++) {
UAVObjectField *field = mSettings->getField(throttlePattern.arg(i));
Q_ASSERT(field);
// Wizard support only Multirotors - Set default curve with 90% max
// Set default curve at 90% max for Multirotors
for (quint32 i = 0; i < field->getNumElements(); i++) {
field->setValue(i * (0.9f / (field->getNumElements() - 1)), i);
}
@ -1929,3 +2007,108 @@ void VehicleConfigurationHelper::setupVtail()
applyMixerConfiguration(channels);
applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_FIXEDWINGVTAIL, guiSettings);
}
/*
*
* Ground vehicles
*
*/
void VehicleConfigurationHelper::setupCar()
{
// Typical vehicle setup
// 1. Setup mixer data
// 2. Setup GUI data
// 3. Apply changes
mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
GUIConfigDataUnion guiSettings = getGUIConfigData();
// Steering Servo (Chan 1)
channels[0].type = MIXER_TYPE_SERVO;
channels[0].throttle1 = 0;
channels[0].throttle2 = 0;
channels[0].roll = 0;
channels[0].pitch = 0;
channels[0].yaw = 100;
// Motor (Chan 2)
channels[1].type = MIXER_TYPE_MOTOR;
channels[1].throttle1 = 0;
channels[1].throttle2 = 100;
channels[1].roll = 0;
channels[1].pitch = 0;
channels[1].yaw = 0;
guiSettings.ground.GroundVehicleSteering1 = 1;
guiSettings.ground.GroundVehicleThrottle2 = 2;
applyMixerConfiguration(channels);
applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_GROUNDVEHICLECAR, guiSettings);
}
void VehicleConfigurationHelper::setupTank()
{
// Typical vehicle setup
// 1. Setup mixer data
// 2. Setup GUI data
// 3. Apply changes
mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
GUIConfigDataUnion guiSettings = getGUIConfigData();
// Left Motor (Chan 1)
channels[0].type = MIXER_TYPE_SERVO;
channels[0].throttle1 = 0;
channels[0].throttle2 = 100;
channels[0].roll = 0;
channels[0].pitch = 0;
channels[0].yaw = 100;
// Right Motor (Chan 2)
channels[1].type = MIXER_TYPE_MOTOR;
channels[1].throttle1 = 0;
channels[1].throttle2 = 100;
channels[1].roll = 0;
channels[1].pitch = 0;
channels[1].yaw = -100;
guiSettings.ground.GroundVehicleThrottle1 = 1;
guiSettings.ground.GroundVehicleThrottle2 = 2;
applyMixerConfiguration(channels);
applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEDIFFERENTIAL, guiSettings);
}
void VehicleConfigurationHelper::setupMotorcycle()
{
// Typical vehicle setup
// 1. Setup mixer data
// 2. Setup GUI data
// 3. Apply changes
mixerChannelSettings channels[ActuatorSettings::CHANNELADDR_NUMELEM];
GUIConfigDataUnion guiSettings = getGUIConfigData();
// Steering Servo (Chan 1)
channels[0].type = MIXER_TYPE_SERVO;
channels[0].throttle1 = 0;
channels[0].throttle2 = 0;
channels[0].roll = 0;
channels[0].pitch = 0;
channels[0].yaw = 100;
// Motor (Chan 2)
channels[1].type = MIXER_TYPE_MOTOR;
channels[1].throttle1 = 0;
channels[1].throttle2 = 100;
channels[1].roll = 0;
channels[1].pitch = 0;
channels[1].yaw = 0;
guiSettings.ground.GroundVehicleSteering1 = 1;
guiSettings.ground.GroundVehicleThrottle2 = 2;
applyMixerConfiguration(channels);
applyMultiGUISettings(SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEMOTORCYCLE, guiSettings);
}

View File

@ -115,6 +115,10 @@ private:
void setupAileron();
void setupVtail();
void setupCar();
void setupTank();
void setupMotorcycle();
private slots:
void uAVOTransactionCompleted(UAVObject *object, bool success);
void uAVOTransactionCompleted(int oid, bool success);

View File

@ -61,7 +61,8 @@ public:
enum VEHICLE_SUB_TYPE { MULTI_ROTOR_UNKNOWN, MULTI_ROTOR_TRI_Y, MULTI_ROTOR_QUAD_X, MULTI_ROTOR_QUAD_PLUS, MULTI_ROTOR_QUAD_H,
MULTI_ROTOR_HEXA, MULTI_ROTOR_HEXA_H, MULTI_ROTOR_HEXA_X, MULTI_ROTOR_HEXA_COAX_Y, MULTI_ROTOR_OCTO,
MULTI_ROTOR_OCTO_X, MULTI_ROTOR_OCTO_V, MULTI_ROTOR_OCTO_COAX_X, MULTI_ROTOR_OCTO_COAX_PLUS,
FIXED_WING_DUAL_AILERON, FIXED_WING_AILERON, FIXED_WING_ELEVON, FIXED_WING_VTAIL, HELI_CCPM };
FIXED_WING_DUAL_AILERON, FIXED_WING_AILERON, FIXED_WING_ELEVON, FIXED_WING_VTAIL, HELI_CCPM,
GROUNDVEHICLE_MOTORCYCLE, GROUNDVEHICLE_CAR, GROUNDVEHICLE_DIFFERENTIAL };
enum ESC_TYPE { ESC_RAPID, ESC_STANDARD, ESC_UNKNOWN };
enum SERVO_TYPE { SERVO_ANALOG, SERVO_DIGITAL, SERVO_UNKNOWN };
enum INPUT_TYPE { INPUT_PWM, INPUT_PPM, INPUT_SBUS, INPUT_DSM, INPUT_UNKNOWN };

View File

@ -39,6 +39,8 @@
<file>resources/multirotor-shapes.svg</file>
<file>resources/fixedwing-shapes-wizard.svg</file>
<file>resources/fixedwing-shapes-wizard-no-numbers.svg</file>
<file>resources/ground-shapes-wizard.svg</file>
<file>resources/ground-shapes-wizard-no-numbers.svg</file>
<file>resources/sensor-shapes.svg</file>
<file>resources/bttn-illustration-color-up.png</file>
<file>resources/bttn-illustration-color-down.png</file>