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:
parent
64fb124856
commit
4ec3f3fe4c
@ -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";
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 |
Loading…
x
Reference in New Issue
Block a user