mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
Merge remote-tracking branch 'origin/MikeL_ConfigVehicle' into next
This commit is contained in:
commit
e309ff7f2d
@ -132,16 +132,11 @@ ConfigCcpmWidget::ConfigCcpmWidget(QWidget *parent) : VehicleConfig(parent)
|
||||
|
||||
}
|
||||
|
||||
m_ccpm->PitchCurve->setMin(-1);
|
||||
|
||||
resetMixer(m_ccpm->PitchCurve, 5);
|
||||
resetMixer(m_ccpm->ThrottleCurve, 5);
|
||||
|
||||
MixerSettings * mixerSettings = MixerSettings::GetInstance(getObjectManager());
|
||||
Q_ASSERT(mixerSettings);
|
||||
UAVObjectField * curve2source = mixerSettings->getField("Curve2Source");
|
||||
Q_ASSERT(curve2source);
|
||||
//initialize our two mixer curves
|
||||
m_ccpm->PitchCurve->initLinearCurve(5, 1.0, -1.0);
|
||||
m_ccpm->ThrottleCurve->initLinearCurve(5, 1.0);
|
||||
|
||||
//initialize channel names
|
||||
m_ccpm->ccpmEngineChannel->addItems(channelNames);
|
||||
m_ccpm->ccpmEngineChannel->setCurrentIndex(0);
|
||||
m_ccpm->ccpmTailChannel->addItems(channelNames);
|
||||
@ -474,14 +469,6 @@ void ConfigCcpmWidget::UpdateType()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Resets a mixer curve
|
||||
*/
|
||||
void ConfigCcpmWidget::resetMixer(MixerCurveWidget *mixer, int numElements)
|
||||
{
|
||||
mixer->initLinearCurve(numElements,(double)1);
|
||||
}
|
||||
|
||||
void ConfigCcpmWidget::UpdateCurveWidgets()
|
||||
{
|
||||
int NumCurvePoints,i,Changed;
|
||||
@ -501,7 +488,8 @@ void ConfigCcpmWidget::UpdateCurveWidgets()
|
||||
if (ThisValue!=OldCurveValues.at(i))Changed=1;
|
||||
}
|
||||
// Setup all Throttle1 curves for all types of airframes
|
||||
if (Changed==1)m_ccpm->ThrottleCurve->setCurve(curveValues);
|
||||
if (Changed==1)
|
||||
m_ccpm->ThrottleCurve->setCurve(&curveValues);
|
||||
|
||||
curveValues.clear();
|
||||
Changed=0;
|
||||
@ -513,7 +501,8 @@ void ConfigCcpmWidget::UpdateCurveWidgets()
|
||||
if (ThisValue!=OldCurveValues.at(i))Changed=1;
|
||||
}
|
||||
// Setup all Throttle1 curves for all types of airframes
|
||||
if (Changed==1)m_ccpm->PitchCurve->setCurve(curveValues);
|
||||
if (Changed==1)
|
||||
m_ccpm->PitchCurve->setCurve(&curveValues);
|
||||
}
|
||||
|
||||
void ConfigCcpmWidget::updatePitchCurveValue(QList<double> curveValues0,double Value0)
|
||||
@ -606,50 +595,40 @@ void ConfigCcpmWidget::UpdateCurveSettings()
|
||||
m_ccpm->CurveValue2->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
|
||||
m_ccpm->CurveValue3->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
|
||||
|
||||
//set default visible
|
||||
m_ccpm->CurveLabel1->setVisible(true);
|
||||
m_ccpm->CurveValue1->setVisible(true);
|
||||
m_ccpm->CurveLabel2->setVisible(false);
|
||||
m_ccpm->CurveValue2->setVisible(false);
|
||||
m_ccpm->CurveLabel3->setVisible(false);
|
||||
m_ccpm->CurveValue3->setVisible(false);
|
||||
m_ccpm->ccpmGenerateCurve->setVisible(true);
|
||||
m_ccpm->CurveToGenerate->setVisible(true);
|
||||
|
||||
if ( CurveType.compare("Flat")==0)
|
||||
{
|
||||
m_ccpm->CurveLabel1->setText("Value");
|
||||
m_ccpm->CurveLabel1->setVisible(true);
|
||||
m_ccpm->CurveValue1->setVisible(true);
|
||||
m_ccpm->CurveLabel2->setVisible(false);
|
||||
m_ccpm->CurveValue2->setVisible(false);
|
||||
m_ccpm->CurveLabel3->setVisible(false);
|
||||
m_ccpm->CurveValue3->setVisible(false);
|
||||
m_ccpm->ccpmGenerateCurve->setVisible(true);
|
||||
m_ccpm->CurveToGenerate->setVisible(true);
|
||||
}
|
||||
if ( CurveType.compare("Linear")==0)
|
||||
{
|
||||
m_ccpm->CurveLabel1->setText("Min");
|
||||
m_ccpm->CurveLabel1->setVisible(true);
|
||||
m_ccpm->CurveValue1->setVisible(true);
|
||||
m_ccpm->CurveLabel2->setText("Max");
|
||||
m_ccpm->CurveLabel2->setVisible(true);
|
||||
m_ccpm->CurveValue2->setVisible(true);
|
||||
m_ccpm->CurveLabel3->setVisible(false);
|
||||
m_ccpm->CurveValue3->setVisible(false);
|
||||
m_ccpm->ccpmGenerateCurve->setVisible(true);
|
||||
m_ccpm->CurveToGenerate->setVisible(true);
|
||||
}
|
||||
if ( CurveType.compare("Step")==0)
|
||||
{
|
||||
m_ccpm->CurveLabel1->setText("Min");
|
||||
m_ccpm->CurveLabel1->setVisible(true);
|
||||
m_ccpm->CurveValue1->setVisible(true);
|
||||
m_ccpm->CurveLabel2->setText("Max");
|
||||
m_ccpm->CurveLabel2->setVisible(true);
|
||||
m_ccpm->CurveValue2->setVisible(true);
|
||||
m_ccpm->CurveLabel3->setText("Step at");
|
||||
m_ccpm->CurveLabel3->setVisible(true);
|
||||
m_ccpm->CurveValue3->setVisible(true);
|
||||
m_ccpm->ccpmGenerateCurve->setVisible(true);
|
||||
m_ccpm->CurveToGenerate->setVisible(true);
|
||||
}
|
||||
if ( CurveType.compare("Exp")==0)
|
||||
{
|
||||
m_ccpm->CurveLabel1->setText("Min");
|
||||
m_ccpm->CurveLabel1->setVisible(true);
|
||||
m_ccpm->CurveValue1->setVisible(true);
|
||||
m_ccpm->CurveLabel2->setText("Max");
|
||||
m_ccpm->CurveLabel2->setVisible(true);
|
||||
m_ccpm->CurveValue2->setVisible(true);
|
||||
@ -660,14 +639,10 @@ void ConfigCcpmWidget::UpdateCurveSettings()
|
||||
m_ccpm->CurveValue3->setMaximum(100.0);
|
||||
m_ccpm->CurveValue3->setSingleStep(1.0);
|
||||
m_ccpm->CurveValue3->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);;
|
||||
m_ccpm->ccpmGenerateCurve->setVisible(true);
|
||||
m_ccpm->CurveToGenerate->setVisible(true);
|
||||
}
|
||||
if ( CurveType.compare("Log")==0)
|
||||
{
|
||||
m_ccpm->CurveLabel1->setText("Min");
|
||||
m_ccpm->CurveLabel1->setVisible(true);
|
||||
m_ccpm->CurveValue1->setVisible(true);
|
||||
m_ccpm->CurveLabel2->setText("Max");
|
||||
m_ccpm->CurveLabel2->setVisible(true);
|
||||
m_ccpm->CurveValue2->setVisible(true);
|
||||
@ -677,22 +652,17 @@ void ConfigCcpmWidget::UpdateCurveSettings()
|
||||
m_ccpm->CurveValue3->setMinimum(1.0);
|
||||
m_ccpm->CurveValue3->setMaximum(100.0);
|
||||
m_ccpm->CurveValue3->setSingleStep(1.0);
|
||||
m_ccpm->CurveValue3->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);;
|
||||
m_ccpm->ccpmGenerateCurve->setVisible(true);
|
||||
m_ccpm->CurveToGenerate->setVisible(true);
|
||||
m_ccpm->CurveValue3->setCorrectionMode(QAbstractSpinBox::CorrectToNearestValue);
|
||||
}
|
||||
if ( CurveType.compare("Custom")==0)
|
||||
{
|
||||
m_ccpm->CurveLabel1->setVisible(false);
|
||||
m_ccpm->CurveValue1->setVisible(false);
|
||||
m_ccpm->CurveLabel2->setVisible(false);
|
||||
m_ccpm->CurveValue2->setVisible(false);
|
||||
m_ccpm->CurveLabel3->setVisible(false);
|
||||
m_ccpm->CurveValue3->setVisible(false);
|
||||
m_ccpm->ccpmGenerateCurve->setVisible(false);
|
||||
m_ccpm->CurveToGenerate->setVisible(false);
|
||||
}
|
||||
UpdateCurveWidgets();
|
||||
|
||||
UpdateCurveWidgets();
|
||||
|
||||
}
|
||||
void ConfigCcpmWidget::GenerateCurve()
|
||||
@ -881,7 +851,8 @@ void ConfigCcpmWidget::UpdateMixer()
|
||||
float CollectiveConstant,PitchConstant,RollConstant,ThisAngle[6];
|
||||
QString Channel;
|
||||
|
||||
throwConfigError(QString("HeliCP"));
|
||||
if (throwConfigError(QString("HeliCP")))
|
||||
return;
|
||||
|
||||
GUIConfigDataUnion config = GetConfigData();
|
||||
|
||||
@ -1744,13 +1715,16 @@ void ConfigCcpmWidget::SwashLvlSpinBoxChanged(int value)
|
||||
/**
|
||||
This function displays text and color formatting in order to help the user understand what channels have not yet been configured.
|
||||
*/
|
||||
void ConfigCcpmWidget::throwConfigError(QString airframeType)
|
||||
bool ConfigCcpmWidget::throwConfigError(QString airframeType)
|
||||
{
|
||||
Q_UNUSED(airframeType);
|
||||
|
||||
bool error = false;
|
||||
|
||||
if((m_ccpm->ccpmServoWChannel->currentIndex()==0)&&(m_ccpm->ccpmServoWChannel->isEnabled()))
|
||||
{
|
||||
m_ccpm->ccpmServoWLabel->setText("<font color=red>Servo W</font>");
|
||||
error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1759,6 +1733,7 @@ void ConfigCcpmWidget::throwConfigError(QString airframeType)
|
||||
if((m_ccpm->ccpmServoXChannel->currentIndex()==0)&&(m_ccpm->ccpmServoXChannel->isEnabled()))
|
||||
{
|
||||
m_ccpm->ccpmServoXLabel->setText("<font color=red>Servo X</font>");
|
||||
error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1767,6 +1742,7 @@ void ConfigCcpmWidget::throwConfigError(QString airframeType)
|
||||
if((m_ccpm->ccpmServoYChannel->currentIndex()==0)&&(m_ccpm->ccpmServoYChannel->isEnabled()))
|
||||
{
|
||||
m_ccpm->ccpmServoYLabel->setText("<font color=red>Servo Y</font>");
|
||||
error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1775,6 +1751,7 @@ void ConfigCcpmWidget::throwConfigError(QString airframeType)
|
||||
if((m_ccpm->ccpmServoZChannel->currentIndex()==0)&&(m_ccpm->ccpmServoZChannel->isEnabled()))
|
||||
{
|
||||
m_ccpm->ccpmServoZLabel->setText("<font color=red>Servo Z</font>");
|
||||
error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1793,10 +1770,12 @@ void ConfigCcpmWidget::throwConfigError(QString airframeType)
|
||||
if((m_ccpm->ccpmTailChannel->currentIndex()==0)&&(m_ccpm->ccpmTailChannel->isEnabled()))
|
||||
{
|
||||
m_ccpm->ccpmTailLabel->setText("<font color=red>Tail Rotor</font>");
|
||||
error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ccpm->ccpmTailLabel->setText("<font color=black>Tail Rotor</font>");
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ private:
|
||||
virtual void setupUI(QString airframeType);
|
||||
virtual void refreshWidgetsValues(QString frameType);
|
||||
virtual QString updateConfigObjectsFromWidgets();
|
||||
virtual void throwConfigError(QString airframeType);
|
||||
virtual bool throwConfigError(QString airframeType);
|
||||
|
||||
void ccpmSwashplateUpdate();
|
||||
void ccpmSwashplateRedraw();
|
||||
@ -103,7 +103,6 @@ private:
|
||||
void GenerateCurve();
|
||||
void UpdateMixer();
|
||||
void UpdateType();
|
||||
void resetMixer(MixerCurveWidget *mixer, int numElements);
|
||||
void UpdateCurveWidgets();
|
||||
void updatePitchCurveValue(QList<double>,double);
|
||||
void updateThrottleCurveValue(QList<double>,double);
|
||||
|
@ -262,15 +262,7 @@ bool ConfigFixedWingWidget::setupFrameFixedWing(QString airframeType)
|
||||
{
|
||||
// Check coherence:
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(airframeType);
|
||||
|
||||
// - At least Pitch and either Roll or Yaw
|
||||
if (m_aircraft->fwEngineChannelBox->currentText() == "None" ||
|
||||
m_aircraft->fwElevator1ChannelBox->currentText() == "None" ||
|
||||
((m_aircraft->fwAileron1ChannelBox->currentText() == "None") &&
|
||||
(m_aircraft->fwRudder1ChannelBox->currentText() == "None"))) {
|
||||
// TODO: explain the problem in the UI
|
||||
// m_aircraft->fwStatusLabel->setText("ERROR: check channel assignment");
|
||||
if (throwConfigError(airframeType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -351,14 +343,7 @@ bool ConfigFixedWingWidget::setupFrameElevon(QString airframeType)
|
||||
{
|
||||
// Check coherence:
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(airframeType);
|
||||
|
||||
// - At least Aileron1 and Aileron 2, and engine
|
||||
if (m_aircraft->fwEngineChannelBox->currentText() == "None" ||
|
||||
m_aircraft->fwAileron1ChannelBox->currentText() == "None" ||
|
||||
m_aircraft->fwAileron2ChannelBox->currentText() == "None") {
|
||||
// TODO: explain the problem in the UI
|
||||
// m_aircraft->fwStatusLabel->setText("ERROR: check channel assignment");
|
||||
if (throwConfigError(airframeType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -436,14 +421,7 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType)
|
||||
{
|
||||
// Check coherence:
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(airframeType);
|
||||
|
||||
// - At least Pitch1 and Pitch2, and engine
|
||||
if (m_aircraft->fwEngineChannelBox->currentText() == "None" ||
|
||||
m_aircraft->fwElevator1ChannelBox->currentText() == "None" ||
|
||||
m_aircraft->fwElevator2ChannelBox->currentText() == "None") {
|
||||
// TODO: explain the problem in the UI
|
||||
// m_aircraft->fwStatusLabel->setText("WARNING: check channel assignment");
|
||||
if (throwConfigError(airframeType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -526,7 +504,7 @@ bool ConfigFixedWingWidget::setupFrameVtail(QString airframeType)
|
||||
/**
|
||||
This function displays text and color formatting in order to help the user understand what channels have not yet been configured.
|
||||
*/
|
||||
void ConfigFixedWingWidget::throwConfigError(QString airframeType)
|
||||
bool ConfigFixedWingWidget::throwConfigError(QString airframeType)
|
||||
{
|
||||
//Initialize configuration error flag
|
||||
bool error=false;
|
||||
@ -618,4 +596,6 @@ void ConfigFixedWingWidget::throwConfigError(QString airframeType)
|
||||
if (error){
|
||||
m_aircraft->fwStatusLabel->setText(QString("<font color='red'>ERROR: Assign all necessary channels</font>"));
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ private slots:
|
||||
virtual void setupUI(QString airframeType);
|
||||
virtual void refreshWidgetsValues(QString frameType);
|
||||
virtual QString updateConfigObjectsFromWidgets();
|
||||
virtual void throwConfigError(QString airframeType);
|
||||
virtual bool throwConfigError(QString airframeType);
|
||||
|
||||
|
||||
protected:
|
||||
|
@ -289,16 +289,9 @@ void ConfigGroundVehicleWidget::refreshWidgetsValues(QString frameType)
|
||||
bool ConfigGroundVehicleWidget::setupGroundVehicleMotorcycle(QString airframeType){
|
||||
// Check coherence:
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(airframeType);
|
||||
|
||||
// - Motor, steering, and balance
|
||||
if (m_aircraft->gvMotor2ChannelBox->currentText() == "None" ||
|
||||
(m_aircraft->gvSteering1ChannelBox->currentText() == "None" ||
|
||||
m_aircraft->gvSteering2ChannelBox->currentText() == "None") )
|
||||
{
|
||||
if (throwConfigError(airframeType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Now setup the channels:
|
||||
GUIConfigDataUnion config = GetConfigData();
|
||||
@ -352,16 +345,11 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleMotorcycle(QString airframeTyp
|
||||
bool ConfigGroundVehicleWidget::setupGroundVehicleDifferential(QString airframeType){
|
||||
// Check coherence:
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(airframeType);
|
||||
|
||||
// - Left and right steering
|
||||
if ( m_aircraft->gvMotor2ChannelBox->currentText() == "None" ||
|
||||
m_aircraft->gvSteering1ChannelBox->currentText() == "None")
|
||||
{
|
||||
|
||||
if (throwConfigError(airframeType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Now setup the channels:
|
||||
GUIConfigDataUnion config = GetConfigData();
|
||||
ResetActuators(&config);
|
||||
@ -411,14 +399,7 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleCar(QString airframeType)
|
||||
{
|
||||
// Check coherence:
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(airframeType);
|
||||
|
||||
// - At least one motor and one steering servo
|
||||
if ((m_aircraft->gvMotor1ChannelBox->currentText() == "None" &&
|
||||
m_aircraft->gvMotor2ChannelBox->currentText() == "None") ||
|
||||
(m_aircraft->gvSteering1ChannelBox->currentText() == "None" &&
|
||||
m_aircraft->gvSteering2ChannelBox->currentText() == "None"))
|
||||
{
|
||||
if (throwConfigError(airframeType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -468,7 +449,7 @@ bool ConfigGroundVehicleWidget::setupGroundVehicleCar(QString airframeType)
|
||||
/**
|
||||
This function displays text and color formatting in order to help the user understand what channels have not yet been configured.
|
||||
*/
|
||||
void ConfigGroundVehicleWidget::throwConfigError(QString airframeType)
|
||||
bool ConfigGroundVehicleWidget::throwConfigError(QString airframeType)
|
||||
{
|
||||
//Initialize configuration error flag
|
||||
bool error=false;
|
||||
@ -558,5 +539,6 @@ void ConfigGroundVehicleWidget::throwConfigError(QString airframeType)
|
||||
if (error){
|
||||
m_aircraft->gvStatusLabel->setText(QString("<font color='red'>ERROR: Assign all necessary channels</font>"));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ private slots:
|
||||
virtual void setupUI(QString airframeType);
|
||||
virtual void refreshWidgetsValues(QString frameType);
|
||||
virtual QString updateConfigObjectsFromWidgets();
|
||||
virtual void throwConfigError(QString airframeType);
|
||||
virtual bool throwConfigError(QString airframeType);
|
||||
|
||||
|
||||
protected:
|
||||
|
@ -93,6 +93,10 @@ void ConfigMultiRotorWidget::setupUI(QString frameType)
|
||||
enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
|
||||
}
|
||||
|
||||
m_aircraft->mrRollMixLevel->setValue(100);
|
||||
m_aircraft->mrPitchMixLevel->setValue(100);
|
||||
m_aircraft->mrYawMixLevel->setValue(50);
|
||||
|
||||
m_aircraft->triYawChannelBox->setEnabled(true);
|
||||
}
|
||||
else if (frameType == "QuadX" || frameType == "Quad X") {
|
||||
@ -104,6 +108,7 @@ void ConfigMultiRotorWidget::setupUI(QString frameType)
|
||||
enableComboBox(uiowner, QString("multiMotorChannelBox%0").arg(i), true);
|
||||
}
|
||||
|
||||
// init mixer levels
|
||||
m_aircraft->mrRollMixLevel->setValue(50);
|
||||
m_aircraft->mrPitchMixLevel->setValue(50);
|
||||
m_aircraft->mrYawMixLevel->setValue(50);
|
||||
@ -283,20 +288,12 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
|
||||
{
|
||||
QString airframeType;
|
||||
QList<QString> motorList;
|
||||
|
||||
// We can already setup the feedforward here, as it is common to all platforms
|
||||
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
UAVObjectField* field = obj->getField(QString("FeedForward"));
|
||||
field->setDouble((double)m_aircraft->feedForwardSlider->value()/100);
|
||||
field = obj->getField(QString("AccelTime"));
|
||||
field->setDouble(m_aircraft->accelTime->value());
|
||||
field = obj->getField(QString("DecelTime"));
|
||||
field->setDouble(m_aircraft->decelTime->value());
|
||||
field = obj->getField(QString("MaxAccel"));
|
||||
field->setDouble(m_aircraft->maxAccelSlider->value());
|
||||
|
||||
|
||||
UAVDataObject* mixerObj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixerObj);
|
||||
|
||||
// Curve is also common to all quads:
|
||||
setThrottleCurve(obj, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->multiThrottleCurve->getCurve() );
|
||||
setThrottleCurve(mixerObj, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->multiThrottleCurve->getCurve() );
|
||||
|
||||
if (m_aircraft->multirotorFrameType->currentText() == "Quad +") {
|
||||
airframeType = "QuadP";
|
||||
@ -314,15 +311,7 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
|
||||
airframeType = "HexaCoax";
|
||||
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(6);
|
||||
|
||||
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox3->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox4->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox5->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox6->currentText() == "None" ) {
|
||||
|
||||
if (throwConfigError(6)) {
|
||||
return airframeType;
|
||||
}
|
||||
motorList << "VTOLMotorNW" << "VTOLMotorW" << "VTOLMotorNE" << "VTOLMotorE"
|
||||
@ -348,18 +337,9 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
|
||||
airframeType = "Octo";
|
||||
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(8);
|
||||
|
||||
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox3->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox4->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox5->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox6->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox7->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox8->currentText() == "None") {
|
||||
|
||||
if (throwConfigError(8)) {
|
||||
return airframeType;
|
||||
|
||||
}
|
||||
motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE"
|
||||
<< "VTOLMotorS" << "VTOLMotorSW" << "VTOLMotorW" << "VTOLMotorNW";
|
||||
@ -383,17 +363,7 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
|
||||
airframeType = "OctoV";
|
||||
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(8);
|
||||
|
||||
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox3->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox4->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox5->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox6->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox7->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox8->currentText() == "None") {
|
||||
|
||||
if (throwConfigError(8)) {
|
||||
return airframeType;
|
||||
}
|
||||
motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE"
|
||||
@ -419,17 +389,7 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
|
||||
airframeType = "OctoCoaxP";
|
||||
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(8);
|
||||
|
||||
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox3->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox4->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox5->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox6->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox7->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox8->currentText() == "None") {
|
||||
|
||||
if (throwConfigError(8)) {
|
||||
return airframeType;
|
||||
}
|
||||
motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE" << "VTOLMotorSE"
|
||||
@ -454,17 +414,7 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
|
||||
airframeType = "OctoCoaxX";
|
||||
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(8);
|
||||
|
||||
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox3->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox4->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox5->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox6->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox7->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox8->currentText() == "None") {
|
||||
|
||||
if (throwConfigError(8)) {
|
||||
return airframeType;
|
||||
}
|
||||
motorList << "VTOLMotorNW" << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorE"
|
||||
@ -489,12 +439,9 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
|
||||
airframeType = "Tri";
|
||||
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(3);
|
||||
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox3->currentText() == "None" ) {
|
||||
|
||||
if (throwConfigError(3)) {
|
||||
return airframeType;
|
||||
|
||||
}
|
||||
if (m_aircraft->triYawChannelBox->currentText() == "None") {
|
||||
m_aircraft->mrStatusLabel->setText("<font color='red'>Error: Assign a Yaw channel</font>");
|
||||
@ -523,8 +470,6 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
|
||||
setupMultiRotorMixer(mixer);
|
||||
|
||||
//tell the mixer about tricopter yaw channel
|
||||
UAVDataObject* mixerObj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixerObj);
|
||||
|
||||
int channel = m_aircraft->triYawChannelBox->currentIndex()-1;
|
||||
if (channel > -1){
|
||||
@ -868,14 +813,7 @@ bool ConfigMultiRotorWidget::setupQuad(bool pLayout)
|
||||
// Check coherence:
|
||||
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(4);
|
||||
|
||||
// - Four engines have to be defined
|
||||
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox3->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox4->currentText() == "None") {
|
||||
|
||||
if (throwConfigError(4)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -943,19 +881,9 @@ bool ConfigMultiRotorWidget::setupHexa(bool pLayout)
|
||||
{
|
||||
// Check coherence:
|
||||
//Show any config errors in GUI
|
||||
throwConfigError(6);
|
||||
|
||||
// - Four engines have to be defined
|
||||
if (m_aircraft->multiMotorChannelBox1->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox2->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox3->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox4->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox5->currentText() == "None" ||
|
||||
m_aircraft->multiMotorChannelBox6->currentText() == "None") {
|
||||
|
||||
if (throwConfigError(6))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QList<QString> motorList;
|
||||
if (pLayout) {
|
||||
motorList << "VTOLMotorN" << "VTOLMotorNE" << "VTOLMotorSE"
|
||||
@ -1069,7 +997,7 @@ bool ConfigMultiRotorWidget::setupMultiRotorMixer(double mixerFactors[8][3])
|
||||
/**
|
||||
This function displays text and color formatting in order to help the user understand what channels have not yet been configured.
|
||||
*/
|
||||
void ConfigMultiRotorWidget::throwConfigError(int numMotors)
|
||||
bool ConfigMultiRotorWidget::throwConfigError(int numMotors)
|
||||
{
|
||||
//Initialize configuration error flag
|
||||
bool error=false;
|
||||
@ -1096,6 +1024,7 @@ void ConfigMultiRotorWidget::throwConfigError(int numMotors)
|
||||
if (error){
|
||||
m_aircraft->mrStatusLabel->setText(QString("<font color='red'>ERROR: Assign all %1 motor channels</font>").arg(numMotors));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
@ -71,7 +71,7 @@ private slots:
|
||||
virtual void setupUI(QString airframeType);
|
||||
virtual void refreshWidgetsValues(QString frameType);
|
||||
virtual QString updateConfigObjectsFromWidgets();
|
||||
void throwConfigError(int numMotors);
|
||||
virtual bool throwConfigError(int numMotors);
|
||||
|
||||
|
||||
protected:
|
||||
|
@ -233,6 +233,30 @@ void VehicleConfig::setMixerVectorValue(UAVDataObject* mixer, int channel, Mixer
|
||||
}
|
||||
}
|
||||
|
||||
double VehicleConfig::getMixerValue(UAVDataObject* mixer, QString elementName)
|
||||
{
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
double value = 0.0;
|
||||
|
||||
QPointer<UAVObjectField> field = mixer->getField(elementName);
|
||||
if (field) {
|
||||
value = field->getDouble();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void VehicleConfig::setMixerValue(UAVDataObject* mixer, QString elementName, double value)
|
||||
{
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
QPointer<UAVObjectField> field = mixer->getField(elementName);
|
||||
if (field) {
|
||||
field->setDouble(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VehicleConfig::setThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveElem curveType, QList<double> curve)
|
||||
{
|
||||
QPointer<UAVObjectField> field;
|
||||
@ -287,6 +311,36 @@ void VehicleConfig::getThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveEle
|
||||
}
|
||||
}
|
||||
|
||||
bool VehicleConfig::isValidThrottleCurve(QList<double>* curve)
|
||||
{
|
||||
Q_ASSERT(curve);
|
||||
|
||||
if (curve) {
|
||||
for (int i=0; i < curve->count(); i++) {
|
||||
if (curve->at(i) != 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
double VehicleConfig::getCurveMin(QList<double>* curve)
|
||||
{
|
||||
double min = 0;
|
||||
for (int i=0; i<curve->count(); i++)
|
||||
min = std::min(min, curve->at(i));
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
double VehicleConfig::getCurveMax(QList<double>* curve)
|
||||
{
|
||||
double max = 0;
|
||||
for (int i=0; i<curve->count(); i++)
|
||||
max = std::max(max, curve->at(i));
|
||||
|
||||
return max;
|
||||
}
|
||||
/**
|
||||
Reset the contents of a field
|
||||
*/
|
||||
|
@ -130,9 +130,13 @@ class VehicleConfig: public ConfigTaskWidget
|
||||
void resetMixerVector(UAVDataObject* mixer, int channel);
|
||||
QString getMixerType(UAVDataObject* mixer, int channel);
|
||||
void setMixerType(UAVDataObject* mixer, int channel, MixerTypeElem mixerType);
|
||||
double getMixerValue(UAVDataObject* mixer, QString elementName);
|
||||
void setMixerValue(UAVDataObject* mixer, QString elementName, double value);
|
||||
void setThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveElem curveType, QList<double> curve);
|
||||
void getThrottleCurve(UAVDataObject* mixer, MixerThrottleCurveElem curveType, QList<double>* curve);
|
||||
|
||||
bool isValidThrottleCurve(QList<double>* curve);
|
||||
double getCurveMin(QList<double>* curve);
|
||||
double getCurveMax(QList<double>* curve);
|
||||
virtual void ResetActuators(GUIConfigDataUnion* configData);
|
||||
virtual QStringList getChannelDescriptions();
|
||||
|
||||
|
@ -274,7 +274,7 @@ QStringList ConfigVehicleTypeWidget::getChannelDescriptions()
|
||||
case SystemSettings::AIRFRAMETYPE_FIXEDWINGELEVON:
|
||||
case SystemSettings::AIRFRAMETYPE_FIXEDWINGVTAIL:
|
||||
{
|
||||
ConfigFixedWingWidget* fixedwing = new ConfigFixedWingWidget();
|
||||
QPointer<ConfigFixedWingWidget> fixedwing = new ConfigFixedWingWidget();
|
||||
channelDesc = fixedwing->getChannelDescriptions();
|
||||
}
|
||||
break;
|
||||
@ -282,7 +282,7 @@ QStringList ConfigVehicleTypeWidget::getChannelDescriptions()
|
||||
// helicp
|
||||
case SystemSettings::AIRFRAMETYPE_HELICP:
|
||||
{
|
||||
ConfigCcpmWidget* heli = new ConfigCcpmWidget();
|
||||
QPointer<ConfigCcpmWidget> heli = new ConfigCcpmWidget();
|
||||
channelDesc = heli->getChannelDescriptions();
|
||||
}
|
||||
break;
|
||||
@ -300,7 +300,7 @@ QStringList ConfigVehicleTypeWidget::getChannelDescriptions()
|
||||
case SystemSettings::AIRFRAMETYPE_HEXACOAX:
|
||||
case SystemSettings::AIRFRAMETYPE_HEXA:
|
||||
{
|
||||
ConfigMultiRotorWidget* multi = new ConfigMultiRotorWidget();
|
||||
QPointer<ConfigMultiRotorWidget> multi = new ConfigMultiRotorWidget();
|
||||
channelDesc = multi->getChannelDescriptions();
|
||||
}
|
||||
break;
|
||||
@ -310,7 +310,7 @@ QStringList ConfigVehicleTypeWidget::getChannelDescriptions()
|
||||
case SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEDIFFERENTIAL:
|
||||
case SystemSettings::AIRFRAMETYPE_GROUNDVEHICLEMOTORCYCLE:
|
||||
{
|
||||
ConfigGroundVehicleWidget* ground = new ConfigGroundVehicleWidget();
|
||||
QPointer<ConfigGroundVehicleWidget> ground = new ConfigGroundVehicleWidget();
|
||||
channelDesc = ground->getChannelDescriptions();
|
||||
}
|
||||
break;
|
||||
@ -444,16 +444,17 @@ void ConfigVehicleTypeWidget::enableFFTest()
|
||||
// Depending on phase, either move actuator or send FF settings:
|
||||
if (ffTuningPhase) {
|
||||
// Send FF settings to the board
|
||||
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
UAVObjectField* field = obj->getField(QString("FeedForward"));
|
||||
field->setDouble((double)m_aircraft->feedForwardSlider->value()/100);
|
||||
field = obj->getField(QString("AccelTime"));
|
||||
field->setDouble(m_aircraft->accelTime->value());
|
||||
field = obj->getField(QString("DecelTime"));
|
||||
field->setDouble(m_aircraft->decelTime->value());
|
||||
field = obj->getField(QString("MaxAccel"));
|
||||
field->setDouble(m_aircraft->maxAccelSlider->value());
|
||||
obj->updated();
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
QPointer<VehicleConfig> vconfig = new VehicleConfig();
|
||||
|
||||
// Update feed forward settings
|
||||
vconfig->setMixerValue(mixer, "FeedForward", m_aircraft->feedForwardSlider->value() / 100.0);
|
||||
vconfig->setMixerValue(mixer, "AccelTime", m_aircraft->accelTime->value());
|
||||
vconfig->setMixerValue(mixer, "DecelTime", m_aircraft->decelTime->value());
|
||||
vconfig->setMixerValue(mixer, "MaxAccel", m_aircraft->maxAccelSlider->value());
|
||||
mixer->updated();
|
||||
} else {
|
||||
// Toggle motor state
|
||||
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ManualControlCommand")));
|
||||
@ -614,84 +615,55 @@ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject * o)
|
||||
{
|
||||
Q_UNUSED(o);
|
||||
|
||||
if(!allObjectsUpdated())
|
||||
return;
|
||||
//if(!allObjectsUpdated())
|
||||
// return;
|
||||
|
||||
//WHAT DOES THIS DO?
|
||||
bool dirty=isDirty(); //WHY IS THIS CALLED HERE AND THEN AGAIN SEVERAL LINES LATER IN setupAirframeUI()
|
||||
|
||||
// Get the Airframe type from the system settings:
|
||||
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings")));
|
||||
Q_ASSERT(obj);
|
||||
UAVObjectField *field = obj->getField(QString("AirframeType"));
|
||||
UAVDataObject* system = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings")));
|
||||
Q_ASSERT(system);
|
||||
|
||||
UAVObjectField *field = system->getField(QString("AirframeType"));
|
||||
Q_ASSERT(field);
|
||||
// At this stage, we will need to have some hardcoded settings in this code, this
|
||||
// is not ideal, but here you go.
|
||||
QString frameType = field->getValue().toString();
|
||||
setupAirframeUI(frameType);
|
||||
|
||||
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(obj);
|
||||
field = obj->getField(QString("ThrottleCurve1"));
|
||||
Q_ASSERT(field);
|
||||
QList<double> curveValues;
|
||||
// If the 1st element of the curve is <= -10, then the curve
|
||||
// is a straight line (that's how the mixer works on the mainboard):
|
||||
if (field->getValue(0).toInt() <= -10) {
|
||||
m_aircraft->multiThrottleCurve->initLinearCurve(field->getNumElements(),(double)1);
|
||||
m_aircraft->fixedWingThrottle->initLinearCurve(field->getNumElements(),(double)1);
|
||||
m_aircraft->groundVehicleThrottle1->initLinearCurve(field->getNumElements(),(double)1);
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
QPointer<VehicleConfig> vconfig = new VehicleConfig();
|
||||
|
||||
QList<double> curveValues;
|
||||
vconfig->getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, &curveValues);
|
||||
|
||||
// is at least one of the curve values != 0?
|
||||
if (vconfig->isValidThrottleCurve(&curveValues)) {
|
||||
// yes, use the curve we just read from mixersettings
|
||||
m_aircraft->multiThrottleCurve->initCurve(&curveValues);
|
||||
m_aircraft->fixedWingThrottle->initCurve(&curveValues);
|
||||
m_aircraft->groundVehicleThrottle1->initCurve(&curveValues);
|
||||
}
|
||||
else {
|
||||
double temp=0;
|
||||
double value;
|
||||
for (unsigned int i=0; i < field->getNumElements(); i++) {
|
||||
value=field->getValue(i).toDouble();
|
||||
temp+=value;
|
||||
curveValues.append(value);
|
||||
}
|
||||
if(temp==0)
|
||||
{
|
||||
m_aircraft->multiThrottleCurve->initLinearCurve(field->getNumElements(),0.9);
|
||||
m_aircraft->fixedWingThrottle->initLinearCurve(field->getNumElements(),(double)1);
|
||||
m_aircraft->groundVehicleThrottle1->initLinearCurve(field->getNumElements(),(double)1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_aircraft->multiThrottleCurve->initCurve(curveValues);
|
||||
m_aircraft->fixedWingThrottle->initCurve(curveValues);
|
||||
m_aircraft->groundVehicleThrottle1->initCurve(curveValues);
|
||||
}
|
||||
// no, init a straight curve
|
||||
m_aircraft->multiThrottleCurve->initLinearCurve(curveValues.count(), 0.9);
|
||||
m_aircraft->fixedWingThrottle->initLinearCurve(curveValues.count(), 1.0);
|
||||
m_aircraft->groundVehicleThrottle1->initLinearCurve(curveValues.count(), 1.0);
|
||||
}
|
||||
|
||||
// Setup all Throttle2 curves for all types of airframes //AT THIS MOMENT, THAT MEANS ONLY GROUND VEHICLES
|
||||
Q_ASSERT(obj);
|
||||
field = obj->getField(QString("ThrottleCurve2"));
|
||||
Q_ASSERT(field);
|
||||
curveValues.clear();
|
||||
// If the 1st element of the curve is <= -10, then the curve
|
||||
// is a straight line (that's how the mixer works on the mainboard):
|
||||
if (field->getValue(0).toInt() <= -10) {
|
||||
m_aircraft->groundVehicleThrottle2->initLinearCurve(field->getNumElements(),(double)1);
|
||||
vconfig->getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, &curveValues);
|
||||
|
||||
if (vconfig->isValidThrottleCurve(&curveValues)) {
|
||||
m_aircraft->groundVehicleThrottle2->initCurve(&curveValues);
|
||||
}
|
||||
else {
|
||||
double temp=0;
|
||||
double value;
|
||||
for (unsigned int i=0; i < field->getNumElements(); i++) {
|
||||
value=field->getValue(i).toDouble();
|
||||
temp+=value;
|
||||
curveValues.append(value);
|
||||
}
|
||||
if(temp==0)
|
||||
{
|
||||
m_aircraft->groundVehicleThrottle2->initLinearCurve(field->getNumElements(),(double)1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_aircraft->groundVehicleThrottle2->initCurve(curveValues);
|
||||
}
|
||||
m_aircraft->groundVehicleThrottle2->initLinearCurve(curveValues.count(), 1.0);
|
||||
}
|
||||
|
||||
|
||||
// Load the Settings for fixed wing frames:
|
||||
if (frameType.startsWith("FixedWing")) {
|
||||
|
||||
@ -716,8 +688,7 @@ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject * o)
|
||||
|
||||
} else if (frameType == "Custom") {
|
||||
setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText("Custom"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateCustomAirframeUI();
|
||||
setDirty(dirty);
|
||||
@ -786,39 +757,35 @@ void ConfigVehicleTypeWidget::updateCustomAirframeUI()
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
VehicleConfig* vconfig = new VehicleConfig();
|
||||
QPointer<VehicleConfig> vconfig = new VehicleConfig();
|
||||
|
||||
QList<double> curveValues;
|
||||
vconfig->getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, &curveValues);
|
||||
|
||||
// setup throttlecurve 1
|
||||
vconfig->getThrottleCurve(mixer,VehicleConfig::MIXER_THROTTLECURVE1,&curveValues);
|
||||
|
||||
int total = 0;
|
||||
for (int i=0; i<curveValues.length(); i++)
|
||||
total += curveValues.at(i);
|
||||
|
||||
if (curveValues.at(0) <= -10 || total == 0) {
|
||||
m_aircraft->customThrottle1Curve->initLinearCurve(curveValues.length(),(double)1);
|
||||
// is at least one of the curve values != 0?
|
||||
if (vconfig->isValidThrottleCurve(&curveValues)) {
|
||||
// yes, use the curve we just read from mixersettings
|
||||
m_aircraft->customThrottle1Curve->setMin(vconfig->getCurveMin(&curveValues));
|
||||
m_aircraft->customThrottle1Curve->setMax(vconfig->getCurveMax(&curveValues));
|
||||
m_aircraft->customThrottle1Curve->initCurve(&curveValues);
|
||||
}
|
||||
else {
|
||||
m_aircraft->customThrottle1Curve->initCurve(curveValues);
|
||||
// no, init a straight curve
|
||||
m_aircraft->customThrottle1Curve->initLinearCurve(curveValues.count(),(double)1);
|
||||
}
|
||||
|
||||
// setup throttlecurve 2
|
||||
vconfig->getThrottleCurve(mixer,VehicleConfig::MIXER_THROTTLECURVE2,&curveValues);
|
||||
// Setup all Throttle2 curves for all types of airframes //AT THIS MOMENT, THAT MEANS ONLY GROUND VEHICLES
|
||||
vconfig->getThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, &curveValues);
|
||||
|
||||
total = 0;
|
||||
for (int i=0; i<curveValues.length(); i++)
|
||||
total += curveValues.at(i);
|
||||
|
||||
if (curveValues.at(0) <= -10 || total == 0) {
|
||||
m_aircraft->customThrottle2Curve->initLinearCurve(curveValues.length(),(double)1);
|
||||
if (vconfig->isValidThrottleCurve(&curveValues)) {
|
||||
m_aircraft->customThrottle2Curve->setMin(vconfig->getCurveMin(&curveValues));
|
||||
m_aircraft->customThrottle2Curve->setMax(vconfig->getCurveMax(&curveValues));
|
||||
m_aircraft->customThrottle2Curve->initCurve(&curveValues);
|
||||
}
|
||||
else {
|
||||
m_aircraft->customThrottle2Curve->initCurve(curveValues);
|
||||
m_aircraft->customThrottle2Curve->initLinearCurve(curveValues.count(),(double)1);
|
||||
}
|
||||
|
||||
|
||||
// Update the mixer table:
|
||||
for (int channel=0; channel<8; channel++) {
|
||||
UAVObjectField* field = mixer->getField(mixerTypes.at(channel));
|
||||
@ -843,6 +810,12 @@ void ConfigVehicleTypeWidget::updateCustomAirframeUI()
|
||||
QString::number(vconfig->getMixerVectorValue(mixer,channel,VehicleConfig::MIXERVECTOR_YAW)));
|
||||
}
|
||||
}
|
||||
|
||||
// Update feed forward settings
|
||||
m_aircraft->feedForwardSlider->setValue(vconfig->getMixerValue(mixer,"FeedForward") * 100);
|
||||
m_aircraft->accelTime->setValue(vconfig->getMixerValue(mixer,"AccelTime"));
|
||||
m_aircraft->decelTime->setValue(vconfig->getMixerValue(mixer,"DecelTime"));
|
||||
m_aircraft->maxAccelSlider->setValue(vconfig->getMixerValue(mixer,"MaxAccel"));
|
||||
}
|
||||
|
||||
|
||||
@ -855,6 +828,17 @@ void ConfigVehicleTypeWidget::updateCustomAirframeUI()
|
||||
*/
|
||||
void ConfigVehicleTypeWidget::updateObjectsFromWidgets()
|
||||
{
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
QPointer<VehicleConfig> vconfig = new VehicleConfig();
|
||||
|
||||
// Update feed forward settings
|
||||
vconfig->setMixerValue(mixer, "FeedForward", m_aircraft->feedForwardSlider->value() / 100.0);
|
||||
vconfig->setMixerValue(mixer, "AccelTime", m_aircraft->accelTime->value());
|
||||
vconfig->setMixerValue(mixer, "DecelTime", m_aircraft->decelTime->value());
|
||||
vconfig->setMixerValue(mixer, "MaxAccel", m_aircraft->maxAccelSlider->value());
|
||||
|
||||
QString airframeType = "Custom"; //Sets airframe type default to "Custom"
|
||||
if (m_aircraft->aircraftType->currentText() == "Fixed Wing") {
|
||||
airframeType = m_fixedwing->updateConfigObjectsFromWidgets();
|
||||
@ -869,12 +853,6 @@ void ConfigVehicleTypeWidget::updateObjectsFromWidgets()
|
||||
airframeType = m_groundvehicle->updateConfigObjectsFromWidgets();
|
||||
}
|
||||
else {
|
||||
|
||||
UAVDataObject* mixer = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
|
||||
Q_ASSERT(mixer);
|
||||
|
||||
VehicleConfig* vconfig = new VehicleConfig();
|
||||
|
||||
vconfig->setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->customThrottle1Curve->getCurve());
|
||||
vconfig->setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, m_aircraft->customThrottle2Curve->getCurve());
|
||||
|
||||
|
@ -43,7 +43,6 @@ Node::Node(MixerCurveWidget *graphWidget)
|
||||
setCacheMode(DeviceCoordinateCache);
|
||||
setZValue(-1);
|
||||
vertical = false;
|
||||
value = 0;
|
||||
}
|
||||
|
||||
void Node::addEdge(Edge *edge)
|
||||
@ -61,14 +60,14 @@ QList<Edge *> Node::edges() const
|
||||
QRectF Node::boundingRect() const
|
||||
{
|
||||
qreal adjust = 2;
|
||||
return QRectF(-10 - adjust, -10 - adjust,
|
||||
23 + adjust, 23 + adjust);
|
||||
return QRectF(-12 - adjust, -12 - adjust,
|
||||
28 + adjust, 28 + adjust);
|
||||
}
|
||||
|
||||
QPainterPath Node::shape() const
|
||||
{
|
||||
QPainterPath path;
|
||||
path.addEllipse(-10, -10, 20, 20);
|
||||
path.addEllipse(-12, -12, 25, 25);
|
||||
return path;
|
||||
}
|
||||
|
||||
@ -92,59 +91,60 @@ void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid
|
||||
}
|
||||
painter->setBrush(gradient);
|
||||
painter->setPen(QPen(Qt::black, 0));
|
||||
painter->drawEllipse(-10, -10, 20, 20);
|
||||
painter->drawEllipse(-12, -12, 25, 25);
|
||||
|
||||
painter->setPen(QPen(Qt::white, 0));
|
||||
painter->drawText(-10, 3, QString().sprintf("%.2f", value()));
|
||||
}
|
||||
|
||||
void Node::verticalMove(bool flag){
|
||||
vertical = flag;
|
||||
}
|
||||
|
||||
double Node::getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
void Node::setValue(double val) {
|
||||
value = val;
|
||||
}
|
||||
|
||||
|
||||
QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
|
||||
QPointF newPos = value.toPointF();
|
||||
double Node::value() {
|
||||
double h = graph->sceneRect().height();
|
||||
double ratio = (h - pos().y()) / h;
|
||||
return ((graph->getMax() - graph->getMin()) * ratio ) + graph->getMin();
|
||||
}
|
||||
|
||||
|
||||
QVariant Node::itemChange(GraphicsItemChange change, const QVariant &val)
|
||||
{
|
||||
QPointF newPos = val.toPointF();
|
||||
double h = graph->sceneRect().height();
|
||||
|
||||
switch (change) {
|
||||
case ItemPositionChange: {
|
||||
if (!vertical)
|
||||
break;
|
||||
// Force node to move vertically
|
||||
newPos.setX(pos().x());
|
||||
// Stay inside graph
|
||||
if (newPos.y() < 0)
|
||||
newPos.setY(0);
|
||||
//qDebug() << h << " - " << newPos.y();
|
||||
if (newPos.y() > h)
|
||||
newPos.setY(h);
|
||||
return newPos;
|
||||
|
||||
if (!vertical)
|
||||
break;
|
||||
|
||||
// Force node to move vertically
|
||||
newPos.setX(pos().x());
|
||||
|
||||
// Stay inside graph
|
||||
if (newPos.y() < 0)
|
||||
newPos.setY(0);
|
||||
//qDebug() << h << " - " << newPos.y();
|
||||
if (newPos.y() > h)
|
||||
newPos.setY(h);
|
||||
|
||||
return newPos;
|
||||
}
|
||||
case ItemPositionHasChanged: {
|
||||
foreach (Edge *edge, edgeList)
|
||||
edge->adjust();
|
||||
|
||||
double min = graph->getMin();
|
||||
double range = graph->getMax() - min;
|
||||
double ratio = (h - newPos.y()) / h;
|
||||
double val = (range * ratio ) + min;
|
||||
setValue(val);
|
||||
update();
|
||||
|
||||
graph->itemMoved(val);
|
||||
graph->itemMoved(value());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
return QGraphicsItem::itemChange(change, val);
|
||||
}
|
||||
|
||||
void Node::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
@ -55,22 +55,21 @@ public:
|
||||
QPainterPath shape() const;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
|
||||
void setValue(double val);
|
||||
double getValue();
|
||||
double value();
|
||||
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &val);
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
|
||||
private:
|
||||
|
||||
double value;
|
||||
QList<Edge *> edgeList;
|
||||
QPointF newPos;
|
||||
MixerCurveWidget *graph;
|
||||
bool vertical;
|
||||
|
||||
};
|
||||
|
||||
#endif // MIXERCURVEPOINT_H
|
||||
|
@ -69,6 +69,7 @@ MixerCurveWidget::MixerCurveWidget(QWidget *parent) : QGraphicsView(parent)
|
||||
//plot->setElementId("map");
|
||||
scene->addItem(plot);
|
||||
plot->setZValue(-1);
|
||||
|
||||
scene->setSceneRect(plot->boundingRect());
|
||||
setScene(scene);
|
||||
|
||||
@ -77,11 +78,11 @@ MixerCurveWidget::MixerCurveWidget(QWidget *parent) : QGraphicsView(parent)
|
||||
|
||||
MixerCurveWidget::~MixerCurveWidget()
|
||||
{
|
||||
for (int i=0; i<nodePool.count(); i++)
|
||||
delete nodePool.at(i);
|
||||
while (!nodePool.isEmpty())
|
||||
delete nodePool.takeFirst();
|
||||
|
||||
for (int i=0; i<edgePool.count(); i++)
|
||||
delete edgePool.at(i);
|
||||
while (!edgePool.isEmpty())
|
||||
delete edgePool.takeFirst();
|
||||
}
|
||||
|
||||
Node* MixerCurveWidget::getNode(int index)
|
||||
@ -122,14 +123,11 @@ Edge* MixerCurveWidget::getEdge(int index, Node* sourceNode, Node* destNode)
|
||||
If a curve exists already, resets it.
|
||||
Points should be between 0 and 1.
|
||||
*/
|
||||
void MixerCurveWidget::initCurve(QList<double> points)
|
||||
void MixerCurveWidget::initCurve(const QList<double>* points)
|
||||
{
|
||||
if (points.length() < 2)
|
||||
if (points->length() < 2)
|
||||
return; // We need at least 2 points on a curve!
|
||||
|
||||
if (nodeList.count() != points.count())
|
||||
initNodes(points.count());
|
||||
|
||||
// finally, set node positions
|
||||
setCurve(points);
|
||||
}
|
||||
@ -139,12 +137,8 @@ void MixerCurveWidget::initNodes(int numPoints)
|
||||
// First of all, clear any existing list
|
||||
if (nodeList.count()) {
|
||||
foreach (Node *node, nodeList ) {
|
||||
QList<Edge*> edges = node->edges();
|
||||
foreach(Edge *edge, edges) {
|
||||
if (edge->destNode() == node) {
|
||||
delete edge;
|
||||
}
|
||||
else {
|
||||
foreach(Edge *edge, node->edges()) {
|
||||
if (edge->sourceNode() == node) {
|
||||
scene()->removeItem(edge);
|
||||
}
|
||||
}
|
||||
@ -163,6 +157,8 @@ void MixerCurveWidget::initNodes(int numPoints)
|
||||
nodeList.append(node);
|
||||
scene()->addItem(node);
|
||||
|
||||
node->setPos(0,0);
|
||||
|
||||
if (prevNode) {
|
||||
scene()->addItem(getEdge(i, prevNode, node));
|
||||
}
|
||||
@ -179,7 +175,7 @@ QList<double> MixerCurveWidget::getCurve() {
|
||||
QList<double> list;
|
||||
|
||||
foreach(Node *node, nodeList) {
|
||||
list.append(node->getValue());
|
||||
list.append(node->value());
|
||||
}
|
||||
|
||||
return list;
|
||||
@ -187,51 +183,48 @@ QList<double> MixerCurveWidget::getCurve() {
|
||||
/**
|
||||
Sets a linear graph
|
||||
*/
|
||||
void MixerCurveWidget::initLinearCurve(quint32 numPoints, double maxValue, double minValue)
|
||||
void MixerCurveWidget::initLinearCurve(int numPoints, double maxValue, double minValue)
|
||||
{
|
||||
Q_UNUSED(maxValue);
|
||||
Q_UNUSED(minValue);
|
||||
double range = setRange(minValue, maxValue);
|
||||
|
||||
QList<double> points;
|
||||
for (double i=0; i<numPoints;i++) {
|
||||
double val = ((curveMax - curveMin) * (i/(numPoints-1))) + curveMin;
|
||||
for (double i=0; i < (double)numPoints; i++) {
|
||||
double val = (range * ( i / (double)(numPoints-1) ) ) + minValue;
|
||||
points.append(val);
|
||||
}
|
||||
initCurve(points);
|
||||
initCurve(&points);
|
||||
}
|
||||
/**
|
||||
Setd the current curve settings
|
||||
*/
|
||||
void MixerCurveWidget::setCurve(QList<double> points)
|
||||
void MixerCurveWidget::setCurve(const QList<double>* points)
|
||||
{
|
||||
curveUpdating = true;
|
||||
|
||||
if (nodeList.count() != points.count())
|
||||
initNodes(points.count());
|
||||
int ptCnt = points->count();
|
||||
if (nodeList.count() != ptCnt)
|
||||
initNodes(ptCnt);
|
||||
|
||||
double min = curveMin + 10;
|
||||
double max = curveMax + 10;
|
||||
double range = curveMax - curveMin;
|
||||
|
||||
qreal w = plot->boundingRect().width()/(points.count()-1);
|
||||
qreal w = plot->boundingRect().width()/(ptCnt-1);
|
||||
qreal h = plot->boundingRect().height();
|
||||
for (int i=0; i<points.count(); i++) {
|
||||
for (int i=0; i<ptCnt; i++) {
|
||||
|
||||
double val = points.at(i);
|
||||
if (val < curveMin)
|
||||
val = curveMin;
|
||||
if (val > curveMax)
|
||||
val = curveMax;
|
||||
double val = (points->at(i) < curveMin) ? curveMin : (points->at(i) > curveMax) ? curveMax : points->at(i);
|
||||
|
||||
val += 10;
|
||||
val -= min;
|
||||
val /= (max - min);
|
||||
val += range;
|
||||
val -= (curveMin + range);
|
||||
val /= range;
|
||||
|
||||
nodeList.at(i)->setPos(w*i, h - (val*h));
|
||||
nodeList.at(i)->verticalMove(true);
|
||||
Node* node = nodeList.at(i);
|
||||
node->setPos(w*i, h - (val*h));
|
||||
node->verticalMove(true);
|
||||
}
|
||||
|
||||
curveUpdating = false;
|
||||
|
||||
update();
|
||||
|
||||
emit curveUpdated(points, (double)0);
|
||||
}
|
||||
|
||||
@ -252,13 +245,11 @@ void MixerCurveWidget::resizeEvent(QResizeEvent* event)
|
||||
fitInView(plot, Qt::KeepAspectRatio);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MixerCurveWidget::itemMoved(double itemValue)
|
||||
{
|
||||
if (!curveUpdating) {
|
||||
QList<double> list = getCurve();
|
||||
emit curveUpdated(list, itemValue);
|
||||
QList<double> curve = getCurve();
|
||||
emit curveUpdated(&curve, itemValue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,8 +269,9 @@ double MixerCurveWidget::getMax()
|
||||
{
|
||||
return curveMax;
|
||||
}
|
||||
void MixerCurveWidget::setRange(double min, double max)
|
||||
double MixerCurveWidget::setRange(double min, double max)
|
||||
{
|
||||
curveMin = min;
|
||||
curveMax = max;
|
||||
return curveMax - curveMin;
|
||||
}
|
||||
|
@ -44,20 +44,20 @@ public:
|
||||
MixerCurveWidget(QWidget *parent = 0);
|
||||
~MixerCurveWidget();
|
||||
void itemMoved(double itemValue); // Callback when a point is moved, to be updated
|
||||
void initCurve (QList<double> points);
|
||||
void initCurve (const QList<double>* points);
|
||||
QList<double> getCurve();
|
||||
void initLinearCurve(quint32 numPoints, double maxValue = 1, double minValue = 0);
|
||||
void setCurve(QList<double>);
|
||||
void initLinearCurve(int numPoints, double maxValue = 1, double minValue = 0);
|
||||
void setCurve(const QList<double>* points);
|
||||
void setMin(double value);
|
||||
double getMin();
|
||||
void setMax(double value);
|
||||
double getMax();
|
||||
void setRange(double min, double max);
|
||||
double setRange(double min, double max);
|
||||
|
||||
static const int NODE_NUMELEM = 5;
|
||||
|
||||
signals:
|
||||
void curveUpdated(QList<double>, double );
|
||||
void curveUpdated(const QList<double>* points, const double value);
|
||||
|
||||
private slots:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user