1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-18 08:54:15 +01:00

Merged in f5soh/librepilot/laurent/LP-92_Feed_forward_remove (pull request #33)

Laurent/lp 92_feed_forward_remove
This commit is contained in:
Alessio Morale 2015-08-21 13:35:10 +02:00
commit 538a137bf6
9 changed files with 46 additions and 927 deletions

View File

@ -86,8 +86,6 @@ static xTaskHandle taskHandle;
static FrameType_t frameType = FRAME_TYPE_MULTIROTOR;
static SystemSettingsThrustControlOptions thrustType = SYSTEMSETTINGS_THRUSTCONTROL_THROTTLE;
static float lastResult[MAX_MIX_ACTUATORS] = { 0 };
static float filterAccumulator[MAX_MIX_ACTUATORS] = { 0 };
static uint8_t pinsMode[MAX_MIX_ACTUATORS];
// used to inform the actuator thread that actuator update rate is changed
static ActuatorSettingsData actuatorSettings;
@ -111,7 +109,7 @@ static void ActuatorSettingsUpdatedCb(UAVObjEvent *ev);
static void SettingsUpdatedCb(UAVObjEvent *ev);
float ProcessMixer(const int index, const float curve1, const float curve2,
ActuatorDesiredData *desired,
const float period, bool multirotor, bool fixedwing);
bool multirotor, bool fixedwing);
// this structure is equivalent to the UAVObjects for one mixer.
typedef struct {
@ -196,7 +194,6 @@ static void actuatorTask(__attribute__((unused)) void *parameters)
UAVObjEvent ev;
portTickType lastSysTime;
portTickType thisSysTime;
float dTSeconds;
uint32_t dTMilliseconds;
ActuatorCommandData command;
@ -246,7 +243,6 @@ static void actuatorTask(__attribute__((unused)) void *parameters)
thisSysTime = xTaskGetTickCount();
dTMilliseconds = (thisSysTime == lastSysTime) ? 1 : (thisSysTime - lastSysTime) * portTICK_RATE_MS;
lastSysTime = thisSysTime;
dTSeconds = dTMilliseconds * 0.001f;
FlightStatusGet(&flightStatus);
FlightModeSettingsGet(&settings);
@ -408,12 +404,10 @@ static void actuatorTask(__attribute__((unused)) void *parameters)
nonreversible_curve2 = 0.0f;
}
}
status[ct] = ProcessMixer(ct, nonreversible_curve1, nonreversible_curve2, &desired, dTSeconds, multirotor, fixedwing);
status[ct] = ProcessMixer(ct, nonreversible_curve1, nonreversible_curve2, &desired, multirotor, fixedwing);
// If not armed or motors aren't meant to spin all the time
if (!armed ||
(!spinWhileArmed && !positiveThrottle)) {
filterAccumulator[ct] = 0;
lastResult[ct] = 0;
status[ct] = -1; // force min throttle
}
// If armed meant to keep spinning,
@ -426,16 +420,14 @@ static void actuatorTask(__attribute__((unused)) void *parameters)
}
}
} else if (mixer_type == MIXERSETTINGS_MIXER1TYPE_REVERSABLEMOTOR) {
status[ct] = ProcessMixer(ct, curve1, curve2, &desired, dTSeconds, multirotor, fixedwing);
status[ct] = ProcessMixer(ct, curve1, curve2, &desired, multirotor, fixedwing);
// Reversable Motors are like Motors but go to neutral instead of minimum
// If not armed or motor is inactive - no "spinwhilearmed" for this engine type
if (!armed || !activeThrottle) {
filterAccumulator[ct] = 0;
lastResult[ct] = 0;
status[ct] = 0; // force neutral throttle
}
} else if (mixer_type == MIXERSETTINGS_MIXER1TYPE_SERVO) {
status[ct] = ProcessMixer(ct, curve1, curve2, &desired, dTSeconds, multirotor, fixedwing);
status[ct] = ProcessMixer(ct, curve1, curve2, &desired, multirotor, fixedwing);
} else {
status[ct] = -1;
@ -557,9 +549,9 @@ static void actuatorTask(__attribute__((unused)) void *parameters)
* Process mixing for one actuator
*/
float ProcessMixer(const int index, const float curve1, const float curve2,
ActuatorDesiredData *desired, const float period, bool multirotor, bool fixedwing)
ActuatorDesiredData *desired, bool multirotor, bool fixedwing)
{
static float lastFilteredResult[MAX_MIX_ACTUATORS];
const Mixer_t *mixers = (Mixer_t *)&mixerSettings.Mixer1Type; // pointer to array of mixers in UAVObjects
const Mixer_t *mixer = &mixers[index];
float differential = 1.0f;
@ -589,46 +581,12 @@ float ProcessMixer(const int index, const float curve1, const float curve2,
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_PITCH]) * desired->Pitch) +
(((float)mixer->matrix[MIXERSETTINGS_MIXER1VECTOR_YAW]) * desired->Yaw)) / 128.0f;
// note: no feedforward for reversable motors yet for safety reasons
if (mixer->type == MIXERSETTINGS_MIXER1TYPE_MOTOR) {
if (!multirotor) { // we allow negative throttle with a multirotor
if (result < 0.0f) { // zero throttle
result = 0.0f;
}
}
if (!fixedwing) {
// feed forward, do not apply to fixedwing
float accumulator = filterAccumulator[index];
accumulator += (result - lastResult[index]) * mixerSettings.FeedForward;
lastResult[index] = result;
result += accumulator;
if (period > 0.0f) {
if (accumulator > 0.0f) {
float invFilter = period / mixerSettings.AccelTime;
if (invFilter > 1) {
invFilter = 1;
}
accumulator -= accumulator * invFilter;
} else {
float invFilter = period / mixerSettings.DecelTime;
if (invFilter > 1) {
invFilter = 1;
}
accumulator -= accumulator * invFilter;
}
}
filterAccumulator[index] = accumulator;
result += accumulator;
// acceleration limit
float dt = result - lastFilteredResult[index];
float maxDt = mixerSettings.MaxAccel * period;
if (dt > maxDt) { // we are accelerating too hard
result = lastFilteredResult[index] + maxDt;
}
lastFilteredResult[index] = result;
}
}
return result;

View File

@ -163,13 +163,13 @@
#define CPULOAD_LIMIT_CRITICAL 95
/* Task stack sizes */
#define PIOS_ACTUATOR_STACK_SIZE 820
#define PIOS_ACTUATOR_STACK_SIZE 700
#define PIOS_MANUAL_STACK_SIZE 735
#define PIOS_RECEIVER_STACK_SIZE 620
#define PIOS_STABILIZATION_STACK_SIZE 400
#ifdef DIAG_TASKS
#define PIOS_SYSTEM_STACK_SIZE 740
#define PIOS_SYSTEM_STACK_SIZE 760
#else
#define PIOS_SYSTEM_STACK_SIZE 660
#endif

View File

@ -128,6 +128,12 @@
</item>
<item>
<widget class="QFrame" name="vehicleTypeFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
@ -148,700 +154,30 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<widget class="QStackedWidget" name="airframesWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<kerning>true</kerning>
</font>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
<widget class="QWidget" name="mixerSettingsPage">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<attribute name="title">
<string>Mixer Settings</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item>
<widget class="QScrollArea" name="airframesScrollArea">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>232</red>
<green>232</green>
<blue>232</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>232</red>
<green>232</green>
<blue>232</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>232</red>
<green>232</green>
<blue>232</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>232</red>
<green>232</green>
<blue>232</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>820</width>
<height>435</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QStackedWidget" name="airframesWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="feedForwardPage">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<attribute name="title">
<string>Feed Forward</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_25">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="scrollArea_2">
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>232</red>
<green>232</green>
<blue>232</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>232</red>
<green>232</green>
<blue>232</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>232</red>
<green>232</green>
<blue>232</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>232</red>
<green>232</green>
<blue>232</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>293</width>
<height>300</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_18">
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox_12">
<property name="title">
<string>Feed Forward Configuration</string>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>12</number>
</property>
<item row="2" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QLabel" name="label_22">
<property name="text">
<string>Decel Time Constant</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="decelTime">
<property name="enabled">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>When tuning: Slowly raise decel time from zero to just
under the level where the motor starts to undershoot
its target speed when decelerating.
Do it after accel time is setup.</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_12">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QLabel" name="label_21">
<property name="text">
<string>Accel Time Constant</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="accelTime">
<property name="enabled">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>In miliseconds.
When tuning: Slowly raise accel time from zero to just
under the level where the motor starts to overshoot
its target speed.</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_13">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="1">
<widget class="QLabel" name="maxAccelSliderValue">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16</height>
</size>
</property>
<property name="text">
<string>1000</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSlider" name="feedForwardSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Overall level of feed forward (in percentage).</string>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSlider" name="maxAccelSlider">
<property name="minimumSize">
<size>
<width>0</width>
<height>32</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>Limits how much the engines can accelerate or decelerate.
In 'units per second', a sound default is 1000.</string>
</property>
<property name="minimum">
<number>500</number>
</property>
<property name="maximum">
<number>2000</number>
</property>
<property name="value">
<number>1000</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_37">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16</height>
</size>
</property>
<property name="text">
<string>MaxAccel</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="feedForwardSliderValue">
<property name="minimumSize">
<size>
<width>30</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>000</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_20">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>FeedForward </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox_13">
<property name="title">
<string/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>267</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="ffTestBox1">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;Beware! Check &lt;/span&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt; font-weight:600;&quot;&gt;all three&lt;/span&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt; checkboxes to test Feed Forward.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;It will run only if your airframe armed.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ffTestBox2">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;Beware! Check &lt;/span&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt; font-weight:600;&quot;&gt;all three&lt;/span&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt; checkboxes to test Feed Forward.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;It will run only if your airframe armed.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ffTestBox3">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;Beware! Check &lt;/span&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt; font-weight:600;&quot;&gt;all three&lt;/span&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt; checkboxes to test Feed Forward.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;It will run only if your airframe armed.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Enable FF tuning</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>267</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QTextBrowser" name="textBrowser">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;table border=&quot;0&quot; style=&quot;-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;&quot;&gt;
&lt;tr&gt;
&lt;td style=&quot;border: none;&quot;&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:14pt; font-weight:600; color:#ff0000;&quot;&gt;SETTING UP FEED FORWARD REQUIRES CAUTION&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;Beware: Feed Forward Tuning will launch all engines around mid-throttle, you have been warned!&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;Remove your props initially, and for fine-tuning, make sure your airframe is safely held in place. Wear glasses and protect your face and body.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
@ -951,56 +287,12 @@ p, li { white-space: pre-wrap; }
<tabstops>
<tabstop>nameEdit</tabstop>
<tabstop>vehicleSetupWizardButton</tabstop>
<tabstop>airframesScrollArea</tabstop>
<tabstop>scrollArea_2</tabstop>
<tabstop>decelTime</tabstop>
<tabstop>accelTime</tabstop>
<tabstop>feedForwardSlider</tabstop>
<tabstop>maxAccelSlider</tabstop>
<tabstop>ffTestBox1</tabstop>
<tabstop>ffTestBox2</tabstop>
<tabstop>ffTestBox3</tabstop>
<tabstop>textBrowser</tabstop>
<tabstop>airframeHelp</tabstop>
<tabstop>saveAircraftToRAM</tabstop>
<tabstop>saveAircraftToSD</tabstop>
<tabstop>tabWidget</tabstop>
</tabstops>
<resources>
<include location="../coreplugin/core.qrc"/>
</resources>
<connections>
<connection>
<sender>feedForwardSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>feedForwardSliderValue</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>103</y>
</hint>
<hint type="destinationlabel">
<x>146</x>
<y>107</y>
</hint>
</hints>
</connection>
<connection>
<sender>maxAccelSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>maxAccelSliderValue</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>272</x>
<y>214</y>
</hint>
<hint type="destinationlabel">
<x>127</x>
<y>214</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>

View File

@ -310,9 +310,6 @@ QString ConfigFixedWingWidget::updateConfigObjectsFromWidgets()
Q_ASSERT(mixer);
// Remove Feed Forward, it is pointless on a plane:
setMixerValue(mixer, "FeedForward", 0.0);
// Set the throttle curve
setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->fixedWingThrottle->getCurve());

View File

@ -2,6 +2,7 @@
******************************************************************************
*
* @file configgroundvehiclemwidget.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @author K. Sebesta & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
@ -353,9 +354,6 @@ QString ConfigGroundVehicleWidget::updateConfigObjectsFromWidgets()
// Save the curve (common to all ground vehicle frames)
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
// Remove Feed Forward, it is pointless on a ground vehicle:
setMixerValue(mixer, "FeedForward", 0.0);
// set the throttle curves
setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE1, m_aircraft->groundVehicleThrottle1->getCurve());
setThrottleCurve(mixer, VehicleConfig::MIXER_THROTTLECURVE2, m_aircraft->groundVehicleThrottle2->getCurve());

View File

@ -135,9 +135,6 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
addUAVObject("MixerSettings");
addUAVObject("ActuatorSettings");
m_ffTuningInProgress = false;
m_ffTuningPhase = false;
// The order of the tabs is important since they correspond with the AirframCategory enum
m_aircraft->aircraftType->addTab(tr("Multirotor"));
m_aircraft->aircraftType->addTab(tr("Fixed Wing"));
@ -148,24 +145,11 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
// Connect aircraft type selection dropbox to callback function
connect(m_aircraft->aircraftType, SIGNAL(currentChanged(int)), this, SLOT(switchAirframeType(int)));
// Connect the three feed forward test checkboxes
connect(m_aircraft->ffTestBox1, SIGNAL(clicked(bool)), this, SLOT(enableFFTest()));
connect(m_aircraft->ffTestBox2, SIGNAL(clicked(bool)), this, SLOT(enableFFTest()));
connect(m_aircraft->ffTestBox3, SIGNAL(clicked(bool)), this, SLOT(enableFFTest()));
// Connect the help pushbutton
connect(m_aircraft->airframeHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
refreshWidgetsValues();
// register FF widgets for dirty state management
addWidget(m_aircraft->feedForwardSlider);
addWidget(m_aircraft->accelTime);
addWidget(m_aircraft->decelTime);
addWidget(m_aircraft->maxAccelSlider);
addWidget(m_aircraft->ffTestBox1);
addWidget(m_aircraft->ffTestBox2);
addWidget(m_aircraft->ffTestBox3);
addWidget(m_aircraft->nameEdit);
disableMouseWheelEvents();
@ -183,7 +167,6 @@ ConfigVehicleTypeWidget::~ConfigVehicleTypeWidget()
void ConfigVehicleTypeWidget::switchAirframeType(int index)
{
m_aircraft->airframesWidget->setCurrentWidget(getVehicleConfigWidget(index));
m_aircraft->tabWidget->setTabEnabled(1, index != 1);
}
/**
@ -247,7 +230,6 @@ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *object)
}
m_aircraft->nameEdit->setText(name);
updateFeedForwardUI();
setDirty(dirty);
}
@ -281,17 +263,6 @@ void ConfigVehicleTypeWidget::updateObjectsFromWidgets()
field->setValue(airframeType);
}
// Update feed forward settings
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(mixer);
QPointer<VehicleConfig> vconfig = new VehicleConfig();
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());
field = system->getField(QString("VehicleName"));
Q_ASSERT(field);
QString name = m_aircraft->nameEdit->text();
@ -306,7 +277,6 @@ void ConfigVehicleTypeWidget::updateObjectsFromWidgets()
// call refreshWidgetsValues() to reflect actual saved values
refreshWidgetsValues();
ConfigTaskWidget::updateObjectsFromWidgets();
updateFeedForwardUI();
}
int ConfigVehicleTypeWidget::frameCategory(QString frameType)
@ -372,86 +342,6 @@ VehicleConfig *ConfigVehicleTypeWidget::createVehicleConfigWidget(int frameCateg
return NULL;
}
/**
Enables and runs feed forward testing
*/
void ConfigVehicleTypeWidget::enableFFTest()
{
// Role:
// - Check if all three checkboxes are checked
// - Every other timer event: toggle engine from 45% to 55%
// - Every other time event: send FF settings to flight FW
if (m_aircraft->ffTestBox1->isChecked() && m_aircraft->ffTestBox2->isChecked()
&& m_aircraft->ffTestBox3->isChecked()) {
if (!m_ffTuningInProgress) {
// Initiate tuning:
UAVDataObject *obj = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(
QString("ManualControlCommand")));
UAVObject::Metadata mdata = obj->getMetadata();
m_accInitialData = mdata;
UAVObject::SetFlightAccess(mdata, UAVObject::ACCESS_READONLY);
obj->setMetadata(mdata);
}
// Depending on phase, either move actuator or send FF settings:
if (m_ffTuningPhase) {
// Send FF settings to the board
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")));
double value = obj->getField("Throttle")->getDouble();
double target = (value < 0.5) ? 0.55 : 0.45;
obj->getField("Throttle")->setValue(target);
obj->updated();
}
m_ffTuningPhase = !m_ffTuningPhase;
m_ffTuningInProgress = true;
QTimer::singleShot(1000, this, SLOT(enableFFTest()));
} else {
// - If no: disarm timer, restore actuatorcommand metadata
// Disarm!
if (m_ffTuningInProgress) {
m_ffTuningInProgress = false;
UAVDataObject *obj = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(
QString("ManualControlCommand")));
UAVObject::Metadata mdata = obj->getMetadata();
mdata = m_accInitialData; // Restore metadata
obj->setMetadata(mdata);
}
}
}
/**
Updates the custom airframe settings based on the current airframe.
Note: does NOT ask for an object refresh itself!
*/
void ConfigVehicleTypeWidget::updateFeedForwardUI()
{
UAVDataObject *mixer = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(mixer);
QPointer<VehicleConfig> vconfig = new VehicleConfig();
// 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"));
}
/**
Opens the wiki from the user's default browser
*/

View File

@ -2,6 +2,7 @@
******************************************************************************
*
* @file configairframetwidget.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup GCSPlugins GCS Plugins
* @{
@ -86,17 +87,9 @@ private:
VehicleConfig *getVehicleConfigWidget(int frameCategory);
VehicleConfig *createVehicleConfigWidget(int frameCategory);
// Feed Forward
void updateFeedForwardUI();
bool m_ffTuningInProgress;
bool m_ffTuningPhase;
UAVObject::Metadata m_accInitialData;
private slots:
void switchAirframeType(int index);
void openHelp();
void enableFFTest();
};
#endif // CONFIGVEHICLETYPEWIDGET_H

View File

@ -2,6 +2,7 @@
******************************************************************************
*
* @file vehicleconfigurationhelper.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup
* @{
@ -1013,12 +1014,6 @@ void VehicleConfigurationHelper::resetVehicleConfig()
// Reset all vehicle data
MixerSettings *mSettings = MixerSettings::GetInstance(m_uavoManager);
// Reset feed forward, accel times etc
mSettings->setFeedForward(0.0f);
mSettings->setMaxAccel(1000.0f);
mSettings->setAccelTime(0.0f);
mSettings->setDecelTime(0.0f);
// Reset throttle curves
QString throttlePattern = "ThrottleCurve%1";
for (int i = 1; i <= 2; i++) {

View File

@ -1,16 +1,12 @@
<xml>
<object name="MixerSettings" singleinstance="true" settings="true" category="Control">
<description>Settings for the @ref ActuatorModule that controls the channel assignments for the mixer based on AircraftType</description>
<field name="MaxAccel" units="units/sec" type="float" elements="1" defaultvalue="1000"/>
<field name="MixerValueRoll" units="percent" type="int8" elements="1" defaultvalue="50"/>
<field name="MixerValueRoll" units="percent" type="int8" elements="1" defaultvalue="50"/>
<field name="MixerValuePitch" units="percent" type="int8" elements="1" defaultvalue="50"/>
<field name="MixerValueYaw" units="percent" type="int8" elements="1" defaultvalue="50"/>
<field name="RollDifferential" units="percent" type="int8" elements="1" defaultvalue="0"/>
<field name="FirstRollServo" units="" type="uint8" elements="1" defaultvalue="0"/>
<field name="FeedForward" units="" type="float" elements="1" defaultvalue="0"/>
<field name="AccelTime" units="ms" type="float" elements="1" defaultvalue="0"/>
<field name="DecelTime" units="ms" type="float" elements="1" defaultvalue="0"/>
<field name="ThrottleCurve1" units="percent" type="float" elementnames="0,25,50,75,100" defaultvalue="0,0,0,0,0"/>
<field name="FirstRollServo" units="" type="uint8" elements="1" defaultvalue="0"/>
<field name="ThrottleCurve1" units="percent" type="float" elementnames="0,25,50,75,100" defaultvalue="0,0,0,0,0"/>
<field name="Curve2Source" units="" type="enum" elements="1" defaultvalue="Throttle">
<options>
<option>Throttle</option>
@ -83,10 +79,10 @@
<field name="Mixer11Type" cloneof="Mixer1Type"/>
<field name="Mixer11Vector" cloneof="Mixer1Vector"/>
<field name="Mixer12Type" cloneof="Mixer1Type"/>
<field name="Mixer12Vector" cloneof="Mixer1Vector"/>
<access gcs="readwrite" flight="readwrite"/>
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
<telemetryflight acked="true" updatemode="onchange" period="0"/>