mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-18 08:54:15 +01:00
Merge remote-tracking branch 'origin/os/features/advanced-camera-stabilization' into next
This commit is contained in:
commit
1b6ff0e470
@ -1,5 +1,8 @@
|
||||
Short summary of changes. For a complete list see the git log.
|
||||
|
||||
2012-01-02
|
||||
Added new camera stabilization features: AxisLock mode and LPF.
|
||||
|
||||
2011-12-10
|
||||
Merged a change that sorts the UAVO fields based on size. Because this changes
|
||||
all of the objects, erase all existing flash files based on this.
|
||||
|
@ -61,10 +61,15 @@
|
||||
// Private types
|
||||
|
||||
// Private variables
|
||||
static struct CameraStab_data {
|
||||
portTickType lastSysTime;
|
||||
float inputs[CAMERASTABSETTINGS_INPUT_NUMELEM];
|
||||
float inputs_filtered[CAMERASTABSETTINGS_INPUT_NUMELEM];
|
||||
} *csd;
|
||||
|
||||
// Private functions
|
||||
static void attitudeUpdated(UAVObjEvent* ev);
|
||||
static float bound(float val);
|
||||
static float bound(float val, float limit);
|
||||
|
||||
/**
|
||||
* Initialise the module, called on startup
|
||||
@ -72,8 +77,6 @@ static float bound(float val);
|
||||
*/
|
||||
int32_t CameraStabInitialize(void)
|
||||
{
|
||||
static UAVObjEvent ev;
|
||||
|
||||
bool cameraStabEnabled;
|
||||
uint8_t optionalModules[HWSETTINGS_OPTIONALMODULES_NUMELEM];
|
||||
|
||||
@ -87,15 +90,24 @@ int32_t CameraStabInitialize(void)
|
||||
|
||||
if (cameraStabEnabled) {
|
||||
|
||||
// allocate and initialize the static data storage only if module is enabled
|
||||
csd = (struct CameraStab_data *) pvPortMalloc(sizeof(struct CameraStab_data));
|
||||
if (!csd)
|
||||
return -1;
|
||||
|
||||
// make sure that all inputs[] and inputs_filtered[] are zeroed
|
||||
memset(csd, 0, sizeof(struct CameraStab_data));
|
||||
csd->lastSysTime = xTaskGetTickCount();
|
||||
|
||||
AttitudeActualInitialize();
|
||||
|
||||
ev.obj = AttitudeActualHandle();
|
||||
ev.instId = 0;
|
||||
ev.event = 0;
|
||||
|
||||
CameraStabSettingsInitialize();
|
||||
CameraDesiredInitialize();
|
||||
|
||||
UAVObjEvent ev = {
|
||||
.obj = AttitudeActualHandle(),
|
||||
.instId = 0,
|
||||
.event = 0,
|
||||
};
|
||||
EventPeriodicCallbackCreate(&ev, attitudeUpdated, SAMPLE_PERIOD_MS / portTICK_RATE_MS);
|
||||
|
||||
return 0;
|
||||
@ -117,47 +129,68 @@ static void attitudeUpdated(UAVObjEvent* ev)
|
||||
if (ev->obj != AttitudeActualHandle())
|
||||
return;
|
||||
|
||||
float attitude;
|
||||
float output;
|
||||
AccessoryDesiredData accessory;
|
||||
|
||||
CameraStabSettingsData cameraStab;
|
||||
CameraStabSettingsGet(&cameraStab);
|
||||
|
||||
// Read any input channels
|
||||
float inputs[3] = {0,0,0};
|
||||
if(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_ROLL] != CAMERASTABSETTINGS_INPUTS_NONE) {
|
||||
if(AccessoryDesiredInstGet(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_ROLL] - CAMERASTABSETTINGS_INPUTS_ACCESSORY0, &accessory) == 0)
|
||||
inputs[0] = accessory.AccessoryVal * cameraStab.InputRange[CAMERASTABSETTINGS_INPUTRANGE_ROLL];
|
||||
}
|
||||
if(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_PITCH] != CAMERASTABSETTINGS_INPUTS_NONE) {
|
||||
if(AccessoryDesiredInstGet(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_PITCH] - CAMERASTABSETTINGS_INPUTS_ACCESSORY0, &accessory) == 0)
|
||||
inputs[1] = accessory.AccessoryVal * cameraStab.InputRange[CAMERASTABSETTINGS_INPUTRANGE_PITCH];
|
||||
}
|
||||
if(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_YAW] != CAMERASTABSETTINGS_INPUTS_NONE) {
|
||||
if(AccessoryDesiredInstGet(cameraStab.Inputs[CAMERASTABSETTINGS_INPUTS_YAW] - CAMERASTABSETTINGS_INPUTS_ACCESSORY0, &accessory) == 0)
|
||||
inputs[2] = accessory.AccessoryVal * cameraStab.InputRange[CAMERASTABSETTINGS_INPUTRANGE_YAW];
|
||||
// Check how long since last update, time delta between calls in ms
|
||||
portTickType thisSysTime = xTaskGetTickCount();
|
||||
float dT = (thisSysTime > csd->lastSysTime) ?
|
||||
(thisSysTime - csd->lastSysTime) / portTICK_RATE_MS :
|
||||
(float)SAMPLE_PERIOD_MS / 1000.0f;
|
||||
csd->lastSysTime = thisSysTime;
|
||||
|
||||
// Read any input channels and apply LPF
|
||||
for (uint8_t i = 0; i < CAMERASTABSETTINGS_INPUT_NUMELEM; i++) {
|
||||
if (cameraStab.Input[i] != CAMERASTABSETTINGS_INPUT_NONE) {
|
||||
if (AccessoryDesiredInstGet(cameraStab.Input[i] - CAMERASTABSETTINGS_INPUT_ACCESSORY0, &accessory) == 0) {
|
||||
float input_rate;
|
||||
switch (cameraStab.StabilizationMode[i]) {
|
||||
case CAMERASTABSETTINGS_STABILIZATIONMODE_ATTITUDE:
|
||||
csd->inputs[i] = accessory.AccessoryVal * cameraStab.InputRange[i];
|
||||
break;
|
||||
case CAMERASTABSETTINGS_STABILIZATIONMODE_AXISLOCK:
|
||||
input_rate = accessory.AccessoryVal * cameraStab.InputRate[i];
|
||||
if (fabs(input_rate) > cameraStab.MaxAxisLockRate)
|
||||
csd->inputs[i] = bound(csd->inputs[i] + input_rate * dT / 1000.0f, cameraStab.InputRange[i]);
|
||||
break;
|
||||
default:
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
|
||||
// bypass LPF calculation if ResponseTime is zero
|
||||
float rt = (float)cameraStab.ResponseTime[i];
|
||||
if (rt)
|
||||
csd->inputs_filtered[i] = (rt / (rt + dT)) * csd->inputs_filtered[i]
|
||||
+ (dT / (rt + dT)) * csd->inputs[i];
|
||||
else
|
||||
csd->inputs_filtered[i] = csd->inputs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set output channels
|
||||
float attitude;
|
||||
float output;
|
||||
|
||||
AttitudeActualRollGet(&attitude);
|
||||
output = bound((attitude + inputs[0]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_ROLL]);
|
||||
output = bound((attitude + csd->inputs_filtered[CAMERASTABSETTINGS_INPUT_ROLL]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_ROLL], 1.0f);
|
||||
CameraDesiredRollSet(&output);
|
||||
|
||||
AttitudeActualPitchGet(&attitude);
|
||||
output = bound((attitude + inputs[1]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_PITCH]);
|
||||
output = bound((attitude + csd->inputs_filtered[CAMERASTABSETTINGS_INPUT_PITCH]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_PITCH], 1.0f);
|
||||
CameraDesiredPitchSet(&output);
|
||||
|
||||
AttitudeActualYawGet(&attitude);
|
||||
output = bound((attitude + inputs[2]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_YAW]);
|
||||
output = bound((attitude + csd->inputs_filtered[CAMERASTABSETTINGS_INPUT_YAW]) / cameraStab.OutputRange[CAMERASTABSETTINGS_OUTPUTRANGE_YAW], 1.0f);
|
||||
CameraDesiredYawSet(&output);
|
||||
|
||||
}
|
||||
|
||||
float bound(float val)
|
||||
float bound(float val, float limit)
|
||||
{
|
||||
return (val > 1) ? 1 :
|
||||
(val < -1) ? -1 :
|
||||
return (val > limit) ? limit :
|
||||
(val < -limit) ? -limit :
|
||||
val;
|
||||
}
|
||||
/**
|
||||
|
@ -1,328 +1,740 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CameraStabilizationWidget</class>
|
||||
<widget class="QWidget" name="CameraStabilizationWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>720</width>
|
||||
<height>567</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableCameraStabilization">
|
||||
<property name="text">
|
||||
<string>Enable CameraStabilization module</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>After enabling the module, you must power cycle before using and configuring.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Channel Ranges (number of degrees full range)</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Pitch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Yaw</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Roll</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="rollOutputRange">
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="pitchOutputRange">
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="yawOutputRange">
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>212</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Channel Mapping (select output channel or none to disable)</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Roll</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="rollChannel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="yawChannel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Pitch</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="pitchChannel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Yaw</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>212</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="message">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<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>
|
||||
<layout class="QHBoxLayout" name="submitButtons">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="camerastabilizationHelp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<kerning>true</kerning>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../coreplugin/core.qrc">
|
||||
<normaloff>:/core/images/helpicon.svg</normaloff>:/core/images/helpicon.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+S</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="camerastabilizationSaveRAM">
|
||||
<property name="toolTip">
|
||||
<string>Save settings to the board (RAM only).
|
||||
|
||||
This does not save the calibration settings, this is done using the
|
||||
specific calibration button on top of the screen.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="camerastabilizationSaveSD">
|
||||
<property name="toolTip">
|
||||
<string>Send settings to the board, and save to the non-volatile memory.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../coreplugin/core.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CameraStabilizationWidget</class>
|
||||
<widget class="QWidget" name="CameraStabilizationWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>720</width>
|
||||
<height>567</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</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>702</width>
|
||||
<height>488</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="enableCameraStabilization">
|
||||
<property name="text">
|
||||
<string>Enable CameraStabilization module</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>After enabling the module, you must power cycle before using and configuring.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Basic Settings (Stabilization)</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="2" column="3">
|
||||
<widget class="QSpinBox" name="yawOutputRange">
|
||||
<property name="toolTip">
|
||||
<string>Camera yaw angle for 100% output value, deg.
|
||||
|
||||
This value should be tuned for particular gimbal and servo. You also
|
||||
have to define channel output range using Output configuration tab.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QSpinBox" name="pitchOutputRange">
|
||||
<property name="toolTip">
|
||||
<string>Camera pitch angle for 100% output value, deg.
|
||||
|
||||
This value should be tuned for particular gimbal and servo. You also
|
||||
have to define channel output range using Output configuration tab.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="rollOutputRange">
|
||||
<property name="toolTip">
|
||||
<string>Camera roll angle for 100% output value, deg.
|
||||
|
||||
This value should be tuned for particular gimbal and servo. You also
|
||||
have to define channel output range using Output configuration tab.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QComboBox" name="yawChannel">
|
||||
<property name="toolTip">
|
||||
<string>Yaw output channel for camera gimbal</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QComboBox" name="pitchChannel">
|
||||
<property name="toolTip">
|
||||
<string>Pitch output channel for camera gimbal</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="rollChannel">
|
||||
<property name="toolTip">
|
||||
<string>Roll output channel for camera gimbal</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_42">
|
||||
<property name="text">
|
||||
<string>Output Channel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_43">
|
||||
<property name="text">
|
||||
<string>Output Range</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_44">
|
||||
<property name="text">
|
||||
<string>Yaw</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_45">
|
||||
<property name="text">
|
||||
<string>Pitch</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_46">
|
||||
<property name="text">
|
||||
<string>Roll</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>204</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Advanced Settings (Control)</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_32">
|
||||
<property name="text">
|
||||
<string>Yaw</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_33">
|
||||
<property name="text">
|
||||
<string>Pitch</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_34">
|
||||
<property name="text">
|
||||
<string>Roll</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QComboBox" name="yawInputChannel">
|
||||
<property name="toolTip">
|
||||
<string>Input channel to control camera yaw
|
||||
|
||||
Don't forget to map this channel using Input configuration tab.</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QComboBox" name="pitchInputChannel">
|
||||
<property name="toolTip">
|
||||
<string>Input channel to control camera pitch
|
||||
|
||||
Don't forget to map this channel using Input configuration tab.</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="rollInputChannel">
|
||||
<property name="toolTip">
|
||||
<string>Input channel to control camera roll
|
||||
|
||||
Don't forget to map this channel using Input configuration tab.</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_35">
|
||||
<property name="text">
|
||||
<string>Input Channel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QComboBox" name="yawStabilizationMode">
|
||||
<property name="toolTip">
|
||||
<string>Axis stabilization mode
|
||||
|
||||
Attitude: camera tracks level for the axis. Input controls the deflection.
|
||||
AxisLock: camera remembers tracking attitude. Input controls the rate of deflection.</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Attitude</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QSpinBox" name="yawInputRange">
|
||||
<property name="toolTip">
|
||||
<string>Maximum camera yaw deflection for 100% input in Attitude mode, deg.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QSpinBox" name="yawInputRate">
|
||||
<property name="toolTip">
|
||||
<string>Maximum camera yaw rate for 100% input in AxisLock mode, deg/s.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QSpinBox" name="yawResponseTime">
|
||||
<property name="toolTip">
|
||||
<string>Input low-pass filter response time for yaw axis, ms.
|
||||
|
||||
This option smoothes the stick input. Zero value disables LPF.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>150</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QComboBox" name="pitchStabilizationMode">
|
||||
<property name="toolTip">
|
||||
<string>Axis stabilization mode
|
||||
|
||||
Attitude: camera tracks level for the axis. Input controls the deflection.
|
||||
AxisLock: camera remembers tracking attitude. Input controls the rate of deflection.</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Attitude</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QSpinBox" name="pitchInputRange">
|
||||
<property name="toolTip">
|
||||
<string>Maximum camera pitch deflection for 100% input in Attitude mode, deg.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QSpinBox" name="pitchInputRate">
|
||||
<property name="toolTip">
|
||||
<string>Maximum camera pitch rate for 100% input in AxisLock mode, deg/s.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QSpinBox" name="pitchResponseTime">
|
||||
<property name="toolTip">
|
||||
<string>Input low-pass filter response time for pitch axis, ms.
|
||||
|
||||
This option smoothes the stick input. Zero value disables LPF.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>150</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="rollStabilizationMode">
|
||||
<property name="toolTip">
|
||||
<string>Axis stabilization mode
|
||||
|
||||
Attitude: camera tracks level for the axis. Input controls the deflection.
|
||||
AxisLock: camera remembers tracking attitude. Input controls the rate of deflection.</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Attitude</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="rollInputRange">
|
||||
<property name="toolTip">
|
||||
<string>Maximum camera roll deflection for 100% input in Attitude mode, deg.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>20</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="rollInputRate">
|
||||
<property name="toolTip">
|
||||
<string>Maximum camera roll rate for 100% input in AxisLock mode, deg/s.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>180</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="rollResponseTime">
|
||||
<property name="toolTip">
|
||||
<string>Input low-pass filter response time for roll axis, ms.
|
||||
|
||||
This option smoothes the stick input. Zero value disables LPF.</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>150</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_36">
|
||||
<property name="text">
|
||||
<string>MaxAxisLockRate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_37">
|
||||
<property name="text">
|
||||
<string>Response Time</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_38">
|
||||
<property name="text">
|
||||
<string>Input Rate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_39">
|
||||
<property name="text">
|
||||
<string>Input Range</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_40">
|
||||
<property name="text">
|
||||
<string>Stabilization Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2" colspan="2">
|
||||
<widget class="QLabel" name="label_41">
|
||||
<property name="text">
|
||||
<string>(the same value for Roll, Pitch, Yaw)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QDoubleSpinBox" name="MaxAxisLockRate">
|
||||
<property name="toolTip">
|
||||
<string>Stick input deadband for all axes in AxisLock mode, deg/s.
|
||||
|
||||
When stick input is within the MaxAxisLockRate range, camera tracks
|
||||
current attitude. Otherwise it starts moving according to input with
|
||||
rate depending on input value.
|
||||
|
||||
If you have drift in your Tx controls, you may want to increase this
|
||||
value.</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="message">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="submitButtons">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="camerastabilizationHelp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<kerning>true</kerning>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../coreplugin/core.qrc">
|
||||
<normaloff>:/core/images/helpicon.svg</normaloff>:/core/images/helpicon.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+S</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="camerastabilizationResetToDefaults">
|
||||
<property name="toolTip">
|
||||
<string>Load default CameraStabilization settings except output channels
|
||||
|
||||
Loaded settings are not applied automatically. You have to click the
|
||||
Apply or Save button afterwards.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reset To Defaults</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="camerastabilizationSaveRAM">
|
||||
<property name="toolTip">
|
||||
<string>Send settings to the board but do not save to the non-volatile memory</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Apply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="camerastabilizationSaveSD">
|
||||
<property name="toolTip">
|
||||
<string>Send settings to the board and save to the non-volatile memory</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>enableCameraStabilization</tabstop>
|
||||
<tabstop>rollChannel</tabstop>
|
||||
<tabstop>pitchChannel</tabstop>
|
||||
<tabstop>yawChannel</tabstop>
|
||||
<tabstop>rollOutputRange</tabstop>
|
||||
<tabstop>pitchOutputRange</tabstop>
|
||||
<tabstop>yawOutputRange</tabstop>
|
||||
<tabstop>rollInputChannel</tabstop>
|
||||
<tabstop>pitchInputChannel</tabstop>
|
||||
<tabstop>yawInputChannel</tabstop>
|
||||
<tabstop>rollStabilizationMode</tabstop>
|
||||
<tabstop>pitchStabilizationMode</tabstop>
|
||||
<tabstop>yawStabilizationMode</tabstop>
|
||||
<tabstop>rollInputRange</tabstop>
|
||||
<tabstop>pitchInputRange</tabstop>
|
||||
<tabstop>yawInputRange</tabstop>
|
||||
<tabstop>rollInputRate</tabstop>
|
||||
<tabstop>pitchInputRate</tabstop>
|
||||
<tabstop>yawInputRate</tabstop>
|
||||
<tabstop>rollResponseTime</tabstop>
|
||||
<tabstop>pitchResponseTime</tabstop>
|
||||
<tabstop>yawResponseTime</tabstop>
|
||||
<tabstop>MaxAxisLockRate</tabstop>
|
||||
<tabstop>camerastabilizationHelp</tabstop>
|
||||
<tabstop>camerastabilizationResetToDefaults</tabstop>
|
||||
<tabstop>camerastabilizationSaveRAM</tabstop>
|
||||
<tabstop>camerastabilizationSaveSD</tabstop>
|
||||
<tabstop>scrollArea</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../coreplugin/core.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -2,7 +2,7 @@
|
||||
******************************************************************************
|
||||
*
|
||||
* @file configcamerastabilizationwidget.cpp
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup ConfigPlugin Config Plugin
|
||||
@ -25,47 +25,69 @@
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "configcamerastabilizationwidget.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QStringList>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QTextEdit>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QPushButton>
|
||||
#include <QThread>
|
||||
#include <iostream>
|
||||
#include <QUrl>
|
||||
#include <QDesktopServices>
|
||||
|
||||
#include "camerastabsettings.h"
|
||||
#include "hwsettings.h"
|
||||
#include "mixersettings.h"
|
||||
#include "actuatorcommand.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
#include <QUrl>
|
||||
|
||||
ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget *parent) : ConfigTaskWidget(parent)
|
||||
{
|
||||
// TODO: this widget should use the addUAVObjectToWidgetRelation()
|
||||
m_camerastabilization = new Ui_CameraStabilizationWidget();
|
||||
m_camerastabilization->setupUi(this);
|
||||
|
||||
QComboBox * selectors[3] = {
|
||||
QComboBox *outputs[3] = {
|
||||
m_camerastabilization->rollChannel,
|
||||
m_camerastabilization->pitchChannel,
|
||||
m_camerastabilization->yawChannel
|
||||
m_camerastabilization->yawChannel,
|
||||
};
|
||||
|
||||
QComboBox *inputs[3] = {
|
||||
m_camerastabilization->rollInputChannel,
|
||||
m_camerastabilization->pitchInputChannel,
|
||||
m_camerastabilization->yawInputChannel,
|
||||
};
|
||||
|
||||
QComboBox *stabilizationMode[3] = {
|
||||
m_camerastabilization->rollStabilizationMode,
|
||||
m_camerastabilization->pitchStabilizationMode,
|
||||
m_camerastabilization->yawStabilizationMode,
|
||||
};
|
||||
|
||||
CameraStabSettings *cameraStab = CameraStabSettings::GetInstance(getObjectManager());
|
||||
CameraStabSettings::DataFields cameraStabData = cameraStab->getData();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
selectors[i]->clear();
|
||||
selectors[i]->addItem("None");
|
||||
for (int j = 0; j < ActuatorCommand::CHANNEL_NUMELEM; j++)
|
||||
selectors[i]->addItem(QString("Channel %1").arg(j+1));
|
||||
outputs[i]->clear();
|
||||
outputs[i]->addItem("None");
|
||||
for (quint32 j = 0; j < ActuatorCommand::CHANNEL_NUMELEM; j++)
|
||||
outputs[i]->addItem(QString("Channel %1").arg(j+1));
|
||||
|
||||
UAVObjectField *field;
|
||||
|
||||
field = cameraStab->getField("Input");
|
||||
Q_ASSERT(field);
|
||||
inputs[i]->clear();
|
||||
inputs[i]->addItems(field->getOptions());
|
||||
inputs[i]->setCurrentIndex(cameraStabData.Input[i]);
|
||||
|
||||
field = cameraStab->getField("StabilizationMode");
|
||||
Q_ASSERT(field);
|
||||
stabilizationMode[i]->clear();
|
||||
stabilizationMode[i]->addItems(field->getOptions());
|
||||
stabilizationMode[i]->setCurrentIndex(cameraStabData.StabilizationMode[i]);
|
||||
}
|
||||
|
||||
connectUpdates();
|
||||
|
||||
// Connect buttons
|
||||
connect(m_camerastabilization->camerastabilizationSaveRAM,SIGNAL(clicked()),this,SLOT(applySettings()));
|
||||
connect(m_camerastabilization->camerastabilizationSaveSD,SIGNAL(clicked()),this,SLOT(saveSettings()));
|
||||
connect(m_camerastabilization->camerastabilizationResetToDefaults, SIGNAL(clicked()), this, SLOT(resetToDefaults()));
|
||||
connect(m_camerastabilization->camerastabilizationSaveRAM, SIGNAL(clicked()), this, SLOT(applySettings()));
|
||||
connect(m_camerastabilization->camerastabilizationSaveSD, SIGNAL(clicked()), this, SLOT(saveSettings()));
|
||||
connect(m_camerastabilization->camerastabilizationHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
|
||||
}
|
||||
|
||||
@ -77,19 +99,19 @@ ConfigCameraStabilizationWidget::~ConfigCameraStabilizationWidget()
|
||||
void ConfigCameraStabilizationWidget::connectUpdates()
|
||||
{
|
||||
// Now connect the widget to the StabilizationSettings object
|
||||
connect(MixerSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
connect(CameraStabSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
connect(MixerSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
|
||||
connect(CameraStabSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
|
||||
// TODO: This will need to support both CC and OP later
|
||||
connect(HwSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
connect(HwSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
|
||||
}
|
||||
|
||||
void ConfigCameraStabilizationWidget::disconnectUpdates()
|
||||
{
|
||||
// Now connect the widget to the StabilizationSettings object
|
||||
disconnect(MixerSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
disconnect(CameraStabSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
disconnect(MixerSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
|
||||
disconnect(CameraStabSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
|
||||
// TODO: This will need to support both CC and OP later
|
||||
disconnect(HwSettings::GetInstance(getObjectManager()),SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
|
||||
disconnect(HwSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,7 +121,7 @@ void ConfigCameraStabilizationWidget::disconnectUpdates()
|
||||
void ConfigCameraStabilizationWidget::applySettings()
|
||||
{
|
||||
// Enable or disable the settings
|
||||
HwSettings * hwSettings = HwSettings::GetInstance(getObjectManager());
|
||||
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
|
||||
HwSettings::DataFields hwSettingsData = hwSettings->getData();
|
||||
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] =
|
||||
m_camerastabilization->enableCameraStabilization->isChecked() ?
|
||||
@ -107,14 +129,14 @@ void ConfigCameraStabilizationWidget::applySettings()
|
||||
HwSettings::OPTIONALMODULES_DISABLED;
|
||||
|
||||
// Update the mixer settings
|
||||
MixerSettings * mixerSettings = MixerSettings::GetInstance(getObjectManager());
|
||||
MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager());
|
||||
MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
|
||||
const int NUM_MIXERS = 10;
|
||||
|
||||
QComboBox * selectors[3] = {
|
||||
QComboBox *outputs[3] = {
|
||||
m_camerastabilization->rollChannel,
|
||||
m_camerastabilization->pitchChannel,
|
||||
m_camerastabilization->yawChannel
|
||||
m_camerastabilization->yawChannel,
|
||||
};
|
||||
|
||||
// TODO: Need to reformat object so types are an
|
||||
@ -136,14 +158,14 @@ void ConfigCameraStabilizationWidget::applySettings()
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
// Channel 1 is second entry, so becomes zero
|
||||
int mixerNum = selectors[i]->currentIndex() - 1;
|
||||
int mixerNum = outputs[i]->currentIndex() - 1;
|
||||
|
||||
if ( mixerNum >= 0 && // Short circuit in case of none
|
||||
*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_DISABLED &&
|
||||
(*mixerTypes[mixerNum] != MixerSettings::MIXER1TYPE_CAMERAROLL + i) ) {
|
||||
// If the mixer channel already to something that isn't what we are
|
||||
// about to set it to reset to none
|
||||
selectors[i]->setCurrentIndex(0);
|
||||
outputs[i]->setCurrentIndex(0);
|
||||
m_camerastabilization->message->setText("One of the channels is already assigned, reverted to none");
|
||||
} else {
|
||||
// Make sure no other channels have this output set
|
||||
@ -158,13 +180,36 @@ void ConfigCameraStabilizationWidget::applySettings()
|
||||
}
|
||||
}
|
||||
|
||||
// Update the ranges
|
||||
CameraStabSettings * cameraStab = CameraStabSettings::GetInstance(getObjectManager());
|
||||
// Update the settings
|
||||
CameraStabSettings *cameraStab = CameraStabSettings::GetInstance(getObjectManager());
|
||||
CameraStabSettings::DataFields cameraStabData = cameraStab->getData();
|
||||
|
||||
cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_ROLL] = m_camerastabilization->rollOutputRange->value();
|
||||
cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_PITCH] = m_camerastabilization->pitchOutputRange->value();
|
||||
cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_YAW] = m_camerastabilization->yawOutputRange->value();
|
||||
|
||||
cameraStabData.Input[CameraStabSettings::INPUT_ROLL] = m_camerastabilization->rollInputChannel->currentIndex();
|
||||
cameraStabData.Input[CameraStabSettings::INPUT_PITCH] = m_camerastabilization->pitchInputChannel->currentIndex();
|
||||
cameraStabData.Input[CameraStabSettings::INPUT_YAW] = m_camerastabilization->yawInputChannel->currentIndex();
|
||||
|
||||
cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_ROLL] = m_camerastabilization->rollStabilizationMode->currentIndex();
|
||||
cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_PITCH] = m_camerastabilization->pitchStabilizationMode->currentIndex();
|
||||
cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_YAW] = m_camerastabilization->yawStabilizationMode->currentIndex();
|
||||
|
||||
cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_ROLL] = m_camerastabilization->rollInputRange->value();
|
||||
cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_PITCH] = m_camerastabilization->pitchInputRange->value();
|
||||
cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_YAW] = m_camerastabilization->yawInputRange->value();
|
||||
|
||||
cameraStabData.InputRate[CameraStabSettings::INPUTRATE_ROLL] = m_camerastabilization->rollInputRate->value();
|
||||
cameraStabData.InputRate[CameraStabSettings::INPUTRATE_PITCH] = m_camerastabilization->pitchInputRate->value();
|
||||
cameraStabData.InputRate[CameraStabSettings::INPUTRATE_YAW] = m_camerastabilization->yawInputRate->value();
|
||||
|
||||
cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_ROLL] = m_camerastabilization->rollResponseTime->value();
|
||||
cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_PITCH] = m_camerastabilization->pitchResponseTime->value();
|
||||
cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_YAW] = m_camerastabilization->yawResponseTime->value();
|
||||
|
||||
cameraStabData.MaxAxisLockRate = m_camerastabilization->MaxAxisLockRate->value();
|
||||
|
||||
// Because multiple objects are updated, and all of them trigger the callback
|
||||
// they must be done together (if update one then load settings from second
|
||||
// the first update would wipe the UI controls). However to be extra cautious
|
||||
@ -182,7 +227,7 @@ void ConfigCameraStabilizationWidget::applySettings()
|
||||
void ConfigCameraStabilizationWidget::saveSettings()
|
||||
{
|
||||
applySettings();
|
||||
UAVObject * obj = HwSettings::GetInstance(getObjectManager());
|
||||
UAVObject *obj = HwSettings::GetInstance(getObjectManager());
|
||||
saveObjectToSD(obj);
|
||||
obj = MixerSettings::GetInstance(getObjectManager());
|
||||
saveObjectToSD(obj);
|
||||
@ -190,24 +235,56 @@ void ConfigCameraStabilizationWidget::saveSettings()
|
||||
saveObjectToSD(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh UI with new settings of CameraStabSettings object
|
||||
* (either from active configuration or just loaded defaults
|
||||
* to be applied or saved)
|
||||
*/
|
||||
void ConfigCameraStabilizationWidget::refreshUIValues(CameraStabSettings::DataFields &cameraStabData)
|
||||
{
|
||||
m_camerastabilization->rollOutputRange->setValue(cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_ROLL]);
|
||||
m_camerastabilization->pitchOutputRange->setValue(cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_PITCH]);
|
||||
m_camerastabilization->yawOutputRange->setValue(cameraStabData.OutputRange[CameraStabSettings::OUTPUTRANGE_YAW]);
|
||||
|
||||
m_camerastabilization->rollInputChannel->setCurrentIndex(cameraStabData.Input[CameraStabSettings::INPUT_ROLL]);
|
||||
m_camerastabilization->pitchInputChannel->setCurrentIndex(cameraStabData.Input[CameraStabSettings::INPUT_PITCH]);
|
||||
m_camerastabilization->yawInputChannel->setCurrentIndex(cameraStabData.Input[CameraStabSettings::INPUT_YAW]);
|
||||
|
||||
m_camerastabilization->rollStabilizationMode->setCurrentIndex(cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_ROLL]);
|
||||
m_camerastabilization->pitchStabilizationMode->setCurrentIndex(cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_PITCH]);
|
||||
m_camerastabilization->yawStabilizationMode->setCurrentIndex(cameraStabData.StabilizationMode[CameraStabSettings::STABILIZATIONMODE_YAW]);
|
||||
|
||||
m_camerastabilization->rollInputRange->setValue(cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_ROLL]);
|
||||
m_camerastabilization->pitchInputRange->setValue(cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_PITCH]);
|
||||
m_camerastabilization->yawInputRange->setValue(cameraStabData.InputRange[CameraStabSettings::INPUTRANGE_YAW]);
|
||||
|
||||
m_camerastabilization->rollInputRate->setValue(cameraStabData.InputRate[CameraStabSettings::INPUTRATE_ROLL]);
|
||||
m_camerastabilization->pitchInputRate->setValue(cameraStabData.InputRate[CameraStabSettings::INPUTRATE_PITCH]);
|
||||
m_camerastabilization->yawInputRate->setValue(cameraStabData.InputRate[CameraStabSettings::INPUTRATE_YAW]);
|
||||
|
||||
m_camerastabilization->rollResponseTime->setValue(cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_ROLL]);
|
||||
m_camerastabilization->pitchResponseTime->setValue(cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_PITCH]);
|
||||
m_camerastabilization->yawResponseTime->setValue(cameraStabData.ResponseTime[CameraStabSettings::RESPONSETIME_YAW]);
|
||||
|
||||
m_camerastabilization->MaxAxisLockRate->setValue(cameraStabData.MaxAxisLockRate);
|
||||
}
|
||||
|
||||
void ConfigCameraStabilizationWidget::refreshValues()
|
||||
{
|
||||
HwSettings * hwSettings = HwSettings::GetInstance(getObjectManager());
|
||||
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
|
||||
HwSettings::DataFields hwSettingsData = hwSettings->getData();
|
||||
m_camerastabilization->enableCameraStabilization->setChecked(
|
||||
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] ==
|
||||
HwSettings::OPTIONALMODULES_ENABLED);
|
||||
|
||||
CameraStabSettings * cameraStabSettings = CameraStabSettings::GetInstance(getObjectManager());
|
||||
CameraStabSettings::DataFields cameraStab = cameraStabSettings->getData();
|
||||
m_camerastabilization->rollOutputRange->setValue(cameraStab.OutputRange[CameraStabSettings::OUTPUTRANGE_ROLL]);
|
||||
m_camerastabilization->pitchOutputRange->setValue(cameraStab.OutputRange[CameraStabSettings::OUTPUTRANGE_PITCH]);
|
||||
m_camerastabilization->yawOutputRange->setValue(cameraStab.OutputRange[CameraStabSettings::OUTPUTRANGE_YAW]);
|
||||
CameraStabSettings *cameraStabSettings = CameraStabSettings::GetInstance(getObjectManager());
|
||||
CameraStabSettings::DataFields cameraStabData = cameraStabSettings->getData();
|
||||
refreshUIValues(cameraStabData);
|
||||
|
||||
MixerSettings * mixerSettings = MixerSettings::GetInstance(getObjectManager());
|
||||
MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager());
|
||||
MixerSettings::DataFields mixerSettingsData = mixerSettings->getData();
|
||||
const int NUM_MIXERS = 10;
|
||||
QComboBox * selectors[3] = {
|
||||
QComboBox *outputs[3] = {
|
||||
m_camerastabilization->rollChannel,
|
||||
m_camerastabilization->pitchChannel,
|
||||
m_camerastabilization->yawChannel
|
||||
@ -232,21 +309,29 @@ void ConfigCameraStabilizationWidget::refreshValues()
|
||||
{
|
||||
// Default to none if not found. Then search for any mixer channels set to
|
||||
// this
|
||||
selectors[i]->setCurrentIndex(0);
|
||||
outputs[i]->setCurrentIndex(0);
|
||||
for (int j = 0; j < NUM_MIXERS; j++)
|
||||
if (*mixerTypes[j] == (MixerSettings::MIXER1TYPE_CAMERAROLL + i) &&
|
||||
selectors[i]->currentIndex() != (j + 1))
|
||||
selectors[i]->setCurrentIndex(j + 1);
|
||||
outputs[i]->currentIndex() != (j + 1))
|
||||
outputs[i]->setCurrentIndex(j + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigCameraStabilizationWidget::resetToDefaults()
|
||||
{
|
||||
CameraStabSettings cameraStabDefaults;
|
||||
CameraStabSettings::DataFields defaults = cameraStabDefaults.getData();
|
||||
refreshUIValues(defaults);
|
||||
}
|
||||
|
||||
void ConfigCameraStabilizationWidget::openHelp()
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/display/Doc/Camera+Stabilization", QUrl::StrictMode) );
|
||||
QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/display/Doc/Camera+Stabilization+Configuration", QUrl::StrictMode) );
|
||||
}
|
||||
|
||||
void ConfigCameraStabilizationWidget::enableControls(bool enable)
|
||||
{
|
||||
m_camerastabilization->camerastabilizationResetToDefaults->setEnabled(enable);
|
||||
m_camerastabilization->camerastabilizationSaveSD->setEnabled(enable);
|
||||
m_camerastabilization->camerastabilizationSaveRAM->setEnabled(enable);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file configahrstwidget.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @file configcamerastabilizationtwidget.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup ConfigPlugin Config Plugin
|
||||
@ -32,13 +32,6 @@
|
||||
#include "extensionsystem/pluginmanager.h"
|
||||
#include "uavobjectmanager.h"
|
||||
#include "uavobject.h"
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtSvg/QSvgRenderer>
|
||||
#include <QtSvg/QGraphicsSvgItem>
|
||||
#include <QList>
|
||||
#include <QTimer>
|
||||
#include <QMutex>
|
||||
|
||||
#include "camerastabsettings.h"
|
||||
|
||||
class ConfigCameraStabilizationWidget: public ConfigTaskWidget
|
||||
@ -50,12 +43,13 @@ public:
|
||||
~ConfigCameraStabilizationWidget();
|
||||
|
||||
private:
|
||||
virtual void enableControls(bool enable);
|
||||
|
||||
Ui_CameraStabilizationWidget *m_camerastabilization;
|
||||
virtual void enableControls(bool enable);
|
||||
void refreshUIValues(CameraStabSettings::DataFields &cameraStabData);
|
||||
|
||||
private slots:
|
||||
void openHelp();
|
||||
void resetToDefaults();
|
||||
void applySettings();
|
||||
void saveSettings();
|
||||
void refreshValues();
|
||||
@ -65,4 +59,4 @@ protected:
|
||||
void disconnectUpdates();
|
||||
};
|
||||
|
||||
#endif // ConfigCameraStabilization_H
|
||||
#endif // CONFIGCAMERASTABILIZATIONWIDGET_H
|
||||
|
@ -1,8 +1,12 @@
|
||||
<xml>
|
||||
<object name="CameraStabSettings" singleinstance="true" settings="true">
|
||||
<description>Settings for the @ref CameraStab mmodule</description>
|
||||
<field name="Inputs" units="channel" type="enum" elementnames="Roll,Pitch,Yaw" options="Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5,,None" defaultvalue="None"/>
|
||||
<field name="Input" units="channel" type="enum" elementnames="Roll,Pitch,Yaw" options="Accessory0,Accessory1,Accessory2,Accessory3,Accessory4,Accessory5,None" defaultvalue="None"/>
|
||||
<field name="InputRange" units="deg" type="uint8" elementnames="Roll,Pitch,Yaw" defaultvalue="20"/>
|
||||
<field name="InputRate" units="deg/s" type="uint8" elementnames="Roll,Pitch,Yaw" defaultvalue="50"/>
|
||||
<field name="ResponseTime" units="ms" type="uint16" elementnames="Roll,Pitch,Yaw" defaultvalue="150"/>
|
||||
<field name="StabilizationMode" units="" type="enum" elementnames="Roll,Pitch,Yaw" options="Attitude,AxisLock" defaultvalue="Attitude"/>
|
||||
<field name="MaxAxisLockRate" units="deg/s" type="float" elements="1" defaultvalue="1"/>
|
||||
<field name="OutputRange" units="deg" type="uint8" elementnames="Roll,Pitch,Yaw" defaultvalue="20"/>
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="true" updatemode="onchange" period="0"/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user