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

OP-138 Hexacopter support in the config gadget. NOT TESTED on a real frame, do it at your own risk... and report, please!

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1939 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
edouard 2010-10-10 13:45:10 +00:00 committed by edouard
parent 64fb124856
commit 4ec3f3fe4c
3 changed files with 131 additions and 25 deletions

View File

@ -32,6 +32,7 @@
#include <QtGui/QTextEdit>
#include <QtGui/QVBoxLayout>
#include <QtGui/QPushButton>
#include <math.h>
@ -388,28 +389,49 @@ void ConfigAirframeWidget::requestAircraftUpdate()
i = field->getElementNames().indexOf("Roll");
val = field->getDouble(i)/1.27;
m_aircraft->mrRollMixLevel->setValue(val);
}
} else if (frameType == "Hexa") {
// Motors 1/2/3 4/5/6 are: NW / N / NE and SE / S / SW
field = obj->getField(QString("VTOLMotorNW"));
Q_ASSERT(field);
m_aircraft->multiMotor1->setCurrentIndex(m_aircraft->multiMotor1->findText(field->getValue().toString()));
// Motors 1/2/3 4/5/6 are: N / NE / SE / S / SW / NW
field = obj->getField(QString("VTOLMotorN"));
Q_ASSERT(field);
m_aircraft->multiMotor2->setCurrentIndex(m_aircraft->multiMotor2->findText(field->getValue().toString()));
m_aircraft->multiMotor1->setCurrentIndex(m_aircraft->multiMotor1->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorNE"));
Q_ASSERT(field);
m_aircraft->multiMotor3->setCurrentIndex(m_aircraft->multiMotor3->findText(field->getValue().toString()));
m_aircraft->multiMotor2->setCurrentIndex(m_aircraft->multiMotor2->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorSE"));
Q_ASSERT(field);
m_aircraft->multiMotor4->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString()));
m_aircraft->multiMotor3->setCurrentIndex(m_aircraft->multiMotor3->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorS"));
Q_ASSERT(field);
m_aircraft->multiMotor5->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString()));
m_aircraft->multiMotor4->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorSW"));
Q_ASSERT(field);
m_aircraft->multiMotor5->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString()));
field = obj->getField(QString("VTOLMotorNW"));
Q_ASSERT(field);
m_aircraft->multiMotor6->setCurrentIndex(m_aircraft->multiMotor4->findText(field->getValue().toString()));
// Now, read the 1st mixer R/P/Y levels and initialize the mix sliders.
// This assumes that all vectors are identical - if not, the user should use the
// "custom" setting.
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
int eng= m_aircraft->multiMotor1->currentIndex()-1;
// eng will be -1 if value is set to "None"
if (eng > -1) {
field = obj->getField(mixerVectors.at(eng));
int i = field->getElementNames().indexOf("Pitch");
double val = floor(field->getDouble(i)/1.27);
m_aircraft->mrPitchMixLevel->setValue(val);
i = field->getElementNames().indexOf("Yaw");
val = floor(-field->getDouble(i)/1.27);
m_aircraft->mrYawMixLevel->setValue(val);
eng = m_aircraft->multiMotor2->currentIndex()-1;
field = obj->getField(mixerVectors.at(eng));
i = field->getElementNames().indexOf("Roll");
val = floor(1-field->getDouble(i)/1.27);
m_aircraft->mrRollMixLevel->setValue(val);
}
} else if (frameType == "Octo") {
// Motors 1 to 8 are N / NE / E / etc
field = obj->getField(QString("VTOLMotorN"));
@ -554,6 +576,9 @@ void ConfigAirframeWidget::setupAirframeUI(QString frameType)
m_aircraft->multiMotor6->setEnabled(true);
m_aircraft->multiMotor7->setEnabled(false);
m_aircraft->multiMotor8->setEnabled(false);
m_aircraft->mrRollMixLevel->setValue(50);
m_aircraft->mrPitchMixLevel->setValue(33);
m_aircraft->mrYawMixLevel->setValue(33);
} else if (frameType == "Octo" || frameType == "Octocopter") {
m_aircraft->aircraftType->setCurrentIndex(m_aircraft->aircraftType->findText("Multirotor"));
m_aircraft->multirotorFrameType->setCurrentIndex(m_aircraft->multirotorFrameType->findText("Octocopter"));
@ -1047,6 +1072,92 @@ bool ConfigAirframeWidget::setupQuad(bool pLayout)
}
/**
Set up a Quad-X or Quad-P
*/
bool ConfigAirframeWidget::setupHexa()
{
// Check coherence:
// - Four engines have to be defined
if (m_aircraft->multiMotor1->currentText() == "None" ||
m_aircraft->multiMotor2->currentText() == "None" ||
m_aircraft->multiMotor3->currentText() == "None" ||
m_aircraft->multiMotor4->currentText() == "None" ||
m_aircraft->multiMotor5->currentText() == "None" ||
m_aircraft->multiMotor6->currentText() == "None") {
m_aircraft->mrStatusLabel->setText("ERROR: Assign 6 motor channels");
return false;
}
resetActuators();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
UAVObjectField *field;
// Save the actuator channels for motor 1 to 6 (N/NE/SE/S/SW/NW)
field = obj->getField("VTOLMotorN");
Q_ASSERT(field);
field->setValue(m_aircraft->multiMotor1->currentText());
field = obj->getField("VTOLMotorNE");
Q_ASSERT(field);
field->setValue(m_aircraft->multiMotor2->currentText());
field = obj->getField("VTOLMotorSE");
Q_ASSERT(field);
field->setValue(m_aircraft->multiMotor3->currentText());
field = obj->getField("VTOLMotorS");
Q_ASSERT(field);
field->setValue(m_aircraft->multiMotor4->currentText());
field = obj->getField("VTOLMotorSW");
Q_ASSERT(field);
field->setValue(m_aircraft->multiMotor5->currentText());
field = obj->getField("VTOLMotorNW");
Q_ASSERT(field);
field->setValue(m_aircraft->multiMotor6->currentText());
obj->updated(); // Save...
// Now, setup the mixer:
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
// 1. Assign the servo/motor/none for each channel
// Disable all
foreach(QString mixer, mixerTypes) {
field = obj->getField(mixer);
Q_ASSERT(field);
field->setValue("Disabled");
}
// and set only the relevant channels:
// Motor 1 to 6, P Layout:
// pitch roll yaw
// 1 { 0.3 , 0 ,-0.3 // N CW
// 2 { 0.3 ,-0.5 , 0.3 // NE CCW
// 3 {-0.3 ,-0.5 ,-0.3 // SE CW
// 4 {-0.3 , 0 , 0.3 // S CCW
// 5 {-0.3 , 0.5 ,-0.3 // SW CW
// 6 { 0.3 , 0.5 , 0.3 // NW CCW
//
double pFactor = (double)m_aircraft->mrPitchMixLevel->value()/100;
double rFactor = (double)m_aircraft->mrRollMixLevel->value()/100;
double yFactor = (double)m_aircraft->mrYawMixLevel->value()/100;
int channel = m_aircraft->multiMotor1->currentIndex()-1;
setupQuadMotor(channel, pFactor, 0, -yFactor);
channel = m_aircraft->multiMotor2->currentIndex()-1;
setupQuadMotor(channel, pFactor, -rFactor, yFactor);
channel = m_aircraft->multiMotor3->currentIndex()-1;
setupQuadMotor(channel, -pFactor, -rFactor, -yFactor);
channel = m_aircraft->multiMotor4->currentIndex()-1;
setupQuadMotor(channel, -pFactor, 0, yFactor);
channel = m_aircraft->multiMotor5->currentIndex()-1;
setupQuadMotor(channel, -pFactor, rFactor, -yFactor);
channel = m_aircraft->multiMotor6->currentIndex()-1;
setupQuadMotor(channel, pFactor, rFactor, yFactor);
obj->updated();
m_aircraft->mrStatusLabel->setText("SUCCESS: Mixer Saved OK");
return true;
}
/**
Sends the config to the board (airframe type)
@ -1109,6 +1220,7 @@ void ConfigAirframeWidget::sendAircraftUpdate()
setupQuad(false);
} else if (m_aircraft->multirotorFrameType->currentText() == "Hexacopter") {
airframeType = "Hexa";
setupHexa();
} else if (m_aircraft->multirotorFrameType->currentText() == "Octocopter") {
airframeType = "Octo";
}

View File

@ -51,6 +51,8 @@ private:
bool setupFrameElevon();
bool setupFrameVtail();
bool setupQuad(bool pLayout);
bool setupHexa();
bool setupOcto();
void resetField(UAVObjectField * field);
void resetMixer (MixerCurveWidget *mixer, int numElements);

View File

@ -32,11 +32,11 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.9899495"
inkscape:cx="338.04953"
inkscape:cy="818.03268"
inkscape:zoom="1.979899"
inkscape:cx="202.64449"
inkscape:cy="675.80836"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:current-layer="g3037"
showgrid="false"
showguides="true"
inkscape:guide-bbox="true"
@ -967,7 +967,7 @@
sodipodi:open="true" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 138.92857,74.147895 -2.85714,-5.714285 -5.35714,3.928571"
d="m 174.4438,80.147895 -2.85714,-5.714285 -5.35714,3.928571"
id="path2975" />
</g>
</g>
@ -1018,7 +1018,7 @@
sodipodi:open="true" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 138.92857,74.147895 -2.85714,-5.714285 -5.35714,3.928571"
d="m 174.19126,80.147895 -2.85714,-5.714285 -5.35714,3.928571"
id="path3021" />
</g>
</g>
@ -1105,17 +1105,9 @@
sodipodi:rx="23.738585"
sodipodi:ry="23.738585"
d="m 176.7767,75.039597 c 0,13.110458 -10.62813,23.738584 -23.73858,23.738584 -13.11046,0 -23.73859,-10.628126 -23.73859,-23.738584 0,-3.124577 0.61685,-6.218415 1.81517,-9.104071" />
<path
id="path3047"
d="m 357.07143,134.50504 4.28571,-3.92857 2.85715,5.35714"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 357.07143,134.50504 4.28571,-3.92857 2.85715,5.35714"
id="path3049" />
<path
id="path3051"
d="m 357.07143,134.50504 4.28571,-3.92857 2.85715,5.35714"
d="m 322.42857,125.21933 4.28571,-3.92857 2.85715,5.35714"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
<g
@ -1157,7 +1149,7 @@
sodipodi:open="true" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 487.07143,134.50504 4.28571,-3.92857 2.85715,5.35714"
d="m 487.57651,132.48473 4.28571,-3.92857 2.85715,5.35714"
id="path3063" />
</g>
</g>

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB