1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

Merged in filnet/librepilot/LP-245_gcs_spurious_unsaved_config_prompts (pull request #315)

LP-245 fixed spurious unsaved data prompts in GCS config gadget
This commit is contained in:
Lalanne Laurent 2016-09-25 15:48:35 +02:00
commit 6d0a643532
87 changed files with 1988 additions and 5566 deletions

View File

@ -218,7 +218,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="airframeHelp">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -250,26 +250,35 @@
<property name="flat">
<bool>true</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:help</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveAircraftToRAM">
<widget class="QPushButton" name="applyButton">
<property name="toolTip">
<string>Send to board, but don't save permanently (flash or SD).</string>
</property>
<property name="text">
<string>Apply</string>
</property>
<property name="objrelation" stdset="0">
<string>button:apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveAircraftToSD">
<widget class="QPushButton" name="saveButton">
<property name="toolTip">
<string>Applies and Saves all settings to flash or SD depending on board.</string>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="objrelation" stdset="0">
<string>button:save</string>
</property>
</widget>
</item>
</layout>
@ -287,9 +296,9 @@
<tabstops>
<tabstop>nameEdit</tabstop>
<tabstop>vehicleSetupWizardButton</tabstop>
<tabstop>airframeHelp</tabstop>
<tabstop>saveAircraftToRAM</tabstop>
<tabstop>saveAircraftToSD</tabstop>
<tabstop>helpButton</tabstop>
<tabstop>applyButton</tabstop>
<tabstop>saveButton</tabstop>
</tabstops>
<resources>
<include location="../coreplugin/core.qrc"/>

View File

@ -23,7 +23,16 @@
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<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>
@ -36,11 +45,38 @@
<string>Pre-Autotune</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_5">
<property name="margin">
<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="3" column="0" colspan="3">
<widget class="QTextEdit" name="textEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<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>16777215</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
@ -51,9 +87,9 @@
<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:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&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 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-family:'Lucida Grande'; font-size:20pt; font-weight:600; color:#ff0000;&quot;&gt;WARNING:&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; font-family:'Lucida Grande'; font-size:13pt;&quot;&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; font-family:'Lucida Grande'; font-size:13pt;&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;&lt;br /&gt;&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:'Lucida Grande'; font-size:13pt;&quot;&gt;&lt;br /&gt;&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:'Lucida Grande'; font-size:13pt;&quot;&gt;This is an experimental plugin for the GCS that is going to make your aircraft shake, etc, so test with lots of space and be &lt;/span&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:600;&quot;&gt;very very wary&lt;/span&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt; for it creating bad tuning values.  Basically there is no reason to think this will work at all.&lt;br /&gt;&lt;br /&gt;To use autotuning, here are the steps:&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
@ -99,7 +135,16 @@ p, li { white-space: pre-wrap; }
<string>Autotune Setup</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="margin">
<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>
@ -182,8 +227,8 @@ p, li { white-space: pre-wrap; }
<rect>
<x>0</x>
<y>0</y>
<width>709</width>
<height>605</height>
<width>526</width>
<height>510</height>
</rect>
</property>
<property name="sizePolicy">
@ -199,7 +244,16 @@ p, li { white-space: pre-wrap; }
<property name="spacing">
<number>12</number>
</property>
<property name="margin">
<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>
@ -601,7 +655,45 @@ will alter settings for the next autotuning flight</string>
</spacer>
</item>
<item>
<widget class="QPushButton" name="stabilizationReloadBoardData_6">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</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>25</width>
<height>25</height>
</size>
</property>
<property name="objrelation" stdset="0">
<string>button:help</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="reloadButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -627,7 +719,7 @@ Useful if you have accidentally changed some settings.</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveStabilizationToRAM_6">
<widget class="QPushButton" name="applyButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -651,7 +743,7 @@ Useful if you have accidentally changed some settings.</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveStabilizationToSD_6">
<widget class="QPushButton" name="saveButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -678,6 +770,8 @@ Useful if you have accidentally changed some settings.</string>
</item>
</layout>
</widget>
<resources/>
<resources>
<include location="../coreplugin/core.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -72,7 +72,7 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-103</y>
<y>0</y>
<width>748</width>
<height>811</height>
</rect>
@ -1321,7 +1321,7 @@ The same value is used for all axes.</string>
</spacer>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="camerastabilizationHelp">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -1369,7 +1369,7 @@ The same value is used for all axes.</string>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="camerastabilizationResetToDefaults">
<widget class="QPushButton" name="defaultButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -1400,7 +1400,7 @@ Apply or Save button afterwards.</string>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="reloadButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -1433,7 +1433,7 @@ Apply or Save button afterwards.</string>
</widget>
</item>
<item row="0" column="4">
<widget class="QPushButton" name="camerastabilizationSaveRAM">
<widget class="QPushButton" name="applyButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -1460,7 +1460,7 @@ Apply or Save button afterwards.</string>
</widget>
</item>
<item row="0" column="5">
<widget class="QPushButton" name="camerastabilizationSaveSD">
<widget class="QPushButton" name="saveButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -1528,10 +1528,10 @@ Apply or Save button afterwards.</string>
<tabstop>yawDecelTime</tabstop>
<tabstop>gimbalType</tabstop>
<tabstop>maxAccel</tabstop>
<tabstop>camerastabilizationResetToDefaults</tabstop>
<tabstop>pushButton</tabstop>
<tabstop>camerastabilizationSaveRAM</tabstop>
<tabstop>camerastabilizationSaveSD</tabstop>
<tabstop>defaultButton</tabstop>
<tabstop>reloadButton</tabstop>
<tabstop>applyButton</tabstop>
<tabstop>saveButton</tabstop>
</tabstops>
<resources>
<include location="../coreplugin/core.qrc"/>

View File

@ -456,7 +456,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="cchwHelp">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -494,10 +494,13 @@
<property name="flat">
<bool>true</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:help</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveTelemetryToRAM">
<widget class="QPushButton" name="applyButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -596,10 +599,13 @@ Beware of not locking yourself out!</string>
<property name="checkable">
<bool>false</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveTelemetryToSD">
<widget class="QPushButton" name="saveButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -625,6 +631,9 @@ Beware of not locking yourself out!</string>
<property name="text">
<string>Save</string>
</property>
<property name="objrelation" stdset="0">
<string>button:save</string>
</property>
</widget>
</item>
</layout>

View File

@ -117,7 +117,7 @@
<x>0</x>
<y>0</y>
<width>758</width>
<height>486</height>
<height>480</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@ -550,7 +550,7 @@ A setting of 0.00 disables the filter.</string>
</spacer>
</item>
<item>
<widget class="QPushButton" name="ccAttitudeHelp">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -582,6 +582,9 @@ A setting of 0.00 disables the filter.</string>
<property name="flat">
<bool>true</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:help</string>
</property>
</widget>
</item>
<item>
@ -595,6 +598,9 @@ A setting of 0.00 disables the filter.</string>
<property name="text">
<string>Apply</string>
</property>
<property name="objrelation" stdset="0">
<string>button:apply</string>
</property>
</widget>
</item>
<item>
@ -611,6 +617,9 @@ A setting of 0.00 disables the filter.</string>
<property name="text">
<string>Save</string>
</property>
<property name="objrelation" stdset="0">
<string>button:save</string>
</property>
</widget>
</item>
</layout>

View File

@ -1,3653 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ccpmWidget</class>
<widget class="QWidget" name="ccpmWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>850</width>
<height>572</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>300</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_17">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout_13">
<item row="0" column="0">
<layout class="QFormLayout" name="formLayout_6">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Swashplate config:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="ccpmType">
<property name="toolTip">
<string>Select aircraft type here</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QTabWidget" name="TabObject">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>300</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">#SwashplateBox,#SwashplateBox_2,#SwashplateBox_3,#SwashplateBox_4,#ccpmSwashImageBox,#SwashLvlInstructionsBox,#SwashLvlccpmSwashImageBox,#SwashLvlccpmSliderBox,#SwashLvlStatusBox,#ThrottleCurveBox,#PitchCurveBox{
background-color: qlineargradient(spread:pad, x1:0.507, y1:0.869318, x2:0.507, y2:0.0965909, stop:0 rgba(243, 243, 243, 255), stop:1 rgba(250, 250, 250, 255));
border: 1px outset #999;
border-radius: 3;
font:bold;
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top center; /* position at the top center */
padding: 0 3px;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #FFOECE, stop: 1 #FFFFFF);
top: 5px;
}</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="BasicTab">
<attribute name="title">
<string>Basic settings</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_6">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<layout class="QVBoxLayout" name="ccpmSettingsBox" stretch="0,1,1,0,0">
<item>
<widget class="QGroupBox" name="SwashplateBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>190</width>
<height>16777215</height>
</size>
</property>
<property name="title">
<string>Motor outputs</string>
</property>
<layout class="QGridLayout" name="gridLayout_18">
<property name="horizontalSpacing">
<number>3</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item row="2" column="1">
<widget class="QComboBox" name="ccpmTailChannel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="ccpmEngineChannel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="ccpmTailLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Tail Rotor</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="ccpmEngineLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Engine</string>
</property>
</widget>
</item>
<item row="0" column="0">
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="SwashplateBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>190</width>
<height>16777215</height>
</size>
</property>
<property name="title">
<string>Swashplate outputs</string>
</property>
<layout class="QGridLayout" name="gridLayout_19">
<property name="horizontalSpacing">
<number>3</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="ccpmServoWLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Servo W</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="ccpmServoWChannel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="ccpmServoXChannel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="ccpmServoYChannel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="ccpmServoXLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Servo X</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="ccpmSingleServo">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<item>
<property name="text">
<string>Front</string>
</property>
</item>
<item>
<property name="text">
<string>Right</string>
</property>
</item>
<item>
<property name="text">
<string>Rear</string>
</property>
</item>
<item>
<property name="text">
<string>Left</string>
</property>
</item>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="ccpmServoZLabel_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>1st Servo</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="ccpmServoZChannel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="ccpmServoZLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Servo Z</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="ccpmServoYLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Servo Y</string>
</property>
</widget>
</item>
<item row="0" column="0">
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="SwashplateBox_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>190</width>
<height>16777215</height>
</size>
</property>
<property name="title">
<string>Swashplate Servo Angles</string>
</property>
<layout class="QGridLayout" name="gridLayout_20">
<property name="horizontalSpacing">
<number>3</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="ccpmAngleW">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>85</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>15.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="ccpmServoWLabel_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Angle W</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="ccpmServoXLabel_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Angle X</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="ccpmServoYLabel_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Angle Y</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="ccpmServoZLabel_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Angle Z</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_10">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Correction Angle</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="ccpmAngleX">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>85</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>15.000000000000000</double>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QDoubleSpinBox" name="ccpmCorrectionAngle">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>85</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>15.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QDoubleSpinBox" name="ccpmAngleZ">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>85</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>15.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="ccpmAngleY">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>85</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>15.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="0">
<spacer name="verticalSpacer_7">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="SwashplateBox_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>190</width>
<height>16777215</height>
</size>
</property>
<property name="title">
<string>CCPM Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_21">
<property name="horizontalSpacing">
<number>3</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item row="2" column="0">
<widget class="QCheckBox" name="ccpmCollectivePassthrough">
<property name="text">
<string>Collective Pass through</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="ccpmLinkRoll">
<property name="text">
<string>Link Roll/Pitch</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="ccpmLinkCyclic">
<property name="text">
<string>Link Cyclic/Collective</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer_8">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<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>
</item>
<item row="0" column="10">
<layout class="QVBoxLayout" name="ccpmSwashImageBox_2">
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="ccpmSwashImageBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>600</width>
<height>600</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="baseSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="font">
<font>
<weight>75</weight>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="title">
<string>Swashplate Layout</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<property name="flat">
<bool>false</bool>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_10">
<property name="horizontalSpacing">
<number>3</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item row="1" column="0">
<widget class="QSplitter" name="splitter_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QGraphicsView" name="SwashplateImage">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1000</width>
<height>1000</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="baseSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="backgroundBrush">
<brush brushstyle="DiagCrossPattern">
<color alpha="50">
<red>112</red>
<green>184</green>
<blue>138</blue>
</color>
</brush>
</property>
<property name="foregroundBrush">
<brush brushstyle="SolidPattern">
<color alpha="0">
<red>127</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</property>
<property name="sceneRect">
<rectf>
<x>0.000000000000000</x>
<y>0.000000000000000</y>
<width>400.000000000000000</width>
<height>400.000000000000000</height>
</rectf>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="resizeAnchor">
<enum>QGraphicsView::AnchorViewCenter</enum>
</property>
</widget>
</widget>
</item>
<item row="0" column="0">
<spacer name="verticalSpacer_9">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="0" column="3">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QGroupBox" name="ccpmRevoMixingBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>600</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QGroupBox::title {
background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
color: rgb(255, 255, 255);
border-radius: 5;
margin:1px;
}</string>
</property>
<property name="title">
<string>REVO</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item>
<spacer name="verticalSpacer_10">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>7</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_14">
<property name="enabled">
<bool>false</bool>
</property>
<property name="font">
<font>
<pointsize>7</pointsize>
</font>
</property>
<property name="text">
<string>100%</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="ccpmRevoSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_13">
<property name="enabled">
<bool>false</bool>
</property>
<property name="font">
<font>
<pointsize>7</pointsize>
</font>
</property>
<property name="text">
<string>0%</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="ccpmREVOspinBox"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="ccpmPitchMixingBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>600</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QGroupBox::title {
background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
color: rgb(255, 255, 255);
border-radius: 5;
margin:1px;
}</string>
</property>
<property name="title">
<string>CCPM</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item>
<spacer name="verticalSpacer_11">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>7</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_15">
<property name="enabled">
<bool>true</bool>
</property>
<property name="font">
<font>
<pointsize>7</pointsize>
</font>
</property>
<property name="text">
<string>Collective</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="ccpmCollectiveSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_16">
<property name="enabled">
<bool>true</bool>
</property>
<property name="font">
<font>
<pointsize>7</pointsize>
</font>
</property>
<property name="text">
<string>Cyclic</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="ccpmCollectivespinBox">
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="ccpmCollectiveScalingBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>600</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QGroupBox::title {
background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
color: rgb(255, 255, 255);
border-radius: 5;
margin:1px;
}</string>
</property>
<property name="title">
<string>Collective</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<layout class="QVBoxLayout" name="verticalLayout_12">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item>
<spacer name="verticalSpacer_12">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>7</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<spacer name="horizontalSpacer_15">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="ccpmCollectiveScale">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_16">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QSpinBox" name="ccpmCollectiveScaleBox">
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="ccpmCyclicScalingBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>600</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QGroupBox::title {
background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
color: rgb(255, 255, 255);
border-radius: 5;
margin:1px;
}</string>
</property>
<property name="title">
<string>Cyclic</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item>
<spacer name="verticalSpacer_13">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>7</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="ccpmCyclicScale">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_10">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QSpinBox" name="ccpmCyclicScaleBox">
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="ccpmPitchScalingBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>600</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QGroupBox::title {
background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
color: rgb(255, 255, 255);
border-radius: 5;
margin:1px;
}</string>
</property>
<property name="title">
<string>Pitch</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item>
<spacer name="verticalSpacer_14">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>7</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<spacer name="horizontalSpacer_17">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="ccpmPitchScale">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_18">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QSpinBox" name="ccpmPitchScaleBox">
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="ccpmRollScalingBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>600</height>
</size>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QGroupBox::title {
background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
color: rgb(255, 255, 255);
border-radius: 5;
margin:1px;
}</string>
</property>
<property name="title">
<string>Roll</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item>
<spacer name="verticalSpacer_15">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>7</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<spacer name="horizontalSpacer_11">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="ccpmRollScale">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_12">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QSpinBox" name="ccpmRollScaleBox">
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="SwashPlateLevel">
<attribute name="title">
<string>Swashplate Levelling</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_8">
<property name="margin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="leftMargin">
<number>3</number>
</property>
<item>
<widget class="QGroupBox" name="SwashLvlInstructionsBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>228</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Commands</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>3</number>
</property>
<item>
<spacer name="verticalSpacer_16">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="SwashLvlStartButton">
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>85</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="SwashLvlNextButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>85</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>85</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Next</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTextEdit" name="SwashLvlStepInstruction">
<property name="minimumSize">
<size>
<width>0</width>
<height>150</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>220</width>
<height>450</height>
</size>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QPushButton" name="SwashLvlCancelButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>170</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>170</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="SwashLvlFinishButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>170</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>170</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Finish</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="SwashLvlStatusBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Status</string>
</property>
<layout class="QGridLayout" name="gridLayout_22">
<property name="horizontalSpacing">
<number>3</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item row="1" column="0">
<widget class="QListWidget" name="SwashLvlStepList">
<property name="minimumSize">
<size>
<width>220</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>190</width>
<height>125</height>
</size>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<item>
<property name="text">
<string>Neutral</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/configgadget/images/none.png</normaloff>
<normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Max</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/configgadget/images/none.png</normaloff>
<normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Min</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/configgadget/images/none.png</normaloff>
<normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset>
</property>
<property name="flags">
<set>ItemIsSelectable|ItemIsEnabled</set>
</property>
</item>
<item>
<property name="text">
<string>Verify</string>
</property>
<property name="icon">
<iconset>
<normaloff>:/configgadget/images/none.png</normaloff>
<normalon>:/configgadget/images/ok.png</normalon>:/configgadget/images/none.png</iconset>
</property>
<property name="flags">
<set>ItemIsEnabled</set>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<spacer name="verticalSpacer_19">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="SwashLvlccpmSliderBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>600</height>
</size>
</property>
<property name="title">
<string>Position</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item>
<spacer name="verticalSpacer_18">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_17">
<property name="enabled">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
color: rgb(255, 255, 255);
border-radius: 5;
font: bold 12px;
margin:1px;</string>
</property>
<property name="text">
<string>Max</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSlider" name="SwashLvlPositionSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_18">
<property name="enabled">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true">background-color: qlineargradient(spread:reflect, x1:0.507, y1:0, x2:0.507, y2:0.772, stop:0.208955 rgba(74, 74, 74, 255), stop:0.78607 rgba(36, 36, 36, 255));
color: rgb(255, 255, 255);
border-radius: 5;
font: bold 12px;
margin:1px;</string>
</property>
<property name="text">
<string>Min</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="SwashLvlPositionSpinBox">
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="2">
<widget class="QGroupBox" name="SwashLvlccpmSwashImageBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>600</width>
<height>600</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="baseSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="title">
<string>Swashplate Adjustment</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
<property name="flat">
<bool>false</bool>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_11">
<property name="horizontalSpacing">
<number>3</number>
</property>
<property name="margin">
<number>3</number>
</property>
<item row="1" column="0">
<widget class="QSplitter" name="splitter_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QGraphicsView" name="SwashLvlSwashplateImage">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1000</width>
<height>1000</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="baseSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="midLineWidth">
<number>0</number>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="backgroundBrush">
<brush brushstyle="DiagCrossPattern">
<color alpha="25">
<red>126</red>
<green>176</green>
<blue>220</blue>
</color>
</brush>
</property>
<property name="foregroundBrush">
<brush brushstyle="NoBrush">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</property>
<property name="sceneRect">
<rectf>
<x>0.000000000000000</x>
<y>0.000000000000000</y>
<width>400.000000000000000</width>
<height>400.000000000000000</height>
</rectf>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="resizeAnchor">
<enum>QGraphicsView::AnchorViewCenter</enum>
</property>
</widget>
</widget>
</item>
<item row="0" column="0">
<spacer name="verticalSpacer_17">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="CurveTab">
<attribute name="title">
<string>Curve settings</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_7">
<property name="margin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_6"/>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>3</number>
</property>
<item>
<widget class="QGroupBox" name="ThrottleCurveBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="baseSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="title">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="flat">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="MixerCurve" name="ThrottleCurve" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1000</width>
<height>1000</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="baseSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="PitchCurveBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="baseSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="MixerCurve" name="PitchCurve" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1000</width>
<height>1000</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>10</width>
<height>10</height>
</size>
</property>
<property name="baseSize">
<size>
<width>200</width>
<height>200</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<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>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="AdvancedTab">
<attribute name="title">
<string>Advanced settings</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_4">
<property name="margin">
<number>3</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QTableWidget" name="ccpmAdvancedSettingsTable">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1000</width>
<height>300</height>
</size>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="autoScroll">
<bool>true</bool>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="cornerButtonEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>75</number>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>20</number>
</attribute>
<row>
<property name="text">
<string>Engine</string>
</property>
</row>
<row>
<property name="text">
<string>Tail Rotor</string>
</property>
</row>
<row>
<property name="text">
<string>Servo W</string>
</property>
</row>
<row>
<property name="text">
<string>Servo X</string>
</property>
</row>
<row>
<property name="text">
<string>Servo Y</string>
</property>
</row>
<row>
<property name="text">
<string>Servo Z</string>
</property>
</row>
<column>
<property name="text">
<string>Channel</string>
</property>
</column>
<column>
<property name="text">
<string>Curve 1</string>
</property>
</column>
<column>
<property name="text">
<string>Curve 2</string>
</property>
</column>
<column>
<property name="text">
<string>Roll</string>
</property>
</column>
<column>
<property name="text">
<string>Pitch</string>
</property>
</column>
<column>
<property name="text">
<string>Yaw</string>
</property>
</column>
<item row="0" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="0" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="0" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="0" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="0" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="0" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="1" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="2" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="3" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="4" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="0">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="1">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="2">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="3">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="4">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
<item row="5" column="5">
<property name="text">
<string>-</string>
</property>
<property name="textAlignment">
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>MixerCurve</class>
<extends>QWidget</extends>
<header location="global">mixercurve.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>ccpmType</tabstop>
<tabstop>TabObject</tabstop>
<tabstop>ccpmEngineChannel</tabstop>
<tabstop>ccpmTailChannel</tabstop>
<tabstop>ccpmServoWChannel</tabstop>
<tabstop>ccpmServoXChannel</tabstop>
<tabstop>ccpmServoYChannel</tabstop>
<tabstop>ccpmServoZChannel</tabstop>
<tabstop>ccpmSingleServo</tabstop>
<tabstop>ccpmAngleW</tabstop>
<tabstop>ccpmAngleX</tabstop>
<tabstop>ccpmAngleY</tabstop>
<tabstop>ccpmAngleZ</tabstop>
<tabstop>ccpmCorrectionAngle</tabstop>
<tabstop>ccpmRevoSlider</tabstop>
<tabstop>ccpmREVOspinBox</tabstop>
<tabstop>ccpmCollectiveSlider</tabstop>
<tabstop>ccpmCollectivespinBox</tabstop>
<tabstop>SwashplateImage</tabstop>
<tabstop>SwashLvlStartButton</tabstop>
<tabstop>SwashLvlNextButton</tabstop>
<tabstop>SwashLvlStepInstruction</tabstop>
<tabstop>SwashLvlCancelButton</tabstop>
<tabstop>SwashLvlFinishButton</tabstop>
<tabstop>SwashLvlStepList</tabstop>
<tabstop>SwashLvlPositionSlider</tabstop>
<tabstop>SwashLvlPositionSpinBox</tabstop>
<tabstop>SwashLvlSwashplateImage</tabstop>
<tabstop>ccpmAdvancedSettingsTable</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>ccpmCollectiveSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmCollectivespinBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>261</x>
<y>496</y>
</hint>
<hint type="destinationlabel">
<x>269</x>
<y>546</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmCollectivespinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmCollectiveSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>269</x>
<y>546</y>
</hint>
<hint type="destinationlabel">
<x>261</x>
<y>511</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmREVOspinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmRevoSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>216</x>
<y>546</y>
</hint>
<hint type="destinationlabel">
<x>208</x>
<y>511</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmRevoSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmREVOspinBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>208</x>
<y>412</y>
</hint>
<hint type="destinationlabel">
<x>216</x>
<y>546</y>
</hint>
</hints>
</connection>
<connection>
<sender>SwashLvlPositionSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>SwashLvlPositionSpinBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>276</x>
<y>486</y>
</hint>
<hint type="destinationlabel">
<x>270</x>
<y>537</y>
</hint>
</hints>
</connection>
<connection>
<sender>SwashLvlPositionSpinBox</sender>
<signal>valueChanged(int)</signal>
<receiver>SwashLvlPositionSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>301</x>
<y>546</y>
</hint>
<hint type="destinationlabel">
<x>277</x>
<y>401</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmCollectiveScaleBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmCollectiveScale</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>296</x>
<y>534</y>
</hint>
<hint type="destinationlabel">
<x>306</x>
<y>480</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmCollectiveScale</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmCollectiveScaleBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>308</x>
<y>328</y>
</hint>
<hint type="destinationlabel">
<x>292</x>
<y>534</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmCyclicScale</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmCyclicScaleBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>358</x>
<y>306</y>
</hint>
<hint type="destinationlabel">
<x>355</x>
<y>538</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmCyclicScaleBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmCyclicScale</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>341</x>
<y>538</y>
</hint>
<hint type="destinationlabel">
<x>351</x>
<y>376</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmPitchScale</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmPitchScaleBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>417</x>
<y>306</y>
</hint>
<hint type="destinationlabel">
<x>406</x>
<y>531</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmPitchScaleBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmPitchScale</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>394</x>
<y>531</y>
</hint>
<hint type="destinationlabel">
<x>408</x>
<y>302</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmRollScaleBox</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmRollScale</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>455</x>
<y>529</y>
</hint>
<hint type="destinationlabel">
<x>458</x>
<y>466</y>
</hint>
</hints>
</connection>
<connection>
<sender>ccpmRollScale</sender>
<signal>valueChanged(int)</signal>
<receiver>ccpmRollScaleBox</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>461</x>
<y>388</y>
</hint>
<hint type="destinationlabel">
<x>474</x>
<y>533</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -29,6 +29,9 @@
#include "ui_airframe_ccpm.h"
#include <extensionsystem/pluginmanager.h>
#include <uavobjectutilmanager.h>
#include "mixersettings.h"
#include "systemsettings.h"
#include "actuatorcommand.h"
@ -124,8 +127,9 @@ QStringList ConfigCcpmWidget::getChannelDescriptions()
}
ConfigCcpmWidget::ConfigCcpmWidget(QWidget *parent) :
VehicleConfig(parent), m_aircraft(new Ui_CcpmConfigWidget())
VehicleConfig(parent)
{
m_aircraft = new Ui_CcpmConfigWidget();
m_aircraft->setupUi(this);
SwashLvlConfigurationInProgress = 0;
@ -1070,23 +1074,6 @@ void ConfigCcpmWidget::setMixer()
updatingToHardware = false;
}
/**
Send ccpm type to the board and request saving to SD card
*/
void ConfigCcpmWidget::saveccpmUpdate()
{
if (SwashLvlConfigurationInProgress) {
return;
}
ShowDisclaimer(0);
// Send update so that the latest value is saved
// sendccpmUpdate();
setMixer();
UAVDataObject *obj = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
saveObjectToSD(obj);
}
void ConfigCcpmWidget::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
@ -1416,6 +1403,16 @@ void ConfigCcpmWidget::SwashLvlFinishButtonPressed()
ccpmSwashplateUpdate();
}
void ConfigCcpmWidget::saveObjectToSD(UAVObject *obj)
{
// saveObjectToSD is now handled by the UAVUtils plugin in one
// central place (and one central queue)
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
utilMngr->saveObjectToSD(obj);
}
int ConfigCcpmWidget::ShowDisclaimer(int messageID)
{
QMessageBox msgBox;

View File

@ -31,8 +31,7 @@
#include "cfg_vehicletypes/vehicleconfig.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
class Ui_CcpmConfigWidget;
@ -69,7 +68,6 @@ public:
public slots:
void getMixer();
void setMixer();
void saveccpmUpdate();
protected:
void showEvent(QShowEvent *event);
@ -112,6 +110,8 @@ private:
QString updateConfigObjects();
void saveObjectToSD(UAVObject *obj);
private slots:
virtual void setupUI(QString airframeType);
virtual bool throwConfigError(int typeInt);

View File

@ -149,9 +149,11 @@ QStringList ConfigCustomWidget::getChannelDescriptions()
}
ConfigCustomWidget::ConfigCustomWidget(QWidget *parent) :
VehicleConfig(parent), m_aircraft(new Ui_CustomConfigWidget())
VehicleConfig(parent)
{
m_aircraft = new Ui_CustomConfigWidget();
m_aircraft->setupUi(this);
m_aircraft->customMixerTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
// Put combo boxes in line one of the custom mixer table:
@ -190,6 +192,7 @@ void ConfigCustomWidget::registerWidgets(ConfigTaskWidget &parent)
parent.addWidget(m_aircraft->customThrottle1Curve);
parent.addWidget(m_aircraft->customThrottle2Curve->getCurveWidget());
parent.addWidget(m_aircraft->customThrottle2Curve);
// TODO why is curve2SourceCombo registered twice ?
parent.addWidgetBinding("MixerSettings", "Curve2Source", m_aircraft->curve2SourceCombo);
parent.addWidget(m_aircraft->curve2SourceCombo);
}

View File

@ -109,8 +109,9 @@ QStringList ConfigFixedWingWidget::getChannelDescriptions()
}
ConfigFixedWingWidget::ConfigFixedWingWidget(QWidget *parent) :
VehicleConfig(parent), m_aircraft(new Ui_FixedWingConfigWidget())
VehicleConfig(parent)
{
m_aircraft = new Ui_FixedWingConfigWidget();
m_aircraft->setupUi(this);
populateChannelComboBoxes();

View File

@ -73,8 +73,9 @@ QStringList ConfigGroundVehicleWidget::getChannelDescriptions()
}
ConfigGroundVehicleWidget::ConfigGroundVehicleWidget(QWidget *parent) :
VehicleConfig(parent), m_aircraft(new Ui_GroundConfigWidget())
VehicleConfig(parent)
{
m_aircraft = new Ui_GroundConfigWidget();
m_aircraft->setupUi(this);
populateChannelComboBoxes();

View File

@ -132,8 +132,9 @@ QStringList ConfigMultiRotorWidget::getChannelDescriptions()
}
ConfigMultiRotorWidget::ConfigMultiRotorWidget(QWidget *parent) :
VehicleConfig(parent), m_aircraft(new Ui_MultiRotorConfigWidget()), invertMotors(false)
VehicleConfig(parent), invertMotors(false)
{
m_aircraft = new Ui_MultiRotorConfigWidget();
m_aircraft->setupUi(this);
populateChannelComboBoxes();
@ -176,8 +177,6 @@ ConfigMultiRotorWidget::ConfigMultiRotorWidget(QWidget *parent) :
m_aircraft->multiThrottleCurve->setXAxisLabel(tr("Input"));
m_aircraft->multiThrottleCurve->setYAxisLabel(tr("Output"));
updateEnableControls();
}
ConfigMultiRotorWidget::~ConfigMultiRotorWidget()

View File

@ -120,12 +120,12 @@ QString VehicleConfig::updateConfigObjectsFromWidgets()
return NULL;
}
void VehicleConfig::refreshWidgetsValues(UAVObject *o)
void VehicleConfig::refreshWidgetsValuesImpl(UAVObject *obj)
{
Q_UNUSED(o);
Q_UNUSED(obj);
}
void VehicleConfig::updateObjectsFromWidgets()
void VehicleConfig::updateObjectsFromWidgetsImpl()
{}
void VehicleConfig::resetActuators(GUIConfigDataUnion *configData)

View File

@ -162,8 +162,13 @@ class ConfigTaskWidget;
/*
* This class handles vehicle specific configuration UI and associated logic.
*
* This class derives from ConfigTaskWidget and overrides its the default "binding" mechanism.
* It does not use the "dirty" state management directlyand registers its relevant widgets with ConfigTaskWidget to do so.
* VehicleConfig derives from ConfigTaskWidget but is not a top level ConfigTaskWidget.
* VehicleConfig objects are nested within the ConfigVehicleConfigWidget and have particularities:
* - bindings are added to the parent (i.e. ConfigVehicleConfigWidget)
* - auto bindings are not supported
* - as a consequence things like dirty state management are bypassed and delegated to the parent class.
*
* It does not use the "dirty" state management directly and registers its relevant widgets with ConfigTaskWidget to do so.
*/
class VehicleConfig : public ConfigTaskWidget {
Q_OBJECT
@ -244,9 +249,8 @@ protected:
double getCurveMin(QList<double> *curve);
double getCurveMax(QList<double> *curve);
protected slots:
virtual void refreshWidgetsValues(UAVObject *o = NULL);
virtual void updateObjectsFromWidgets();
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
private:
static UAVObjectManager *getUAVObjectManager();

View File

@ -4,6 +4,12 @@ DEFINES += CONFIG_LIBRARY
QT += widgets svg opengl qml quick
# silence eigen warnings
QMAKE_CXXFLAGS_WARN_ON += -Wno-deprecated-declarations
win32 {
QMAKE_CXXFLAGS_WARN_ON += -Wno-ignored-attributes
}
include(config_dependencies.pri)
INCLUDEPATH += ../../libs/eigen
@ -21,8 +27,7 @@ HEADERS += \
configccattitudewidget.h \
configstabilizationwidget.h \
assertions.h \
defaultattitudewidget.h \
defaulthwsettingswidget.h \
defaultconfigwidget.h \
channelform.h \
inputchannelform.h \
configcamerastabilizationwidget.h \
@ -70,8 +75,7 @@ SOURCES += \
config_cc_hw_widget.cpp \
configccattitudewidget.cpp \
configstabilizationwidget.cpp \
defaultattitudewidget.cpp \
defaulthwsettingswidget.cpp \
defaultconfigwidget.cpp \
channelform.cpp \
inputchannelform.cpp \
configcamerastabilizationwidget.cpp \
@ -114,8 +118,7 @@ FORMS += \
input_wizard.ui \
output.ui \
ccattitude.ui \
defaultattitude.ui \
defaulthwsettings.ui \
defaultconfig.ui \
inputchannelform.ui \
camerastabilization.ui \
outputchannelform.ui \

View File

@ -1,14 +1,14 @@
/**
******************************************************************************
*
* @file configtelemetrywidget.h
* @file config_cc_hw_widget.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief The Configuration Gadget used to update settings in the firmware
* @brief The Configuration Gadget used to update hardware settings in the firmware
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -31,34 +31,28 @@
#include "ui_cc_hw_settings.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include <uavobjectutilmanager.h>
#include "hwsettings.h"
#include <QDebug>
#include <QStringList>
#include <QWidget>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDesktopServices>
#include <QUrl>
#include <QSvgRenderer>
ConfigCCHWWidget::ConfigCCHWWidget(QWidget *parent) : ConfigTaskWidget(parent)
{
m_telemetry = new Ui_CC_HW_Widget();
m_telemetry->setupUi(this);
// must be done before auto binding !
setWikiURL("CC+Hardware+Configuration");
addAutoBindings();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
m_telemetry->saveTelemetryToRAM->setVisible(false);
}
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
int id = utilMngr->getBoardModel();
switch (id) {
case 0x0101:
m_telemetry->label_2->setPixmap(QPixmap(":/uploader/images/deviceID-0101.svg"));
@ -79,7 +73,7 @@ ConfigCCHWWidget::ConfigCCHWWidget(QWidget *parent) : ConfigTaskWidget(parent)
m_telemetry->label_2->setPixmap(QPixmap(":/configgadget/images/coptercontrol.svg"));
break;
}
addApplySaveButtons(m_telemetry->saveTelemetryToRAM, m_telemetry->saveTelemetryToSD);
addWidgetBinding("HwSettings", "CC_FlexiPort", m_telemetry->cbFlexi);
addWidgetBinding("HwSettings", "CC_MainPort", m_telemetry->cbTele);
addWidgetBinding("HwSettings", "CC_RcvrPort", m_telemetry->cbRcvr);
@ -90,20 +84,13 @@ ConfigCCHWWidget::ConfigCCHWWidget(QWidget *parent) : ConfigTaskWidget(parent)
// Add Gps protocol configuration
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields hwSettingsData = hwSettings->getData();
if (hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_GPS] != HwSettings::OPTIONALMODULES_ENABLED) {
if (hwSettings->getOptionalModules(HwSettings::OPTIONALMODULES_GPS) != HwSettings::OPTIONALMODULES_ENABLED) {
m_telemetry->gpsProtocol->setEnabled(false);
m_telemetry->gpsProtocol->setToolTip(tr("Enable GPS module and reboot the board to be able to select GPS protocol"));
} else {
addWidgetBinding("GPSSettings", "DataProtocol", m_telemetry->gpsProtocol);
}
connect(m_telemetry->cchwHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
enableSaveButtons(false);
populateWidgets();
refreshWidgetsValues();
forceConnectedState();
}
ConfigCCHWWidget::~ConfigCCHWWidget()
@ -146,17 +133,6 @@ void ConfigCCHWWidget::widgetsContentsChanged()
void ConfigCCHWWidget::enableSaveButtons(bool enable)
{
m_telemetry->saveTelemetryToRAM->setEnabled(enable);
m_telemetry->saveTelemetryToSD->setEnabled(enable);
m_telemetry->applyButton->setEnabled(enable);
m_telemetry->saveButton->setEnabled(enable);
}
void ConfigCCHWWidget::openHelp()
{
QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("CC+Hardware+Configuration"),
QUrl::StrictMode));
}
/**
* @}
* @}
*/

View File

@ -1,13 +1,14 @@
/**
******************************************************************************
*
* @file configtelemetrytwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file config_cc_hw_widget.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Telemetry configuration panel
* @brief The Configuration Gadget used to update hardware settings in the firmware
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -28,16 +29,10 @@
#define CONFIGCCHWWIDGET_H
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "smartsavebutton.h"
#include <QWidget>
#include <QList>
#include <QSvgRenderer>
class Ui_CC_HW_Widget;
class QWidget;
class QSvgRenderer;
class ConfigCCHWWidget : public ConfigTaskWidget {
Q_OBJECT
@ -46,7 +41,6 @@ public:
ConfigCCHWWidget(QWidget *parent = 0);
~ConfigCCHWWidget();
private slots:
void openHelp();
void refreshValues();
void widgetsContentsChanged();
void enableSaveButtons(bool enable);

View File

@ -23,8 +23,11 @@ ConfigAutotuneWidget::ConfigAutotuneWidget(QWidget *parent) :
m_autotune = new Ui_AutotuneWidget();
m_autotune->setupUi(this);
// Connect automatic signals
autoLoadWidgets();
// must be done before auto binding !
// setWikiURL("");
addAutoBindings();
disableMouseWheelEvents();
// Whenever any value changes compute new potential stabilization settings
@ -148,26 +151,23 @@ void ConfigAutotuneWidget::recomputeStabilization()
m_autotune->pitchAttitudeKp->setText(QString().number(stabSettings.PitchPI[StabilizationSettings::PITCHPI_KP]));
m_autotune->pitchAttitudeKi->setText(QString().number(stabSettings.PitchPI[StabilizationSettings::PITCHPI_KI]));
}
void ConfigAutotuneWidget::refreshWidgetsValues(UAVObject *obj)
void ConfigAutotuneWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
if (obj == hwSettings) {
bool dirtyBack = isDirty();
HwSettings::DataFields hwSettingsData = hwSettings->getData();
m_autotune->enableAutoTune->setChecked(
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_AUTOTUNE] == HwSettings::OPTIONALMODULES_ENABLED);
setDirty(dirtyBack);
bool enabled = (hwSettings->getOptionalModules(HwSettings::OPTIONALMODULES_AUTOTUNE) == HwSettings::OPTIONALMODULES_ENABLED);
m_autotune->enableAutoTune->setChecked(enabled);
}
ConfigTaskWidget::refreshWidgetsValues(obj);
}
void ConfigAutotuneWidget::updateObjectsFromWidgets()
void ConfigAutotuneWidget::updateObjectsFromWidgetsImpl()
{
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields hwSettingsData = hwSettings->getData();
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_AUTOTUNE] =
m_autotune->enableAutoTune->isChecked() ? HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED;
hwSettings->setData(hwSettingsData);
ConfigTaskWidget::updateObjectsFromWidgets();
quint8 enableModule = (m_autotune->enableAutoTune->isChecked()) ? HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED;
hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_AUTOTUNE, enableModule);
;
}

View File

@ -50,11 +50,10 @@ private:
Ui_AutotuneWidget *m_autotune;
StabilizationSettings::DataFields stabSettings;
signals:
protected:
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
public slots:
void refreshWidgetsValues(UAVObject *obj);
void updateObjectsFromWidgets();
private slots:
void recomputeStabilization();
void saveStabilization();

View File

@ -38,9 +38,6 @@
#include "ui_camerastabilization.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include "camerastabsettings.h"
#include "hwsettings.h"
#include "mixersettings.h"
@ -51,22 +48,16 @@ ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget *parent
ui = new Ui_CameraStabilizationWidget();
ui->setupUi(this);
addApplySaveButtons(ui->camerastabilizationSaveRAM, ui->camerastabilizationSaveSD);
// must be done before auto binding !
setWikiURL("Camera+Stabilisation+Configuration");
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
ui->camerastabilizationSaveRAM->setVisible(false);
}
addAutoBindings();
disableMouseWheelEvents();
// These widgets don't have direct relation to UAVObjects
// and need special processing
QComboBox *outputs[] = {
ui->rollChannel,
ui->pitchChannel,
ui->yawChannel,
};
QComboBox *outputs[] = { ui->rollChannel, ui->pitchChannel, ui->yawChannel, };
const int NUM_OUTPUTS = sizeof(outputs) / sizeof(outputs[0]);
// Populate widgets with channel numbers
@ -78,11 +69,6 @@ ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget *parent
}
}
setWikiURL("Camera+Stabilisation+Configuration");
// Load UAVObjects to widget relations from UI file
// using objrelation dynamic property
autoLoadWidgets();
// Add some widgets to track their UI dirty state and handle smartsave
addWidget(ui->enableCameraStabilization);
addWidget(ui->rollChannel);
@ -101,9 +87,6 @@ ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget *parent
// To set special widgets to defaults when requested
connect(this, SIGNAL(defaultRequested(int)), this, SLOT(defaultRequestedSlot(int)));
disableMouseWheelEvents();
updateEnableControls();
}
ConfigCameraStabilizationWidget::~ConfigCameraStabilizationWidget()
@ -114,21 +97,19 @@ ConfigCameraStabilizationWidget::~ConfigCameraStabilizationWidget()
/*
* This overridden function refreshes widgets which have no direct relation
* to any of UAVObjects. It saves their dirty state first because update comes
* from UAVObjects, and then restores it. Aftewards it calls base class
* function to take care of other widgets which were dynamically added.
* from UAVObjects, and then restores it.
*/
void ConfigCameraStabilizationWidget::refreshWidgetsValues(UAVObject *obj)
void ConfigCameraStabilizationWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
bool dirty = isDirty();
Q_UNUSED(obj);
// Set module enable checkbox from OptionalModules UAVObject item.
// It needs special processing because ConfigTaskWidget uses TRUE/FALSE
// for QCheckBox, but OptionalModules uses Enabled/Disabled enum values.
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields hwSettingsData = hwSettings->getData();
ui->enableCameraStabilization->setChecked(
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] == HwSettings::OPTIONALMODULES_ENABLED);
hwSettings->getOptionalModules(HwSettings::OPTIONALMODULES_CAMERASTAB) == HwSettings::OPTIONALMODULES_ENABLED);
// Load mixer outputs which are mapped to camera controls
MixerSettings *mixerSettings = MixerSettings::GetInstance(getObjectManager());
@ -168,22 +149,16 @@ void ConfigCameraStabilizationWidget::refreshWidgetsValues(UAVObject *obj)
}
}
}
setDirty(dirty);
ConfigTaskWidget::refreshWidgetsValues(obj);
}
/*
* This overridden function updates UAVObjects which have no direct relation
* to any of widgets. Aftewards it calls base class function to take care of
* other object to widget relations which were dynamically added.
* to any of widgets.
*/
void ConfigCameraStabilizationWidget::updateObjectsFromWidgets()
void ConfigCameraStabilizationWidget::updateObjectsFromWidgetsImpl()
{
// Save state of the module enable checkbox first.
// Do not use setData() member on whole object, if possible, since it triggers
// unnessesary UAVObect update.
// Do not use setData() member on whole object, if possible, since it triggers unnecessary UAVObect update.
quint8 enableModule = ui->enableCameraStabilization->isChecked() ?
HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED;
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
@ -257,8 +232,6 @@ void ConfigCameraStabilizationWidget::updateObjectsFromWidgets()
// FIXME: Should not use setData() to prevent double updates.
// It should be refactored after the reformatting of MixerSettings UAVObject.
mixerSettings->setData(mixerSettingsData);
ConfigTaskWidget::updateObjectsFromWidgets();
}
/*
@ -269,18 +242,6 @@ void ConfigCameraStabilizationWidget::defaultRequestedSlot(int group)
{
Q_UNUSED(group);
// Here is the example of how to reset the state of QCheckBox. It is
// commented out because we normally don't want to reset the module
// enable state to default "disabled" (or we don't care about values at all).
// But if you want, you could use the dirtyClone() function to get default
// values of an object and then use them to set a widget state.
//
// HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
// HwSettings *hwSettingsDefault=(HwSettings*)hwSettings->dirtyClone();
// HwSettings::DataFields hwSettingsData = hwSettingsDefault->getData();
// m_camerastabilization->enableCameraStabilization->setChecked(
// hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_CAMERASTAB] == HwSettings::OPTIONALMODULES_ENABLED);
// For outputs we set them all to none, so don't use any UAVObject to get defaults
QComboBox *outputs[] = {
ui->rollChannel,

View File

@ -28,8 +28,7 @@
#define CONFIGCAMERASTABILIZATIONWIDGET_H
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "camerastabsettings.h"
@ -43,10 +42,12 @@ public:
ConfigCameraStabilizationWidget(QWidget *parent = 0);
~ConfigCameraStabilizationWidget();
protected:
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
private:
Ui_CameraStabilizationWidget *ui;
void refreshWidgetsValues(UAVObject *obj);
void updateObjectsFromWidgets();
private slots:
void defaultRequestedSlot(int group);

View File

@ -29,9 +29,7 @@
#include "ui_ccattitude.h"
#include "utils/coordinateconversions.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include <utils/coordinateconversions.h>
#include <calibration/calibrationutils.h>
#include "attitudesettings.h"
@ -39,32 +37,23 @@
#include "accelgyrosettings.h"
#include "gyrostate.h"
#include <QMutexLocker>
#include <QMessageBox>
#include <QDebug>
#include <QDesktopServices>
#include <QUrl>
ConfigCCAttitudeWidget::ConfigCCAttitudeWidget(QWidget *parent) :
ConfigTaskWidget(parent),
ui(new Ui_ccattitude)
ConfigTaskWidget(parent), accelUpdates(0), gyroUpdates(0)
{
ui = new Ui_ccattitude(),
ui->setupUi(this);
connect(ui->zeroBias, SIGNAL(clicked()), this, SLOT(startAccelCalibration()));
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
ui->applyButton->setVisible(false);
}
// must be done before auto binding !
setWikiURL("CC+Attitude+Configuration");
addAutoBindings();
addApplySaveButtons(ui->applyButton, ui->saveButton);
addUAVObject("AttitudeSettings");
addUAVObject("AccelGyroSettings");
// Connect the help button
connect(ui->ccAttitudeHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
addWidgetBinding("AttitudeSettings", "ZeroDuringArming", ui->zeroGyroBiasOnArming);
addWidgetBinding("AttitudeSettings", "InitialZeroWhenBoardSteady", ui->initGyroWhenBoardSteady);
@ -74,9 +63,8 @@ ConfigCCAttitudeWidget::ConfigCCAttitudeWidget(QWidget *parent) :
addWidgetBinding("AttitudeSettings", "BoardRotation", ui->pitchBias, AttitudeSettings::BOARDROTATION_PITCH);
addWidgetBinding("AttitudeSettings", "BoardRotation", ui->yawBias, AttitudeSettings::BOARDROTATION_YAW);
addWidget(ui->zeroBias);
populateWidgets();
refreshWidgetsValues();
forceConnectedState();
connect(ui->zeroBias, SIGNAL(clicked()), this, SLOT(startAccelCalibration()));
}
ConfigCCAttitudeWidget::~ConfigCCAttitudeWidget()
@ -144,7 +132,8 @@ void ConfigCCAttitudeWidget::sensorsUpdated(UAVObject *obj)
attitudeSettingsData.BiasCorrectGyro = AttitudeSettings::BIASCORRECTGYRO_TRUE;
AttitudeSettings::GetInstance(getObjectManager())->setData(attitudeSettingsData);
AccelGyroSettings::GetInstance(getObjectManager())->setData(accelGyroSettingsData);
this->setDirty(true);
setDirty(true);
// reenable controls
enableControls(true);
@ -220,12 +209,6 @@ void ConfigCCAttitudeWidget::startAccelCalibration()
connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
}
void ConfigCCAttitudeWidget::openHelp()
{
QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("CC+Attitude+Configuration"),
QUrl::StrictMode));
}
void ConfigCCAttitudeWidget::setAccelFiltering(bool active)
{
Q_UNUSED(active);
@ -241,9 +224,7 @@ void ConfigCCAttitudeWidget::enableControls(bool enable)
ConfigTaskWidget::enableControls(enable);
}
void ConfigCCAttitudeWidget::updateObjectsFromWidgets()
void ConfigCCAttitudeWidget::updateObjectsFromWidgetsImpl()
{
ConfigTaskWidget::updateObjectsFromWidgets();
ui->zeroBiasProgress->setValue(0);
}

View File

@ -28,8 +28,7 @@
#define CCATTITUDEWIDGET_H
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include <QWidget>
@ -44,13 +43,13 @@ public:
explicit ConfigCCAttitudeWidget(QWidget *parent = 0);
~ConfigCCAttitudeWidget();
virtual void updateObjectsFromWidgets();
protected:
virtual void updateObjectsFromWidgetsImpl();
private slots:
void sensorsUpdated(UAVObject *obj);
void timeout();
void startAccelCalibration();
void openHelp();
void setAccelFiltering(bool active);
private:
@ -66,6 +65,7 @@ private:
QList<double> x_gyro_accum, y_gyro_accum, z_gyro_accum;
static const int NUM_SENSOR_UPDATES = 300;
protected:
virtual void enableControls(bool enable);
};

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file configgadget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -25,8 +26,11 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "configgadget.h"
#include "configgadgetwidget.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
ConfigGadget::ConfigGadget(QString classId, ConfigGadgetWidget *widget, QWidget *parent) :
IUAVGadget(classId, parent), m_widget(widget)
{}
@ -40,3 +44,13 @@ void ConfigGadget::loadConfiguration(IUAVGadgetConfiguration *config)
{
Q_UNUSED(config);
}
void ConfigGadget::saveState(QSettings *settings)
{
m_widget->saveState(settings);
}
void ConfigGadget::restoreState(QSettings *settings)
{
m_widget->restoreState(settings);
}

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file configgadget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -28,14 +29,10 @@
#define CONFIGGADGET_H
#include <coreplugin/iuavgadget.h>
#include "../uavobjectwidgetutils/configtaskwidget.h"
class IUAVGadget;
// class QList<int>;
class QWidget;
class QString;
class ConfigGadgetWidget;
class Ui_ConfigGadget;
using namespace Core;
@ -49,8 +46,12 @@ public:
{
return (QWidget *)m_widget;
}
void loadConfiguration(IUAVGadgetConfiguration *config);
void saveState(QSettings *settings);
void restoreState(QSettings *settings);
private:
ConfigGadgetWidget *m_widget;
};

View File

@ -41,18 +41,22 @@
#include "configrevowidget.h"
#include "configrevonanohwwidget.h"
#include "configsparky2hwwidget.h"
#include "defaultattitudewidget.h"
#include "defaulthwsettingswidget.h"
#include "uavobjectutilmanager.h"
#include "defaultconfigwidget.h"
#include <extensionsystem/pluginmanager.h>
#include <uavobjectutilmanager.h>
#include <uavtalk/telemetrymanager.h>
#include <uavtalk/oplinkmanager.h>
#include "utils/mytabbedstackwidget.h"
#include <QDebug>
#include <QStringList>
#include <QWidget>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QPushButton>
#include <QMessageBox>
#include <QSettings>
#include <QDebug>
#define OPLINK_TIMEOUT 2000
ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
{
@ -66,85 +70,93 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
layout->addWidget(stackWidget);
setLayout(layout);
QWidget *qwd;
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
QIcon *icon = new QIcon();
QWidget *widget;
QIcon *icon;
icon = new QIcon();
icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new DefaultHwSettingsWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware"));
widget = new DefaultConfigWidget(this, tr("Hardware"));
stackWidget->insertTab(ConfigGadgetWidget::Hardware, widget, *icon, QString("Hardware"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/vehicle_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/vehicle_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigVehicleTypeWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::aircraft, qwd, *icon, QString("Vehicle"));
widget = new ConfigVehicleTypeWidget(this);
static_cast<ConfigTaskWidget *>(widget)->bind();
stackWidget->insertTab(ConfigGadgetWidget::Aircraft, widget, *icon, QString("Vehicle"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/input_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/input_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigInputWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::input, qwd, *icon, QString("Input"));
widget = new ConfigInputWidget(this);
static_cast<ConfigTaskWidget *>(widget)->bind();
stackWidget->insertTab(ConfigGadgetWidget::Input, widget, *icon, QString("Input"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/output_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/output_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigOutputWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::output, qwd, *icon, QString("Output"));
widget = new ConfigOutputWidget(this);
static_cast<ConfigTaskWidget *>(widget)->bind();
stackWidget->insertTab(ConfigGadgetWidget::Output, widget, *icon, QString("Output"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new DefaultAttitudeWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Attitude"));
widget = new DefaultConfigWidget(this, tr("Attitude"));
stackWidget->insertTab(ConfigGadgetWidget::Sensors, widget, *icon, QString("Attitude"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/stabilization_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/stabilization_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigStabilizationWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::stabilization, qwd, *icon, QString("Stabilization"));
widget = new ConfigStabilizationWidget(this);
static_cast<ConfigTaskWidget *>(widget)->bind();
stackWidget->insertTab(ConfigGadgetWidget::Stabilization, widget, *icon, QString("Stabilization"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/camstab_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/camstab_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigCameraStabilizationWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::camerastabilization, qwd, *icon, QString("Gimbal"));
widget = new ConfigCameraStabilizationWidget(this);
static_cast<ConfigTaskWidget *>(widget)->bind();
stackWidget->insertTab(ConfigGadgetWidget::CameraStabilization, widget, *icon, QString("Gimbal"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/txpid_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/txpid_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigTxPIDWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::txpid, qwd, *icon, QString("TxPID"));
widget = new ConfigTxPIDWidget(this);
static_cast<ConfigTaskWidget *>(widget)->bind();
stackWidget->insertTab(ConfigGadgetWidget::TxPid, widget, *icon, QString("TxPID"));
stackWidget->setCurrentIndex(ConfigGadgetWidget::hardware);
icon = new QIcon();
icon->addFile(":/configgadget/images/pipx-normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/pipx-selected.png", QSize(), QIcon::Selected, QIcon::Off);
widget = new DefaultConfigWidget(this, tr("OPLink Configuration"));
stackWidget->insertTab(ConfigGadgetWidget::OPLink, widget, *icon, QString("OPLink"));
// Listen to autopilot connection events
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
TelemetryManager *telMngr = pm->getObject<TelemetryManager>();
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
stackWidget->setCurrentIndex(ConfigGadgetWidget::Hardware);
// And check whether by any chance we are not already connected
if (telMngr->isConnected()) {
// connect to autopilot connection events
TelemetryManager *tm = pm->getObject<TelemetryManager>();
connect(tm, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
connect(tm, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
// check if we are already connected
if (tm->isConnected()) {
onAutopilotConnect();
}
// connect to oplink manager
OPLinkManager *om = pm->getObject<OPLinkManager>();
connect(om, SIGNAL(connected()), this, SLOT(onOPLinkConnect()));
connect(om, SIGNAL(disconnected()), this, SLOT(onOPLinkDisconnect()));
// check if we are already connected
if (om->isConnected()) {
onOPLinkConnect();
}
help = 0;
connect(stackWidget, SIGNAL(currentAboutToShow(int, bool *)), this, SLOT(tabAboutToChange(int, bool *)));
// Connect to the OPLinkStatus object updates
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
oplinkStatusObj = dynamic_cast<UAVDataObject *>(objManager->getObject("OPLinkStatus"));
if (oplinkStatusObj != NULL) {
connect(oplinkStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateOPLinkStatus(UAVObject *)));
} else {
qDebug() << "Error: Object is unknown (OPLinkStatus).";
}
// Create the timer that is used to timeout the connection to the OPLink.
oplinkTimeout = new QTimer(this);
connect(oplinkTimeout, SIGNAL(timeout()), this, SLOT(onOPLinkDisconnect()));
oplinkConnected = false;
}
ConfigGadgetWidget::~ConfigGadgetWidget()
@ -154,79 +166,118 @@ ConfigGadgetWidget::~ConfigGadgetWidget()
void ConfigGadgetWidget::startInputWizard()
{
stackWidget->setCurrentIndex(ConfigGadgetWidget::input);
ConfigInputWidget *inputWidget = dynamic_cast<ConfigInputWidget *>(stackWidget->getWidget(ConfigGadgetWidget::input));
stackWidget->setCurrentIndex(ConfigGadgetWidget::Input);
ConfigInputWidget *inputWidget = dynamic_cast<ConfigInputWidget *>(stackWidget->getWidget(ConfigGadgetWidget::Input));
Q_ASSERT(inputWidget);
inputWidget->startInputWizard();
}
void ConfigGadgetWidget::saveState(QSettings *settings)
{
settings->setValue("currentIndex", stackWidget->currentIndex());
}
void ConfigGadgetWidget::restoreState(QSettings *settings)
{
int index = settings->value("currentIndex", 0).toInt();
stackWidget->setCurrentIndex(index);
}
void ConfigGadgetWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
}
void ConfigGadgetWidget::onAutopilotDisconnect()
{
QWidget *qwd = new DefaultAttitudeWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd);
qwd = new DefaultHwSettingsWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd);
emit autopilotDisconnected();
}
void ConfigGadgetWidget::onAutopilotConnect()
{
qDebug() << "ConfigGadgetWidget onAutopilotConnect";
// First of all, check what Board type we are talking to, and
// if necessary, remove/add tabs in the config gadget:
// qDebug() << "ConfigGadgetWidget::onAutopilotConnect";
// Check what Board type we are talking to, and if necessary, remove/add tabs in the config gadget
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
if (utilMngr) {
int board = utilMngr->getBoardModel();
if ((board & 0xff00) == 0x0400) {
// CopterControl family
QWidget *qwd = new ConfigCCAttitudeWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd);
qwd = new ConfigCCHWWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd);
ConfigTaskWidget *widget;
widget = new ConfigCCAttitudeWidget(this);
widget->bind();
stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget);
widget = new ConfigCCHWWidget(this);
widget->bind();
stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget);
} else if ((board & 0xff00) == 0x0900) {
// Revolution family
QWidget *qwd = new ConfigRevoWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd);
ConfigTaskWidget *widget;
widget = new ConfigRevoWidget(this);
widget->bind();
stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget);
if (board == 0x0903 || board == 0x0904) {
qwd = new ConfigRevoHWWidget(this);
widget = new ConfigRevoHWWidget(this);
} else if (board == 0x0905) {
qwd = new ConfigRevoNanoHWWidget(this);
widget = new ConfigRevoNanoHWWidget(this);
}
stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd);
widget->bind();
stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget);
} else if ((board & 0xff00) == 0x9200) {
// Sparky2
QWidget *qwd = new ConfigRevoWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd);
qwd = new ConfigSparky2HWWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd);
ConfigTaskWidget *widget;
widget = new ConfigRevoWidget(this);
widget->bind();
stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget);
widget = new ConfigSparky2HWWidget(this);
widget->bind();
stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget);
} else {
// Unknown board
qDebug() << "Unknown board " << board;
qWarning() << "Unknown board " << board;
}
}
emit autopilotConnected();
}
void ConfigGadgetWidget::tabAboutToChange(int i, bool *proceed)
void ConfigGadgetWidget::onAutopilotDisconnect()
{
Q_UNUSED(i);
// qDebug() << "ConfigGadgetWidget::onAutopilotDiconnect";
QWidget *widget;
widget = new DefaultConfigWidget(this, tr("Attitude"));
stackWidget->replaceTab(ConfigGadgetWidget::Sensors, widget);
widget = new DefaultConfigWidget(this, tr("Hardware"));
stackWidget->replaceTab(ConfigGadgetWidget::Hardware, widget);
}
void ConfigGadgetWidget::onOPLinkConnect()
{
// qDebug() << "ConfigGadgetWidget::onOPLinkConnect";
ConfigTaskWidget *widget = new ConfigOPLinkWidget(this);
widget->bind();
stackWidget->replaceTab(ConfigGadgetWidget::OPLink, widget);
}
void ConfigGadgetWidget::onOPLinkDisconnect()
{
// qDebug() << "ConfigGadgetWidget::onOPLinkDisconnect";
QWidget *widget = new DefaultConfigWidget(this, tr("OPLink Configuration"));
stackWidget->replaceTab(ConfigGadgetWidget::OPLink, widget);
}
void ConfigGadgetWidget::tabAboutToChange(int index, bool *proceed)
{
Q_UNUSED(index);
*proceed = true;
ConfigTaskWidget *wid = qobject_cast<ConfigTaskWidget *>(stackWidget->currentWidget());
if (!wid) {
return;
}
if (wid->isDirty()) {
int ans = QMessageBox::warning(this, tr("Unsaved changes"), tr("The tab you are leaving has unsaved changes,"
int ans = QMessageBox::warning(this, tr("Unsaved changes"), tr("The tab you are leaving has unsaved changes, "
"if you proceed they will be lost.\n"
"Do you still want to proceed?"), QMessageBox::Yes, QMessageBox::No);
if (ans == QMessageBox::No) {
@ -236,35 +287,3 @@ void ConfigGadgetWidget::tabAboutToChange(int i, bool *proceed)
}
}
}
/*!
\brief Called by updates to @OPLinkStatus
*/
void ConfigGadgetWidget::updateOPLinkStatus(UAVObject *)
{
// Restart the disconnection timer.
oplinkTimeout->start(5000);
if (!oplinkConnected) {
qDebug() << "ConfigGadgetWidget onOPLinkConnect";
QIcon *icon = new QIcon();
icon->addFile(":/configgadget/images/pipx-normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/pipx-selected.png", QSize(), QIcon::Selected, QIcon::Off);
QWidget *qwd = new ConfigOPLinkWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::oplink, qwd, *icon, QString("OPLink"));
oplinkConnected = true;
}
}
void ConfigGadgetWidget::onOPLinkDisconnect()
{
qDebug() << "ConfigGadgetWidget onOPLinkDisconnect";
oplinkTimeout->stop();
oplinkConnected = false;
if (stackWidget->currentIndex() == ConfigGadgetWidget::oplink) {
stackWidget->setCurrentIndex(0);
}
stackWidget->removeTab(ConfigGadgetWidget::oplink);
}

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file configgadgetwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -27,53 +28,39 @@
#ifndef CONFIGGADGETWIDGET_H
#define CONFIGGADGETWIDGET_H
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "objectpersistence.h"
#include "utils/pathutils.h"
#include "utils/mytabbedstackwidget.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include <QWidget>
#include <QList>
#include <QTextBrowser>
#include <QMessageBox>
class QTextBrowser;
class QSettings;
class MyTabbedStackWidget;
class ConfigGadgetWidget : public QWidget {
Q_OBJECT
QTextBrowser *help;
public:
enum WidgetTabs { Hardware = 0, Aircraft, Input, Output, Sensors, Stabilization, CameraStabilization, TxPid, OPLink };
ConfigGadgetWidget(QWidget *parent = 0);
~ConfigGadgetWidget();
enum widgetTabs { hardware = 0, aircraft, input, output, sensors, stabilization, camerastabilization, txpid, oplink };
void startInputWizard();
public slots:
void onAutopilotConnect();
void onAutopilotDisconnect();
void tabAboutToChange(int i, bool *);
void updateOPLinkStatus(UAVObject *object);
void onOPLinkDisconnect();
signals:
void autopilotConnected();
void autopilotDisconnected();
void oplinkConnect();
void oplinkDisconnect();
void saveState(QSettings *settings);
void restoreState(QSettings *settings);
protected:
void resizeEvent(QResizeEvent *event);
private slots:
void onAutopilotConnect();
void onAutopilotDisconnect();
void onOPLinkConnect();
void onOPLinkDisconnect();
void tabAboutToChange(int index, bool *proceed);
private:
UAVDataObject *oplinkStatusObj;
// A timer that timesout the connction to the OPLink.
QTimer *oplinkTimeout;
bool oplinkConnected;
MyTabbedStackWidget *stackWidget;
QTextBrowser *help;
};
#endif // CONFIGGADGETWIDGET_H

View File

@ -8,7 +8,7 @@
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Servo input/output configuration panel for the config gadget
* @brief Servo input configuration panel for the config gadget
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -28,11 +28,6 @@
#include "configinputwidget.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include <utils/stylehelper.h>
#include <uavobjecthelper.h>
#include "ui_input.h"
#include "ui_input_wizard.h"
@ -42,18 +37,15 @@
#include "failsafechannelform.h"
#include "ui_failsafechannelform.h"
#include <uavobjectmanager.h>
#include <uavobjecthelper.h>
#include <utils/stylehelper.h>
#include <systemalarms.h>
#include <QDebug>
#include <QStringList>
#include <QWidget>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDesktopServices>
#include <QUrl>
#include <QMessageBox>
#include <QEventLoop>
#include <QGraphicsSvgItem>
#include <QSvgRenderer>
@ -85,6 +77,16 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
accessoryDesiredObj2(NULL),
accessoryDesiredObj3(NULL)
{
ui = new Ui_InputWidget();
ui->setupUi(this);
// must be done before auto binding !
setWikiURL("Input+Configuration");
addAutoBindings();
connect(this, SIGNAL(enableControlsChanged(bool)), this, SLOT(enableControlsChanged(bool)));
manualCommandObj = ManualControlCommand::GetInstance(getObjectManager());
manualSettingsObj = ManualControlSettings::GetInstance(getObjectManager());
flightModeSettingsObj = FlightModeSettings::GetInstance(getObjectManager());
@ -101,22 +103,6 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
// The other instances are populated lazily.
Q_ASSERT(accessoryDesiredObj0);
ui = new Ui_InputWidget();
ui->setupUi(this);
wizardUi = new Ui_InputWizardWidget();
wizardUi->setupUi(ui->wizard);
addApplySaveButtons(ui->saveRCInputToRAM, ui->saveRCInputToSD);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
ui->saveRCInputToRAM->setVisible(false);
}
addApplySaveButtons(ui->saveRCInputToRAM, ui->saveRCInputToSD);
// Generate the rows of buttons in the input channel form GUI
quint32 index = 0;
quint32 indexRT = 0;
@ -203,10 +189,6 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
connect(ui->stackedWidget, SIGNAL(currentChanged(int)), this, SLOT(disableWizardButton(int)));
connect(ui->runCalibration, SIGNAL(toggled(bool)), this, SLOT(simpleCalibration(bool)));
connect(wizardUi->wzNext, SIGNAL(clicked()), this, SLOT(wzNext()));
connect(wizardUi->wzCancel, SIGNAL(clicked()), this, SLOT(wzCancel()));
connect(wizardUi->wzBack, SIGNAL(clicked()), this, SLOT(wzBack()));
connect(ReceiverActivity::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateReceiverActivityStatus()));
ui->receiverActivityStatus->setStyleSheet("QLabel { background-color: darkGreen; color: rgb(255, 255, 255); \
border: 1px solid grey; border-radius: 5; margin:1px; font:bold;}");
@ -258,19 +240,17 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
connect(ui->failsafeFlightMode, SIGNAL(currentIndexChanged(int)), this, SLOT(failsafeFlightModeChanged(int)));
connect(ui->failsafeFlightModeCb, SIGNAL(toggled(bool)), this, SLOT(failsafeFlightModeCbToggled(bool)));
connect(this, SIGNAL(enableControlsChanged(bool)), this, SLOT(enableControlsChanged(bool)));
addWidget(ui->configurationWizard);
addWidget(ui->runCalibration);
addWidget(ui->failsafeFlightModeCb);
autoLoadWidgets();
// Wizard
wizardUi = new Ui_InputWizardWidget();
wizardUi->setupUi(ui->wizard);
populateWidgets();
refreshWidgetsValues();
// Connect the help button
connect(ui->inputHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
connect(wizardUi->wzNext, SIGNAL(clicked()), this, SLOT(wzNext()));
connect(wizardUi->wzCancel, SIGNAL(clicked()), this, SLOT(wzCancel()));
connect(wizardUi->wzBack, SIGNAL(clicked()), this, SLOT(wzBack()));
wizardUi->graphicsView->setScene(new QGraphicsScene(this));
wizardUi->graphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
@ -451,8 +431,6 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
groundChannelOrder << ManualControlSettings::CHANNELGROUPS_THROTTLE <<
ManualControlSettings::CHANNELGROUPS_YAW <<
ManualControlSettings::CHANNELGROUPS_ACCESSORY0;
updateEnableControls();
}
void ConfigInputWidget::buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits)
@ -504,12 +482,6 @@ void ConfigInputWidget::resizeEvent(QResizeEvent *event)
wizardUi->graphicsView->fitInView(m_txBackground, Qt::KeepAspectRatio);
}
void ConfigInputWidget::openHelp()
{
QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Input+Configuration"),
QUrl::StrictMode));
}
void ConfigInputWidget::goToWizard()
{
QMessageBox msgBox;
@ -1964,8 +1936,8 @@ void ConfigInputWidget::simpleCalibration(bool enable)
{
if (enable) {
ui->configurationWizard->setEnabled(false);
ui->saveRCInputToRAM->setEnabled(false);
ui->saveRCInputToSD->setEnabled(false);
ui->applyButton->setEnabled(false);
ui->saveButton->setEnabled(false);
ui->runCalibration->setText(tr("Stop Manual Calibration"));
throttleError = false;
@ -2042,8 +2014,8 @@ void ConfigInputWidget::simpleCalibration(bool enable)
actuatorSettingsObj->setData(memento.actuatorSettingsData);
ui->configurationWizard->setEnabled(true);
ui->saveRCInputToRAM->setEnabled(true);
ui->saveRCInputToSD->setEnabled(true);
ui->applyButton->setEnabled(true);
ui->saveButton->setEnabled(true);
ui->runCalibration->setText(tr("Start Manual Calibration"));
disconnect(manualCommandObj, SIGNAL(objectUnpacked(UAVObject *)), this, SLOT(updateCalibration()));
@ -2199,5 +2171,5 @@ void ConfigInputWidget::failsafeFlightModeCbToggled(bool checked)
void ConfigInputWidget::enableControlsChanged(bool enabled)
{
ui->failsafeFlightMode->setEnabled(enabled && ui->failsafeFlightMode->currentIndex() != -1);
ui->failsafeFlightMode->setEnabled(enabled && (ui->failsafeFlightMode->currentIndex() != -1));
}

View File

@ -8,7 +8,7 @@
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Servo input/output configuration panel for the config gadget
* @brief Servo input configuration panel for the config gadget
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -29,8 +29,7 @@
#define CONFIGINPUTWIDGET_H
#include "uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "manualcontrolcommand.h"
@ -212,7 +211,6 @@ private slots:
void wzCancel();
void goToWizard();
void disableWizardButton(int);
void openHelp();
void identifyControls();
void identifyLimits();
void moveTxControls();

View File

@ -8,7 +8,7 @@
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief The Configuration Gadget used to configure the OPLink and Revo modem
* @brief The Configuration Gadget used to configure the OPLink, Revo and Sparky2 modems
***************************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -30,14 +30,13 @@
#include "ui_oplink.h"
#include <coreplugin/generalsettings.h>
#include <uavobjectmanager.h>
#include <uavobjectutilmanager.h>
#include <oplinksettings.h>
#include <oplinkstatus.h>
#include <QMessageBox>
#include <QDateTime>
#include <QDebug>
// Channel range and Frequency display
static const int MAX_CHANNEL_NUM = 250;
@ -45,40 +44,45 @@ static const int MIN_CHANNEL_RANGE = 10;
static const float FIRST_FREQUENCY = 430.000;
static const float FREQUENCY_STEP = 0.040;
ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(parent)
ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(parent, false), statusUpdated(false)
{
m_oplink = new Ui_OPLinkWidget();
m_oplink->setupUi(this);
// Connect to the OPLinkStatus object updates
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
oplinkStatusObj = dynamic_cast<UAVDataObject *>(objManager->getObject("OPLinkStatus"));
// must be done before auto binding !
setWikiURL("OPLink+Configuration");
addAutoBindings();
disableMouseWheelEvents();
connect(this, SIGNAL(connected()), this, SLOT(connected()));
oplinkStatusObj = dynamic_cast<OPLinkStatus *>(getObject("OPLinkStatus"));
Q_ASSERT(oplinkStatusObj);
connect(oplinkStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateStatus(UAVObject *)));
// Connect to the OPLinkSettings object updates
oplinkSettingsObj = dynamic_cast<OPLinkSettings *>(objManager->getObject("OPLinkSettings"));
oplinkSettingsObj = dynamic_cast<OPLinkSettings *>(getObject("OPLinkSettings"));
Q_ASSERT(oplinkSettingsObj);
connect(oplinkSettingsObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateSettings(UAVObject *)));
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
m_oplink->Apply->setVisible(false);
}
addApplySaveButtons(m_oplink->Apply, m_oplink->Save);
addWidget(m_oplink->FirmwareVersion);
addWidget(m_oplink->SerialNumber);
addWidget(m_oplink->MinFreq);
addWidget(m_oplink->MaxFreq);
addWidget(m_oplink->UnbindButton);
addWidget(m_oplink->PairSignalStrengthBar1);
addWidget(m_oplink->PairSignalStrengthLabel1);
addWidgetBinding("OPLinkSettings", "Protocol", m_oplink->Protocol);
addWidgetBinding("OPLinkSettings", "LinkType", m_oplink->LinkType);
addWidgetBinding("OPLinkSettings", "CoordID", m_oplink->CoordID);
addWidgetBinding("OPLinkSettings", "CustomDeviceID", m_oplink->CustomDeviceID);
addWidgetBinding("OPLinkSettings", "MinChannel", m_oplink->MinimumChannel);
addWidgetBinding("OPLinkSettings", "MaxChannel", m_oplink->MaximumChannel);
addWidgetBinding("OPLinkSettings", "MaxRFPower", m_oplink->MaxRFTxPower);
addWidgetBinding("OPLinkSettings", "ComSpeed", m_oplink->ComSpeed);
addWidgetBinding("OPLinkSettings", "MainPort", m_oplink->MainPort);
addWidgetBinding("OPLinkSettings", "FlexiPort", m_oplink->FlexiPort);
addWidgetBinding("OPLinkSettings", "VCPPort", m_oplink->VCPPort);
addWidgetBinding("OPLinkSettings", "MaxRFPower", m_oplink->MaxRFTxPower);
addWidgetBinding("OPLinkSettings", "MinChannel", m_oplink->MinimumChannel);
addWidgetBinding("OPLinkSettings", "MaxChannel", m_oplink->MaximumChannel);
addWidgetBinding("OPLinkSettings", "CoordID", m_oplink->CoordID);
addWidgetBinding("OPLinkSettings", "Protocol", m_oplink->Protocol);
addWidgetBinding("OPLinkSettings", "LinkType", m_oplink->LinkType);
addWidgetBinding("OPLinkSettings", "ComSpeed", m_oplink->ComSpeed);
addWidgetBinding("OPLinkSettings", "CustomDeviceID", m_oplink->CustomDeviceID);
addWidgetBinding("OPLinkStatus", "DeviceID", m_oplink->DeviceID);
addWidgetBinding("OPLinkStatus", "RxGood", m_oplink->Good);
@ -101,12 +105,14 @@ ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(paren
addWidgetBinding("OPLinkStatus", "RXPacketRate", m_oplink->RXPacketRate);
addWidgetBinding("OPLinkStatus", "TXPacketRate", m_oplink->TXPacketRate);
// initially hide port combo boxes
setPortsVisible(false);
// Connect the selection changed signals.
connect(m_oplink->Protocol, SIGNAL(currentIndexChanged(int)), this, SLOT(protocolChanged()));
connect(m_oplink->LinkType, SIGNAL(currentIndexChanged(int)), this, SLOT(linkTypeChanged()));
connect(m_oplink->MinimumChannel, SIGNAL(valueChanged(int)), this, SLOT(minChannelChanged()));
connect(m_oplink->MaximumChannel, SIGNAL(valueChanged(int)), this, SLOT(maxChannelChanged()));
connect(m_oplink->CustomDeviceID, SIGNAL(editingFinished()), this, SLOT(updateCustomDeviceID()));
connect(m_oplink->MainPort, SIGNAL(currentIndexChanged(int)), this, SLOT(mainPortChanged()));
connect(m_oplink->FlexiPort, SIGNAL(currentIndexChanged(int)), this, SLOT(flexiPortChanged()));
connect(m_oplink->VCPPort, SIGNAL(currentIndexChanged(int)), this, SLOT(vcpPortChanged()));
@ -114,164 +120,143 @@ ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(paren
// Connect the Unbind button
connect(m_oplink->UnbindButton, SIGNAL(released()), this, SLOT(unbind()));
m_oplink->CustomDeviceID->setInputMask("HHHHHHHH");
m_oplink->CoordID->setInputMask("HHHHHHHH");
// all upper case hex
m_oplink->CustomDeviceID->setInputMask(">HHHHHHHH");
m_oplink->CustomDeviceID->setPlaceholderText("AutoGen");
m_oplink->CoordID->setInputMask(">HHHHHHHH");
m_oplink->MinimumChannel->setKeyboardTracking(false);
m_oplink->MaximumChannel->setKeyboardTracking(false);
m_oplink->MaximumChannel->setMaximum(MAX_CHANNEL_NUM);
m_oplink->MinimumChannel->setMaximum(MAX_CHANNEL_NUM - MIN_CHANNEL_RANGE);
// Request and update of the setting object.
settingsUpdated = false;
setWikiURL("OPLink+Configuration");
autoLoadWidgets();
disableMouseWheelEvents();
updateEnableControls();
}
ConfigOPLinkWidget::~ConfigOPLinkWidget()
{}
/*!
\brief Called by updates to @OPLinkStatus
*/
void ConfigOPLinkWidget::updateStatus(UAVObject *object)
void ConfigOPLinkWidget::connected()
{
// qDebug() << "ConfigOPLinkWidget::connected()";
statusUpdated = false;
// Request and update of the setting object if we haven't received it yet.
if (!settingsUpdated) {
oplinkSettingsObj->requestUpdate();
// this is only really needed for OPLM
oplinkSettingsObj->requestUpdate();
updateSettings();
}
void ConfigOPLinkWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
// qDebug() << "ConfigOPLinkWidget::refreshWidgetsValuesImpl()" << obj;
if (obj == oplinkStatusObj) {
updateStatus();
} else if (obj == oplinkSettingsObj) {
updateSettings();
}
}
void ConfigOPLinkWidget::updateStatus()
{
// qDebug() << "ConfigOPLinkWidget::updateStatus";
// Update the link state
UAVObjectField *linkField = object->getField("LinkState");
UAVObjectField *linkField = oplinkStatusObj->getField("LinkState");
m_oplink->LinkState->setText(linkField->getValue().toString());
bool linkConnected = (linkField->getValue() == linkField->getOptions().at(OPLinkStatus::LINKSTATE_CONNECTED));
bool linkConnected = (oplinkStatusObj->linkState() == OPLinkStatus_LinkState::Connected);
m_oplink->PairSignalStrengthBar1->setValue(linkConnected ? m_oplink->RSSI->text().toInt() : -127);
m_oplink->PairSignalStrengthLabel1->setText(QString("%1dB").arg(m_oplink->PairSignalStrengthBar1->value()));
// Enable components based on the board type connected.
switch (oplinkStatusObj->boardType()) {
case 0x09: // Revolution, DiscoveryF4Bare, RevoNano, RevoProto
case 0x92: // Sparky2
setPortsVisible(false);
break;
case 0x03: // OPLinkMini
setPortsVisible(true);
break;
default:
// This shouldn't happen.
break;
}
if (!statusUpdated) {
statusUpdated = true;
// update static info
updateInfo();
}
}
void ConfigOPLinkWidget::setPortsVisible(bool visible)
{
m_oplink->MainPort->setVisible(visible);
m_oplink->MainPortLabel->setVisible(visible);
m_oplink->FlexiPort->setVisible(visible);
m_oplink->FlexiPortLabel->setVisible(visible);
m_oplink->VCPPort->setVisible(visible);
m_oplink->VCPPortLabel->setVisible(visible);
}
void ConfigOPLinkWidget::updateInfo()
{
// qDebug() << "ConfigOPLinkWidget::updateInfo";
// Update the Description field
// TODO use UAVObjectUtilManager::descriptionToStructure()
UAVObjectField *descField = object->getField("Description");
if (descField->getValue(0) != QChar(255)) {
/*
* This looks like a binary with a description at the end:
* 4 bytes: header: "OpFw".
* 4 bytes: GIT commit tag (short version of SHA1).
* 4 bytes: Unix timestamp of compile time.
* 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files.
* 26 bytes: commit tag if it is there, otherwise branch name. '-dirty' may be added if needed. Zero-padded.
* 20 bytes: SHA1 sum of the firmware.
* 20 bytes: SHA1 sum of the uavo definitions.
* 20 bytes: free for now.
*/
char buf[OPLinkStatus::DESCRIPTION_NUMELEM];
for (unsigned int i = 0; i < 26; ++i) {
buf[i] = descField->getValue(i + 14).toChar().toLatin1();
}
buf[26] = '\0';
QString descstr(buf);
quint32 gitDate = descField->getValue(11).toChar().toLatin1() & 0xFF;
for (int i = 1; i < 4; i++) {
gitDate = gitDate << 8;
gitDate += descField->getValue(11 - i).toChar().toLatin1() & 0xFF;
}
QString date = QDateTime::fromTime_t(gitDate).toUTC().toString("yyyy-MM-dd HH:mm");
m_oplink->FirmwareVersion->setText(descstr + " " + date);
quint8 *desc = oplinkStatusObj->getData().Description;
// extract desc into byte array
QByteArray ba;
for (unsigned int i = 0; i < OPLinkStatus::DESCRIPTION_NUMELEM; i++) {
ba.append(desc[i]);
}
// parse byte array intto device descriptor
deviceDescriptorStruct dds;
UAVObjectUtilManager::descriptionToStructure(ba, dds);
// update UI
if (!dds.gitTag.isEmpty()) {
m_oplink->FirmwareVersion->setText(dds.gitTag + " " + dds.gitDate);
} else {
m_oplink->FirmwareVersion->setText(tr("Unknown"));
}
// Update the serial number field
UAVObjectField *serialField = object->getField("CPUSerial");
char buf[OPLinkStatus::CPUSERIAL_NUMELEM * 2 + 1];
for (unsigned int i = 0; i < OPLinkStatus::CPUSERIAL_NUMELEM; ++i) {
unsigned char val = serialField->getValue(i).toUInt() >> 4;
unsigned char val = oplinkStatusObj->cpuSerial(i) >> 4;
buf[i * 2] = ((val < 10) ? '0' : '7') + val;
val = serialField->getValue(i).toUInt() & 0xf;
val = oplinkStatusObj->cpuSerial(i) & 0xf;
buf[i * 2 + 1] = ((val < 10) ? '0' : '7') + val;
}
buf[OPLinkStatus::CPUSERIAL_NUMELEM * 2] = '\0';
m_oplink->SerialNumber->setText(buf);
updateEnableControls();
}
/*!
\brief Called by updates to @OPLinkSettings
*/
void ConfigOPLinkWidget::updateSettings(UAVObject *object)
void ConfigOPLinkWidget::updateSettings()
{
Q_UNUSED(object);
// qDebug() << "ConfigOPLinkWidget::updateSettings";
if (!settingsUpdated) {
settingsUpdated = true;
// Enable components based on the board type connected.
UAVObjectField *board_type_field = oplinkStatusObj->getField("BoardType");
switch (board_type_field->getValue().toInt()) {
case 0x09: // Revolution, DiscoveryF4Bare, RevoNano, RevoProto
case 0x92: // Sparky2
m_oplink->MainPort->setVisible(false);
m_oplink->MainPortLabel->setVisible(false);
m_oplink->FlexiPort->setVisible(false);
m_oplink->FlexiPortLabel->setVisible(false);
m_oplink->VCPPort->setVisible(false);
m_oplink->VCPPortLabel->setVisible(false);
m_oplink->LinkType->setEnabled(true);
break;
case 0x03: // OPLinkMini
m_oplink->MainPort->setVisible(true);
m_oplink->MainPortLabel->setVisible(true);
m_oplink->FlexiPort->setVisible(true);
m_oplink->FlexiPortLabel->setVisible(true);
m_oplink->VCPPort->setVisible(true);
m_oplink->VCPPortLabel->setVisible(true);
m_oplink->LinkType->setEnabled(true);
break;
default:
// This shouldn't happen.
break;
}
updateEnableControls();
}
}
void ConfigOPLinkWidget::updateEnableControls()
{
enableControls(true);
updateCustomDeviceID();
updateCoordID();
protocolChanged();
}
void ConfigOPLinkWidget::disconnected()
{
if (settingsUpdated) {
settingsUpdated = false;
}
}
void ConfigOPLinkWidget::protocolChanged()
{
bool is_enabled = !isComboboxOptionSelected(m_oplink->Protocol, OPLinkSettings::PROTOCOL_DISABLED);
bool is_coordinator = isComboboxOptionSelected(m_oplink->Protocol, OPLinkSettings::PROTOCOL_OPLINKCOORDINATOR);
bool is_receiver = isComboboxOptionSelected(m_oplink->Protocol, OPLinkSettings::PROTOCOL_OPLINKRECEIVER);
bool is_openlrs = isComboboxOptionSelected(m_oplink->Protocol, OPLinkSettings::PROTOCOL_OPENLRS);
bool is_ppm_only = isComboboxOptionSelected(m_oplink->LinkType, OPLinkSettings::LINKTYPE_CONTROL);
bool is_oplm = m_oplink->MainPort->isVisible();
bool is_bound = (m_oplink->CoordID->text() != "");
m_oplink->ComSpeed->setEnabled(!is_ppm_only && !is_openlrs && is_enabled);
m_oplink->CoordID->setEnabled(is_receiver & is_enabled);
m_oplink->UnbindButton->setEnabled(is_bound && !is_coordinator && is_enabled);
m_oplink->ComSpeed->setEnabled(is_enabled && !is_ppm_only && !is_openlrs);
m_oplink->CoordID->setEnabled(is_enabled && is_receiver);
m_oplink->UnbindButton->setEnabled(is_enabled && is_bound && !is_coordinator);
m_oplink->CustomDeviceID->setEnabled(is_coordinator);
m_oplink->MinimumChannel->setEnabled(is_receiver || is_coordinator);
m_oplink->MaximumChannel->setEnabled(is_receiver || is_coordinator);
m_oplink->MainPort->setEnabled(is_oplm);
m_oplink->FlexiPort->setEnabled(is_oplm);
m_oplink->VCPPort->setEnabled(is_oplm);
enableComboBoxOptionItem(m_oplink->VCPPort, OPLinkSettings::VCPPORT_SERIAL, (is_receiver || is_coordinator));
@ -283,9 +268,14 @@ void ConfigOPLinkWidget::protocolChanged()
m_oplink->MaxRFTxPower->setEnabled(is_enabled && !is_openlrs);
}
void ConfigOPLinkWidget::protocolChanged()
{
updateSettings();
}
void ConfigOPLinkWidget::linkTypeChanged()
{
protocolChanged();
updateSettings();
}
void ConfigOPLinkWidget::minChannelChanged()
@ -395,45 +385,18 @@ void ConfigOPLinkWidget::vcpPortChanged()
}
}
void ConfigOPLinkWidget::updateCoordID()
{
bool coordinatorNotSet = (m_oplink->CoordID->text() == "0");
if (settingsUpdated && coordinatorNotSet) {
m_oplink->CoordID->clear();
}
}
void ConfigOPLinkWidget::updateCustomDeviceID()
{
bool customDeviceIDNotSet = (m_oplink->CustomDeviceID->text() == "0");
if (settingsUpdated && customDeviceIDNotSet) {
m_oplink->CustomDeviceID->clear();
m_oplink->CustomDeviceID->setPlaceholderText("AutoGen");
}
}
void ConfigOPLinkWidget::unbind()
{
if (settingsUpdated) {
// Clear the coordinator ID
oplinkSettingsObj->getField("CoordID")->setValue(0);
m_oplink->CoordID->setText("0");
// Clear the coordinator ID
oplinkSettingsObj->setCoordID(0);
m_oplink->CoordID->clear();
// Clear the OpenLRS settings
oplinkSettingsObj->getField("Version")->setValue(0);
oplinkSettingsObj->getField("SerialBaudrate")->setValue(0);
oplinkSettingsObj->getField("RFFrequency")->setValue(0);
oplinkSettingsObj->getField("RFPower")->setValue(0);
oplinkSettingsObj->getField("RFChannelSpacing")->setValue(0);
oplinkSettingsObj->getField("ModemParams")->setValue(0);
oplinkSettingsObj->getField("Flags")->setValue(0);
}
// Clear the OpenLRS settings
oplinkSettingsObj->setVersion((quint16)0);
oplinkSettingsObj->setSerialBaudrate(0);
oplinkSettingsObj->setRFFrequency(0);
oplinkSettingsObj->setRFPower((quint16)0);
oplinkSettingsObj->setRFChannelSpacing((quint16)0);
oplinkSettingsObj->setModemParams((quint16)0);
oplinkSettingsObj->setFlags((quint16)0);
}
/**
@}
@}
*/

View File

@ -8,7 +8,7 @@
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief The Configuration Gadget used to configure the OPLink and Revo modem
* @brief The Configuration Gadget used to configure the OPLink, Revo and Sparky2 modems
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -30,7 +30,8 @@
#include "configtaskwidget.h"
#include "oplinksettings.h"
class OPLinkStatus;
class OPLinkSettings;
class Ui_OPLinkWidget;
@ -41,38 +42,39 @@ public:
ConfigOPLinkWidget(QWidget *parent = 0);
~ConfigOPLinkWidget();
public slots:
void updateStatus(UAVObject *object1);
void updateSettings(UAVObject *object1);
protected:
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
private:
Ui_OPLinkWidget *m_oplink;
// The OPLink status UAVObject
UAVDataObject *oplinkStatusObj;
// The OPLink ssettins UAVObject
OPLinkStatus *oplinkStatusObj;
OPLinkSettings *oplinkSettingsObj;
// Are the settings current?
bool settingsUpdated;
// Is the status current?
bool statusUpdated;
protected:
void updateEnableControls();
void updateStatus();
void updateInfo();
void updateSettings();
void setPortsVisible(bool visible);
private slots:
void disconnected();
void linkTypeChanged();
void connected();
void protocolChanged();
void linkTypeChanged();
void minChannelChanged();
void maxChannelChanged();
void updateCoordID();
void updateCustomDeviceID();
void unbind();
void channelChanged(bool isMax);
void mainPortChanged();
void flexiPortChanged();
void vcpPortChanged();
void unbind();
};
#endif // CONFIGOPLINKWIDGET_H

View File

@ -36,7 +36,6 @@
#include "uavsettingsimportexport/uavsettingsimportexportfactory.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include <uavobjecthelper.h>
#include "mixersettings.h"
@ -50,35 +49,27 @@
#include <QStringList>
#include <QWidget>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QPushButton>
#include <QMessageBox>
#include <QDesktopServices>
#include <QUrl>
ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(parent)
{
m_ui = new Ui_OutputWidget();
m_ui->setupUi(this);
// must be done before auto binding !
setWikiURL("Output+Configuration");
addAutoBindings();
m_ui->gvFrame->setVisible(false);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
m_ui->saveRCOutputToRAM->setVisible(false);
}
UAVSettingsImportExportFactory *importexportplugin = pm->getObject<UAVSettingsImportExportFactory>();
connect(importexportplugin, SIGNAL(importAboutToBegin()), this, SLOT(stopTests()));
connect(m_ui->channelOutTest, SIGNAL(clicked(bool)), this, SLOT(runChannelTests(bool)));
// Configure the task widget
// Connect the help button
connect(m_ui->outputHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
addApplySaveButtons(m_ui->saveRCOutputToRAM, m_ui->saveRCOutputToSD);
// Track the ActuatorSettings object
addUAVObject("ActuatorSettings");
@ -99,7 +90,6 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
addWidget(form->ui->actuatorLink);
}
// Associate the buttons with their UAVO fields
addWidget(m_ui->spinningArmed);
connect(m_ui->spinningArmed, SIGNAL(clicked(bool)), this, SLOT(updateSpinStabilizeCheckComboBoxes()));
@ -137,12 +127,8 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
SystemAlarms *systemAlarmsObj = SystemAlarms::GetInstance(getObjectManager());
connect(systemAlarmsObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateWarnings(UAVObject *)));
// TODO why do we do that ?
disconnect(this, SLOT(refreshWidgetsValues(UAVObject *)));
populateWidgets();
refreshWidgetsValues();
updateEnableControls();
}
ConfigOutputWidget::~ConfigOutputWidget()
@ -314,11 +300,9 @@ void ConfigOutputWidget::setColor(QWidget *widget, const QColor color)
/**
Request the current config from the board (RC Output)
*/
void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj)
void ConfigOutputWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
bool dirty = isDirty();
ConfigTaskWidget::refreshWidgetsValues(obj);
Q_UNUSED(obj);
// Get Actuator Settings
ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
@ -422,17 +406,13 @@ void ConfigOutputWidget::refreshWidgetsValues(UAVObject *obj)
}
updateSpinStabilizeCheckComboBoxes();
setDirty(dirty);
}
/**
* Sends the config to the board, without saving to the SD card (RC Output)
*/
void ConfigOutputWidget::updateObjectsFromWidgets()
void ConfigOutputWidget::updateObjectsFromWidgetsImpl()
{
ConfigTaskWidget::updateObjectsFromWidgets();
ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
Q_ASSERT(actuatorSettings);
@ -500,12 +480,6 @@ void ConfigOutputWidget::updateAlwaysStabilizeStatus()
}
}
void ConfigOutputWidget::openHelp()
{
QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Output+Configuration"),
QUrl::StrictMode));
}
void ConfigOutputWidget::onBankTypeChange()
{
QComboBox *bankModeCombo = qobject_cast<QComboBox *>(sender());

View File

@ -89,6 +89,9 @@ protected:
void enableControls(bool enable);
void setWarning(QString message);
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
private:
Ui_OutputWidget *m_ui;
QList<QSlider> m_sliders;
@ -107,11 +110,8 @@ private slots:
void updateSpinStabilizeCheckComboBoxes();
void updateAlwaysStabilizeStatus();
void stopTests();
virtual void refreshWidgetsValues(UAVObject *obj = NULL);
void updateObjectsFromWidgets();
void runChannelTests(bool state);
void sendChannelTest(int index, int value);
void openHelp();
void onBankTypeChange();
};

View File

@ -1,8 +1,9 @@
/**
******************************************************************************
*
* @file configplugin.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file configplugin.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -25,12 +26,15 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "configplugin.h"
#include "configgadgetfactory.h"
#include <extensionsystem/pluginmanager.h>
#include <uavobjects/uavobjectmanager.h>
#include <QtPlugin>
#include <QStringList>
#include <QTimer>
#include <extensionsystem/pluginmanager.h>
#include "objectpersistence.h"
ConfigPlugin::ConfigPlugin()
{
@ -46,7 +50,8 @@ bool ConfigPlugin::initialize(const QStringList & args, QString *errMsg)
{
Q_UNUSED(args);
Q_UNUSED(errMsg);
cf = new ConfigGadgetFactory(this);
ConfigGadgetFactory *cf = new ConfigGadgetFactory(this);
addAutoReleasedObject(cf);
return true;

View File

@ -1,8 +1,9 @@
/**
******************************************************************************
*
* @file configgadgetplugin.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file configplugin.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -28,14 +29,11 @@
#define CONFIGPLUGIN_H
#include <extensionsystem/iplugin.h>
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include "objectpersistence.h"
#include <QMessageBox>
#include <QString>
#include <QStringList>
class ConfigGadgetFactory;
class UAVObjectManager;
class ConfigPlugin : public ExtensionSystem::IPlugin {
Q_OBJECT
@ -49,9 +47,6 @@ public:
void extensionsInitialized();
bool initialize(const QStringList & arguments, QString *errorString);
void shutdown();
private:
ConfigGadgetFactory *cf;
};
#endif // CONFIGPLUGIN_H

View File

@ -2,7 +2,7 @@
******************************************************************************
*
* @file configrevohwwidget.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
@ -29,30 +29,21 @@
#include "ui_configrevohwwidget.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include <uavobjecthelper.h>
#include "hwsettings.h"
#include <QDebug>
#include <QDesktopServices>
#include <QUrl>
#include <QMessageBox>
ConfigRevoHWWidget::ConfigRevoHWWidget(QWidget *parent) : ConfigTaskWidget(parent), m_refreshing(true)
ConfigRevoHWWidget::ConfigRevoHWWidget(QWidget *parent) : ConfigTaskWidget(parent)
{
m_ui = new Ui_RevoHWWidget();
m_ui->setupUi(this);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
m_ui->saveTelemetryToRAM->setEnabled(false);
m_ui->saveTelemetryToRAM->setVisible(false);
}
// must be done before auto binding !
setWikiURL("Revolution+Configuration");
addApplySaveButtons(m_ui->saveTelemetryToRAM, m_ui->saveTelemetryToSD);
addAutoBindings();
addUAVObject("HwSettings");
addWidgetBinding("HwSettings", "RM_FlexiPort", m_ui->cbFlexi);
addWidgetBinding("HwSettings", "RM_MainPort", m_ui->cbMain);
@ -75,14 +66,7 @@ ConfigRevoHWWidget::ConfigRevoHWWidget(QWidget *parent) : ConfigTaskWidget(paren
addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbFlexiGPSProtocol);
addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbRcvrGPSProtocol);
connect(m_ui->cchwHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
setupCustomCombos();
enableControls(true);
populateWidgets();
refreshWidgetsValues();
forceConnectedState();
m_refreshing = false;
}
ConfigRevoHWWidget::~ConfigRevoHWWidget()
@ -104,37 +88,29 @@ void ConfigRevoHWWidget::setupCustomCombos()
connect(m_ui->cbRcvr, SIGNAL(currentIndexChanged(int)), this, SLOT(rcvrPortChanged(int)));
}
void ConfigRevoHWWidget::refreshWidgetsValues(UAVObject *obj)
void ConfigRevoHWWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
m_refreshing = true;
ConfigTaskWidget::refreshWidgetsValues(obj);
Q_UNUSED(obj);
usbVCPPortChanged(0);
mainPortChanged(0);
flexiPortChanged(0);
rcvrPortChanged(0);
m_refreshing = false;
}
void ConfigRevoHWWidget::updateObjectsFromWidgets()
void ConfigRevoHWWidget::updateObjectsFromWidgetsImpl()
{
ConfigTaskWidget::updateObjectsFromWidgets();
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields data = hwSettings->getData();
// If any port is configured to be GPS port, enable GPS module if it is not enabled.
// Otherwise disable GPS module.
quint8 enableModule = HwSettings::OPTIONALMODULES_DISABLED;
if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_GPS)
|| isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_GPS)) {
data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_ENABLED;
} else {
data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_DISABLED;
enableModule = HwSettings::OPTIONALMODULES_ENABLED;
}
UAVObjectUpdaterHelper updateHelper;
hwSettings->setData(data, false);
updateHelper.doObjectAndWait(hwSettings);
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_GPS, enableModule);
}
void ConfigRevoHWWidget::usbVCPPortChanged(int index)
@ -488,9 +464,3 @@ void ConfigRevoHWWidget::rcvrPortChanged(int index)
break;
}
}
void ConfigRevoHWWidget::openHelp()
{
QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Revolution+Configuration"),
QUrl::StrictMode));
}

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file configrevohwwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -42,14 +43,14 @@ public:
ConfigRevoHWWidget(QWidget *parent = 0);
~ConfigRevoHWWidget();
protected:
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
private:
Ui_RevoHWWidget *m_ui;
bool m_refreshing;
void setupCustomCombos();
protected slots:
void refreshWidgetsValues(UAVObject *obj = NULL);
void updateObjectsFromWidgets();
void setupCustomCombos();
private slots:
void usbVCPPortChanged(int index);
@ -57,7 +58,6 @@ private slots:
void flexiPortChanged(int index);
void mainPortChanged(int index);
void rcvrPortChanged(int index);
void openHelp();
};
#endif // CONFIGREVOHWWIDGET_H

View File

@ -121,9 +121,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-148</y>
<y>0</y>
<width>796</width>
<height>804</height>
<height>807</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
@ -548,7 +548,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="configgadget.qrc">:/configgadget/images/revolution_top.png</pixmap>
<pixmap>:/configgadget/images/revolution_top.png</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
@ -739,7 +739,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="cchwHelp">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -777,10 +777,13 @@
<property name="flat">
<bool>true</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:help</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveTelemetryToRAM">
<widget class="QPushButton" name="applyButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -879,10 +882,13 @@ Beware of not locking yourself out!</string>
<property name="checkable">
<bool>false</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveTelemetryToSD">
<widget class="QPushButton" name="saveButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -908,6 +914,9 @@ Beware of not locking yourself out!</string>
<property name="text">
<string>Save</string>
</property>
<property name="objrelation" stdset="0">
<string>button:save</string>
</property>
</widget>
</item>
</layout>

View File

@ -1,14 +1,14 @@
/**
******************************************************************************
*
* @file configrevohwwidget.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @file configrevonanohwwidget.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Revolution hardware configuration panel
* @brief Revolution Nano hardware configuration panel
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -29,32 +29,21 @@
#include "ui_configrevonanohwwidget.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include <uavobjecthelper.h>
#include "hwsettings.h"
#include <QDebug>
#include <QDesktopServices>
#include <QUrl>
#include <QMessageBox>
ConfigRevoNanoHWWidget::ConfigRevoNanoHWWidget(QWidget *parent) : ConfigTaskWidget(parent), m_refreshing(true)
ConfigRevoNanoHWWidget::ConfigRevoNanoHWWidget(QWidget *parent) : ConfigTaskWidget(parent)
{
m_ui = new Ui_RevoNanoHWWidget();
m_ui->setupUi(this);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
m_ui->saveTelemetryToRAM->setEnabled(false);
m_ui->saveTelemetryToRAM->setVisible(false);
}
// must be done before auto binding !
setWikiURL("Revo+Nano+Configuration");
addApplySaveButtons(m_ui->saveTelemetryToRAM, m_ui->saveTelemetryToSD);
addAutoBindings();
forceConnectedState();
addUAVObject("HwSettings");
addWidgetBinding("HwSettings", "RM_FlexiPort", m_ui->cbFlexi);
addWidgetBinding("HwSettings", "RM_MainPort", m_ui->cbMain);
@ -73,13 +62,7 @@ ConfigRevoNanoHWWidget::ConfigRevoNanoHWWidget(QWidget *parent) : ConfigTaskWidg
addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbMainGPSProtocol);
addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbFlexiGPSProtocol);
connect(m_ui->cchwHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
setupCustomCombos();
enableControls(true);
populateWidgets();
refreshWidgetsValues();
setDirty(false);
m_refreshing = false;
}
ConfigRevoNanoHWWidget::~ConfigRevoNanoHWWidget()
@ -97,37 +80,29 @@ void ConfigRevoNanoHWWidget::setupCustomCombos()
connect(m_ui->cbRcvr, SIGNAL(currentIndexChanged(int)), this, SLOT(rcvrPortChanged(int)));
}
void ConfigRevoNanoHWWidget::refreshWidgetsValues(UAVObject *obj)
void ConfigRevoNanoHWWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
m_refreshing = true;
ConfigTaskWidget::refreshWidgetsValues(obj);
Q_UNUSED(obj);
usbVCPPortChanged(0);
mainPortChanged(0);
flexiPortChanged(0);
rcvrPortChanged(0);
m_refreshing = false;
}
void ConfigRevoNanoHWWidget::updateObjectsFromWidgets()
void ConfigRevoNanoHWWidget::updateObjectsFromWidgetsImpl()
{
ConfigTaskWidget::updateObjectsFromWidgets();
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields data = hwSettings->getData();
// If any port is configured to be GPS port, enable GPS module if it is not enabled.
// Otherwise disable GPS module.
quint8 enableModule = HwSettings::OPTIONALMODULES_DISABLED;
if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::RM_FLEXIPORT_GPS)
|| isComboboxOptionSelected(m_ui->cbMain, HwSettings::RM_MAINPORT_GPS)) {
data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_ENABLED;
} else {
data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_DISABLED;
enableModule = HwSettings::OPTIONALMODULES_ENABLED;
}
UAVObjectUpdaterHelper updateHelper;
hwSettings->setData(data, false);
updateHelper.doObjectAndWait(hwSettings);
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_GPS, enableModule);
}
void ConfigRevoNanoHWWidget::usbVCPPortChanged(int index)
@ -279,9 +254,3 @@ void ConfigRevoNanoHWWidget::rcvrPortChanged(int index)
Q_UNUSED(index);
/* Nano has no USART at rcvrPort */
}
void ConfigRevoNanoHWWidget::openHelp()
{
QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Revo+Nano+Configuration"),
QUrl::StrictMode));
}

View File

@ -1,8 +1,9 @@
/**
******************************************************************************
*
* @file configrevohwwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file configrevonanohwwidget.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -42,14 +43,14 @@ public:
ConfigRevoNanoHWWidget(QWidget *parent = 0);
~ConfigRevoNanoHWWidget();
protected:
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
private:
Ui_RevoNanoHWWidget *m_ui;
bool m_refreshing;
void setupCustomCombos();
protected slots:
void refreshWidgetsValues(UAVObject *obj = NULL);
void updateObjectsFromWidgets();
void setupCustomCombos();
private slots:
void usbVCPPortChanged(int index);
@ -57,7 +58,6 @@ private slots:
void flexiPortChanged(int index);
void mainPortChanged(int index);
void rcvrPortChanged(int index);
void openHelp();
};
#endif // CONFIGREVONANOHWWIDGET_H

View File

@ -254,7 +254,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="configgadget.qrc">:/configgadget/images/nano_top.png</pixmap>
<pixmap>:/configgadget/images/nano_top.png</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
@ -459,7 +459,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="cchwHelp">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -497,10 +497,13 @@
<property name="flat">
<bool>true</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:help</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveTelemetryToRAM">
<widget class="QPushButton" name="applyButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -599,10 +602,13 @@ Beware of not locking yourself out!</string>
<property name="checkable">
<bool>false</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveTelemetryToSD">
<widget class="QPushButton" name="saveButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -628,6 +634,9 @@ Beware of not locking yourself out!</string>
<property name="text">
<string>Save</string>
</property>
<property name="objrelation" stdset="0">
<string>button:save</string>
</property>
</widget>
</item>
</layout>

View File

@ -1,7 +1,7 @@
/**
******************************************************************************
*
* @file ConfigRevoWidget.h
* @file configrevowidget.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
@ -29,7 +29,9 @@
#include "ui_revosensors.h"
#include <uavobjectmanager.h>
#include <uavobjecthelper.h>
#include <attitudestate.h>
#include <attitudesettings.h>
#include <revocalibration.h>
@ -38,29 +40,17 @@
#include <accelstate.h>
#include <magstate.h>
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include "assertions.h"
#include "calibration.h"
#include "calibration/calibrationutils.h"
#include "math.h"
#include <QDebug>
#include <QTimer>
#include <QStringList>
#include <QWidget>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QPushButton>
#include <QMessageBox>
#include <QThread>
#include <QErrorMessage>
#include <QDesktopServices>
#include <QUrl>
#include <math.h>
#include <iostream>
#include <math.h>
#include <QDebug>
#include <QStringList>
#include <QWidget>
#include <QThread>
// #define DEBUG
@ -78,20 +68,16 @@ public:
};
ConfigRevoWidget::ConfigRevoWidget(QWidget *parent) :
ConfigTaskWidget(parent),
m_ui(new Ui_RevoSensorsWidget()),
isBoardRotationStored(false)
ConfigTaskWidget(parent), isBoardRotationStored(false)
{
m_ui = new Ui_RevoSensorsWidget();
m_ui->setupUi(this);
m_ui->tabWidget->setCurrentIndex(0);
addApplySaveButtons(m_ui->revoCalSettingsSaveRAM, m_ui->revoCalSettingsSaveSD);
// must be done before auto binding !
setWikiURL("Revo+Attitude+Configuration");
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
m_ui->revoCalSettingsSaveRAM->setVisible(false);
}
addAutoBindings();
// Initialization of the visual help
m_ui->calibrationVisualHelp->setScene(new QGraphicsScene(this));
@ -108,7 +94,6 @@ ConfigRevoWidget::ConfigRevoWidget(QWidget *parent) :
addUAVObject("RevoSettings");
addUAVObject("AccelGyroSettings");
addUAVObject("AuxMagSettings");
autoLoadWidgets();
// accel calibration
m_accelCalibrationModel = new OpenPilot::SixPointCalibrationModel(this);
@ -223,16 +208,7 @@ ConfigRevoWidget::ConfigRevoWidget(QWidget *parent) :
displayMagError = false;
// Connect the help button
connect(m_ui->attitudeHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
populateWidgets();
enableAllCalibrations();
updateEnableControls();
forceConnectedState();
refreshWidgetsValues();
}
ConfigRevoWidget::~ConfigRevoWidget()
@ -414,9 +390,9 @@ void ConfigRevoWidget::displayTemperatureRange(float temperatureRange)
* Called by the ConfigTaskWidget parent when RevoCalibration is updated
* to update the UI
*/
void ConfigRevoWidget::refreshWidgetsValues(UAVObject *object)
void ConfigRevoWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
ConfigTaskWidget::refreshWidgetsValues(object);
Q_UNUSED(obj);
m_ui->isSetCheckBox->setEnabled(false);
@ -431,10 +407,8 @@ void ConfigRevoWidget::refreshWidgetsValues(UAVObject *object)
onBoardAuxMagError();
}
void ConfigRevoWidget::updateObjectsFromWidgets()
void ConfigRevoWidget::updateObjectsFromWidgetsImpl()
{
ConfigTaskWidget::updateObjectsFromWidgets();
if (m_accelCalibrationModel->dirty()) {
m_accelCalibrationModel->save();
}
@ -714,9 +688,3 @@ void ConfigRevoWidget::updateMagStatus()
m_ui->magStatusSource->setToolTip("");
}
}
void ConfigRevoWidget::openHelp()
{
QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Revo+Attitude+Configuration"),
QUrl::StrictMode));
}

View File

@ -1,8 +1,9 @@
/**
******************************************************************************
*
* @file configahrstwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file configrevowidget.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -28,8 +29,7 @@
#define CONFIGREVOWIDGET_H
#include "configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "calibration/thermal/thermalcalibrationmodel.h"
@ -48,6 +48,10 @@ public:
ConfigRevoWidget(QWidget *parent = 0);
~ConfigRevoWidget();
protected:
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
private:
OpenPilot::SixPointCalibrationModel *m_accelCalibrationModel;
OpenPilot::SixPointCalibrationModel *m_magCalibrationModel;
@ -83,10 +87,6 @@ private slots:
void displayTemperatureGradient(float temparetureGradient);
void displayTemperatureRange(float temparetureRange);
// ! Overriden method from the configTaskWidget to update UI
virtual void refreshWidgetsValues(UAVObject *object = NULL);
virtual void updateObjectsFromWidgets();
// Slot for clearing home location
void clearHomeLocation();
@ -101,7 +101,6 @@ private slots:
float getMagError(float mag[3]);
void updateVisualHelp();
void openHelp();
protected:
void showEvent(QShowEvent *event);

View File

@ -29,30 +29,21 @@
#include "ui_configsparky2hwwidget.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include <uavobjecthelper.h>
#include "hwsettings.h"
#include <QDebug>
#include <QDesktopServices>
#include <QUrl>
#include <QMessageBox>
ConfigSparky2HWWidget::ConfigSparky2HWWidget(QWidget *parent) : ConfigTaskWidget(parent), m_refreshing(true)
ConfigSparky2HWWidget::ConfigSparky2HWWidget(QWidget *parent) : ConfigTaskWidget(parent)
{
m_ui = new Ui_Sparky2HWWidget();
m_ui->setupUi(this);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
m_ui->saveTelemetryToRAM->setEnabled(false);
m_ui->saveTelemetryToRAM->setVisible(false);
}
// must be done before auto binding !
setWikiURL("Sparky2+Configuration");
addApplySaveButtons(m_ui->saveTelemetryToRAM, m_ui->saveTelemetryToSD);
addAutoBindings();
addUAVObject("HwSettings");
addWidgetBinding("HwSettings", "SPK2_FlexiPort", m_ui->cbFlexi);
addWidgetBinding("HwSettings", "SPK2_MainPort", m_ui->cbMain);
@ -72,14 +63,7 @@ ConfigSparky2HWWidget::ConfigSparky2HWWidget(QWidget *parent) : ConfigTaskWidget
addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbMainGPSProtocol);
addWidgetBinding("GPSSettings", "DataProtocol", m_ui->cbFlexiGPSProtocol);
connect(m_ui->cchwHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
setupCustomCombos();
enableControls(true);
populateWidgets();
refreshWidgetsValues();
forceConnectedState();
m_refreshing = false;
}
ConfigSparky2HWWidget::~ConfigSparky2HWWidget()
@ -100,36 +84,28 @@ void ConfigSparky2HWWidget::setupCustomCombos()
connect(m_ui->cbMain, SIGNAL(currentIndexChanged(int)), this, SLOT(mainPortChanged(int)));
}
void ConfigSparky2HWWidget::refreshWidgetsValues(UAVObject *obj)
void ConfigSparky2HWWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
m_refreshing = true;
ConfigTaskWidget::refreshWidgetsValues(obj);
Q_UNUSED(obj);
usbVCPPortChanged(0);
mainPortChanged(0);
flexiPortChanged(0);
m_refreshing = false;
}
void ConfigSparky2HWWidget::updateObjectsFromWidgets()
void ConfigSparky2HWWidget::updateObjectsFromWidgetsImpl()
{
ConfigTaskWidget::updateObjectsFromWidgets();
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields data = hwSettings->getData();
// If any port is configured to be GPS port, enable GPS module if it is not enabled.
// Otherwise disable GPS module.
quint8 enableModule = HwSettings::OPTIONALMODULES_DISABLED;
if (isComboboxOptionSelected(m_ui->cbFlexi, HwSettings::SPK2_FLEXIPORT_GPS)
|| isComboboxOptionSelected(m_ui->cbMain, HwSettings::SPK2_MAINPORT_GPS)) {
data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_ENABLED;
} else {
data.OptionalModules[HwSettings::OPTIONALMODULES_GPS] = HwSettings::OPTIONALMODULES_DISABLED;
enableModule = HwSettings::OPTIONALMODULES_ENABLED;
}
UAVObjectUpdaterHelper updateHelper;
hwSettings->setData(data, false);
updateHelper.doObjectAndWait(hwSettings);
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_GPS, enableModule);
}
void ConfigSparky2HWWidget::usbVCPPortChanged(int index)
@ -275,9 +251,3 @@ void ConfigSparky2HWWidget::mainPortChanged(int index)
break;
}
}
void ConfigSparky2HWWidget::openHelp()
{
QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Sparky2+Configuration"),
QUrl::StrictMode));
}

View File

@ -43,21 +43,20 @@ public:
ConfigSparky2HWWidget(QWidget *parent = 0);
~ConfigSparky2HWWidget();
protected:
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
private:
Ui_Sparky2HWWidget *m_ui;
bool m_refreshing;
void setupCustomCombos();
protected slots:
void refreshWidgetsValues(UAVObject *obj = NULL);
void updateObjectsFromWidgets();
void setupCustomCombos();
private slots:
void usbVCPPortChanged(int index);
void usbHIDPortChanged(int index);
void flexiPortChanged(int index);
void mainPortChanged(int index);
void openHelp();
};
#endif // CONFIGSPARKY2HWWIDGET_H

View File

@ -121,9 +121,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-258</y>
<width>794</width>
<height>927</height>
<y>0</y>
<width>796</width>
<height>731</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
@ -434,7 +434,7 @@
<string/>
</property>
<property name="pixmap">
<pixmap resource="configgadget.qrc">:/configgadget/images/sparky2_top.png</pixmap>
<pixmap>:/configgadget/images/sparky2_top.png</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
@ -555,7 +555,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="cchwHelp">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -593,10 +593,13 @@
<property name="flat">
<bool>true</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:help</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveTelemetryToRAM">
<widget class="QPushButton" name="applyButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -695,10 +698,13 @@ Beware of not locking yourself out!</string>
<property name="checkable">
<bool>false</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveTelemetryToSD">
<widget class="QPushButton" name="saveButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -724,6 +730,9 @@ Beware of not locking yourself out!</string>
<property name="text">
<string>Save</string>
</property>
<property name="objrelation" stdset="0">
<string>button:save</string>
</property>
</widget>
</item>
</layout>

View File

@ -2,7 +2,7 @@
******************************************************************************
*
* @file configstabilizationwidget.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
@ -29,11 +29,9 @@
#include "ui_stabilization.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include "uavobjectutilmanager.h"
#include <uavobjectmanager.h>
#include "objectpersistence.h"
#include "altitudeholdsettings.h"
#include "stabilizationsettings.h"
@ -45,38 +43,30 @@
#include <QDebug>
#include <QStringList>
#include <QWidget>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDesktopServices>
#include <QUrl>
#include <QList>
#include <QTabBar>
#include <QMessageBox>
#include <QToolButton>
#include <QMenu>
#include <QAction>
ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTaskWidget(parent),
boardModel(0), m_stabSettingsBankCount(0), m_currentStabSettingsBank(0)
m_stabSettingsBankCount(0), m_currentStabSettingsBank(0)
{
ui = new Ui_StabilizationWidget();
ui->setupUi(this);
// must be done before auto binding !
setWikiURL("Stabilization+Configuration");
setupExpoPlot();
setupStabBanksGUI();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
addAutoBindings();
if (!settings->useExpertMode()) {
ui->saveStabilizationToRAM_6->setVisible(false);
}
disableMouseWheelEvents();
autoLoadWidgets();
connect(this, SIGNAL(enableControlsChanged(bool)), this, SLOT(enableControlsChanged(bool)));
setupExpoPlot();
realtimeUpdates = new QTimer(this);
connect(realtimeUpdates, SIGNAL(timeout()), this, SLOT(apply()));
@ -116,12 +106,13 @@ ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTa
addWidget(ui->pushButton_13);
addWidget(ui->pushButton_14);
addWidget(ui->pushButton_20);
addWidget(ui->pushButton_21);
addWidget(ui->pushButton_22);
addWidget(ui->pushButton_23);
addWidget(ui->basicResponsivenessGroupBox);
addWidget(ui->basicResponsivenessCheckBox);
connect(ui->basicResponsivenessCheckBox, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
addWidget(ui->advancedResponsivenessGroupBox);
addWidget(ui->advancedResponsivenessCheckBox);
connect(ui->advancedResponsivenessCheckBox, SIGNAL(toggled(bool)), this, SLOT(linkCheckBoxes(bool)));
@ -144,15 +135,12 @@ ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTa
addWidget(ui->thrustPIDScalingCurve);
connect(this, SIGNAL(widgetContentsChanged(QWidget *)), this, SLOT(processLinkedWidgets(QWidget *)));
connect(this, SIGNAL(autoPilotConnected()), this, SLOT(onBoardConnected()));
addWidget(ui->expoPlot);
connect(ui->expoSpinnerRoll, SIGNAL(valueChanged(int)), this, SLOT(replotExpoRoll(int)));
connect(ui->expoSpinnerPitch, SIGNAL(valueChanged(int)), this, SLOT(replotExpoPitch(int)));
connect(ui->expoSpinnerYaw, SIGNAL(valueChanged(int)), this, SLOT(replotExpoYaw(int)));
disableMouseWheelEvents();
updateEnableControls();
ui->AltitudeHold->setEnabled(false);
}
void ConfigStabilizationWidget::setupStabBanksGUI()
@ -247,9 +235,9 @@ ConfigStabilizationWidget::~ConfigStabilizationWidget()
// Do nothing
}
void ConfigStabilizationWidget::refreshWidgetsValues(UAVObject *o)
void ConfigStabilizationWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
ConfigTaskWidget::refreshWidgetsValues(o);
Q_UNUSED(obj);
updateThrottleCurveFromObject();
@ -269,10 +257,9 @@ void ConfigStabilizationWidget::refreshWidgetsValues(UAVObject *o)
}
}
void ConfigStabilizationWidget::updateObjectsFromWidgets()
void ConfigStabilizationWidget::updateObjectsFromWidgetsImpl()
{
updateObjectFromThrottleCurve();
ConfigTaskWidget::updateObjectsFromWidgets();
}
void ConfigStabilizationWidget::updateThrottleCurveFromObject()
@ -647,15 +634,12 @@ void ConfigStabilizationWidget::processLinkedWidgets(QWidget *widget)
}
}
void ConfigStabilizationWidget::onBoardConnected()
void ConfigStabilizationWidget::enableControlsChanged(bool enable)
{
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
Q_ASSERT(utilMngr);
boardModel = utilMngr->getBoardModel();
// If Revolution/Sparky2 board enable Althold tab, otherwise disable it
ui->AltitudeHold->setEnabled(((boardModel & 0xff00) == 0x0900) || ((boardModel & 0xff00) == 0x9200));
bool enableAltitudeHold = (((boardModel() & 0xff00) == 0x0900) || ((boardModel() & 0xff00) == 0x9200));
ui->AltitudeHold->setEnabled(enable && enableAltitudeHold);
}
void ConfigStabilizationWidget::stabBankChanged(int index)
@ -687,7 +671,7 @@ void ConfigStabilizationWidget::stabBankChanged(int index)
bool ConfigStabilizationWidget::shouldObjectBeSaved(UAVObject *object)
{
// AltitudeHoldSettings should only be saved for Revolution/Sparky2 board to avoid error.
if (((boardModel & 0xff00) != 0x0900) && ((boardModel & 0xff00) != 0x9200)) {
if (((boardModel() & 0xff00) != 0x0900) && ((boardModel() & 0xff00) != 0x9200)) {
return dynamic_cast<AltitudeHoldSettings *>(object) == 0;
} else {
return true;

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file configstabilizationwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -28,11 +29,8 @@
#define CONFIGSTABILIZATIONWIDGET_H
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "stabilizationsettings.h"
#include "uavobject.h"
#include "qwt/src/qwt_plot_curve.h"
#include "qwt/src/qwt_plot_grid.h"
@ -51,8 +49,15 @@ class ConfigStabilizationWidget : public ConfigTaskWidget {
public:
ConfigStabilizationWidget(QWidget *parent = 0);
~ConfigStabilizationWidget();
bool shouldObjectBeSaved(UAVObject *object);
protected:
QString mapObjectName(const QString objectName);
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
private:
Ui_StabilizationWidget *ui;
QTimer *realtimeUpdates;
@ -65,7 +70,6 @@ private:
static const int EXPO_CURVE_POINTS_COUNT = 100;
constexpr static const double EXPO_CURVE_CONSTANT = 1.01395948;
int boardModel;
int m_stabSettingsBankCount;
int m_currentStabSettingsBank;
@ -86,18 +90,12 @@ private:
void resetStabBank(int bank);
void restoreStabBank(int bank);
protected:
QString mapObjectName(const QString objectName);
protected slots:
void refreshWidgetsValues(UAVObject *o = NULL);
void updateObjectsFromWidgets();
private slots:
void enableControlsChanged(bool enable);
void realtimeUpdatesSlot(bool value);
void linkCheckBoxes(bool value);
void processLinkedWidgets(QWidget *);
void onBoardConnected();
void stabBankChanged(int index);
void resetThrottleCurveToDefault();
void throttleCurveUpdated();

View File

@ -30,9 +30,6 @@
#include "ui_txpid.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include "txpidsettings.h"
#include "hwsettings.h"
#include "attitudesettings.h"
@ -46,25 +43,14 @@ ConfigTxPIDWidget::ConfigTxPIDWidget(QWidget *parent) : ConfigTaskWidget(parent)
m_txpid = new Ui_TxPIDWidget();
m_txpid->setupUi(this);
// must be done before auto binding !
setWikiURL("TxPID");
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
m_txpid->Apply->setVisible(false);
}
autoLoadWidgets();
addApplySaveButtons(m_txpid->Apply, m_txpid->Save);
// Cannot use addUAVObjectToWidgetRelation() for OptionaModules enum because
// QCheckBox returns bool (0 or -1) and this value is then set to enum instead
// or enum options
connect(HwSettings::GetInstance(getObjectManager()), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshValues()));
connect(m_txpid->Apply, SIGNAL(clicked()), this, SLOT(applySettings()));
connect(m_txpid->Save, SIGNAL(clicked()), this, SLOT(saveSettings()));
addAutoBindings();
connect(m_txpid->PID1, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int)));
connect(m_txpid->PID2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int)));
connect(m_txpid->PID3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int)));
disableMouseWheelEvents();
addUAVObject("HwSettings");
addWidgetBinding("TxPIDSettings", "BankNumber", m_txpid->pidBank, 0, 1, true);
@ -94,15 +80,14 @@ ConfigTxPIDWidget::ConfigTxPIDWidget(QWidget *parent) : ConfigTaskWidget(parent)
addWidgetBinding("TxPIDSettings", "UpdateMode", m_txpid->UpdateMode);
connect(this, SIGNAL(widgetContentsChanged(QWidget *)), this, SLOT(processLinkedWidgets(QWidget *)));
addWidget(m_txpid->TxPIDEnable);
addWidget(m_txpid->enableAutoCalcYaw);
enableControls(false);
populateWidgets();
refreshWidgetsValues();
disableMouseWheelEvents();
connect(m_txpid->PID1, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int)));
connect(m_txpid->PID2, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int)));
connect(m_txpid->PID3, SIGNAL(currentIndexChanged(int)), this, SLOT(updateSpinBoxProperties(int)));
connect(this, SIGNAL(widgetContentsChanged(QWidget *)), this, SLOT(processLinkedWidgets(QWidget *)));
}
ConfigTxPIDWidget::~ConfigTxPIDWidget()
@ -110,6 +95,40 @@ ConfigTxPIDWidget::~ConfigTxPIDWidget()
// Do nothing
}
/*
* This overridden function refreshes widgets which have no direct relation
* to any of UAVObjects. It saves their dirty state first because update comes
* from UAVObjects, and then restores it.
*/
void ConfigTxPIDWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
Q_UNUSED(obj);
// Set module enable checkbox from OptionalModules UAVObject item.
// It needs special processing because ConfigTaskWidget uses TRUE/FALSE
// for QCheckBox, but OptionalModules uses Enabled/Disabled enum values.
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
m_txpid->TxPIDEnable->setChecked(
hwSettings->getOptionalModules(HwSettings::OPTIONALMODULES_TXPID) == HwSettings::OPTIONALMODULES_ENABLED);
}
/*
* This overridden function updates UAVObjects which have no direct relation
* to any of widgets.
*/
void ConfigTxPIDWidget::updateObjectsFromWidgetsImpl()
{
// Save state of the module enable checkbox first.
// Do not use setData() member on whole object, if possible, since it triggers unnecessary UAVObect update.
quint8 enableModule = m_txpid->TxPIDEnable->isChecked() ?
HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED;
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
hwSettings->setOptionalModules(HwSettings::OPTIONALMODULES_TXPID, enableModule);
}
static bool isResponsivenessOption(int pidOption)
{
switch (pidOption) {
@ -444,32 +463,6 @@ void ConfigTxPIDWidget::updateSpinBoxProperties(int selectedPidOption)
maxPID->setValue(value);
}
void ConfigTxPIDWidget::refreshValues()
{
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields hwSettingsData = hwSettings->getData();
m_txpid->TxPIDEnable->setChecked(
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_TXPID] == HwSettings::OPTIONALMODULES_ENABLED);
}
void ConfigTxPIDWidget::applySettings()
{
HwSettings *hwSettings = HwSettings::GetInstance(getObjectManager());
HwSettings::DataFields hwSettingsData = hwSettings->getData();
hwSettingsData.OptionalModules[HwSettings::OPTIONALMODULES_TXPID] =
m_txpid->TxPIDEnable->isChecked() ? HwSettings::OPTIONALMODULES_ENABLED : HwSettings::OPTIONALMODULES_DISABLED;
hwSettings->setData(hwSettingsData);
}
void ConfigTxPIDWidget::saveSettings()
{
applySettings();
UAVObject *obj = HwSettings::GetInstance(getObjectManager());
saveObjectToSD(obj);
}
void ConfigTxPIDWidget::processLinkedWidgets(QWidget *widget)
{
Q_UNUSED(widget);

View File

@ -37,15 +37,18 @@ class ConfigTxPIDWidget : public ConfigTaskWidget {
public:
ConfigTxPIDWidget(QWidget *parent = 0);
~ConfigTxPIDWidget();
protected:
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
private:
Ui_TxPIDWidget *m_txpid;
private slots:
void processLinkedWidgets(QWidget *widget);
void updateSpinBoxProperties(int selectedPidOption);
float getDefaultValueForPidOption(int pidOption);
void refreshValues();
void applySettings();
void saveSettings();
};
#endif // CONFIGTXPIDWIDGET_H

View File

@ -31,7 +31,6 @@
#include "configgadgetfactory.h"
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include "systemsettings.h"
#include "actuatorsettings.h"
@ -47,11 +46,7 @@
#include <QTimer>
#include <QWidget>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QPushButton>
#include <math.h>
#include <QDesktopServices>
#include <QUrl>
/**
Static function to get currently assigned channelDescriptions
@ -120,12 +115,14 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
m_aircraft = new Ui_AircraftWidget();
m_aircraft->setupUi(this);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
m_aircraft->saveAircraftToRAM->setVisible(false);
}
// must be done before auto binding !
setWikiURL("Vehicle+Configuration");
addAutoBindings();
disableMouseWheelEvents();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
ConfigGadgetFactory *configGadgetFactory = pm->getObject<ConfigGadgetFactory>();
connect(m_aircraft->vehicleSetupWizardButton, SIGNAL(clicked()), configGadgetFactory, SIGNAL(onOpenVehicleConfigurationWizard()));
@ -133,31 +130,22 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
Q_ASSERT(syssettings);
m_aircraft->nameEdit->setMaxLength(syssettings->VEHICLENAME_NUMELEM);
addApplySaveButtons(m_aircraft->saveAircraftToRAM, m_aircraft->saveAircraftToSD);
addUAVObject("SystemSettings");
addUAVObject("MixerSettings");
addUAVObject("ActuatorSettings");
// The order of the tabs is important since they correspond with the AirframCategory enum
addWidget(m_aircraft->nameEdit);
// The order of the tabs is important since they correspond with the AirframeCategory enum
m_aircraft->aircraftType->addTab(tr("Multirotor"));
m_aircraft->aircraftType->addTab(tr("Fixed Wing"));
m_aircraft->aircraftType->addTab(tr("Helicopter"));
m_aircraft->aircraftType->addTab(tr("Ground"));
m_aircraft->aircraftType->addTab(tr("Custom"));
// switchAirframeType(0);
// Connect aircraft type selection dropbox to callback function
connect(m_aircraft->aircraftType, SIGNAL(currentChanged(int)), this, SLOT(switchAirframeType(int)));
// Connect the help pushbutton
connect(m_aircraft->airframeHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
refreshWidgetsValues();
addWidget(m_aircraft->nameEdit);
disableMouseWheelEvents();
updateEnableControls();
}
/**
@ -171,23 +159,22 @@ ConfigVehicleTypeWidget::~ConfigVehicleTypeWidget()
void ConfigVehicleTypeWidget::switchAirframeType(int index)
{
m_aircraft->airframesWidget->setCurrentWidget(getVehicleConfigWidget(index));
setDirty(true);
}
/**
Refreshes the current value of the SystemSettings which holds the aircraft type
Note: The default behavior of ConfigTaskWidget is bypassed.
Therefore no automatic synchronization of UAV Objects to UI is done.
Refreshes the current value of the SystemSettings which holds the aircraft type.
Note: no widgets are bound so the default behavior of ConfigTaskWidget will not do much.
Almost everything is handled here to the exception of one case (see ConfigCustomWidget...)
*/
void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *object)
void ConfigVehicleTypeWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
ConfigTaskWidget::refreshWidgetsValues(object);
Q_UNUSED(obj);
if (!allObjectsUpdated()) {
return;
}
bool dirty = isDirty();
// Get the Airframe type from the system settings:
UAVDataObject *system = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("SystemSettings")));
Q_ASSERT(system);
@ -233,8 +220,6 @@ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *object)
}
}
m_aircraft->nameEdit->setText(name);
setDirty(dirty);
}
/**
@ -243,11 +228,8 @@ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *object)
We do all the tasks common to all airframes, or family of airframes, and
we call additional methods for specific frames, so that we do not have a code
that is too heavy.
Note: The default behavior of ConfigTaskWidget is bypassed.
Therefore no automatic synchronization of UI to UAV Objects is done.
*/
void ConfigVehicleTypeWidget::updateObjectsFromWidgets()
void ConfigVehicleTypeWidget::updateObjectsFromWidgetsImpl()
{
// Airframe type defaults to Custom
QString airframeType = "Custom";
@ -262,7 +244,7 @@ void ConfigVehicleTypeWidget::updateObjectsFromWidgets()
UAVDataObject *system = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("SystemSettings")));
Q_ASSERT(system);
QPointer<UAVObjectField> field = system->getField(QString("AirframeType"));
UAVObjectField *field = system->getField(QString("AirframeType"));
if (field) {
field->setValue(airframeType);
}
@ -279,8 +261,8 @@ void ConfigVehicleTypeWidget::updateObjectsFromWidgets()
}
// call refreshWidgetsValues() to reflect actual saved values
// TODO is this needed ?
refreshWidgetsValues();
ConfigTaskWidget::updateObjectsFromWidgets();
}
int ConfigVehicleTypeWidget::frameCategory(QString frameType)
@ -311,46 +293,52 @@ int ConfigVehicleTypeWidget::frameCategory(QString frameType)
VehicleConfig *ConfigVehicleTypeWidget::getVehicleConfigWidget(int frameCategory)
{
VehicleConfig *vehiculeConfig;
VehicleConfig *vehicleConfig;
if (!m_vehicleIndexMap.contains(frameCategory)) {
// create config widget
vehiculeConfig = createVehicleConfigWidget(frameCategory);
// bind config widget "field" to this ConfigTaskWodget
// this is necessary to get "dirty" state management
vehiculeConfig->registerWidgets(*this);
vehicleConfig = createVehicleConfigWidget(frameCategory);
// add config widget to UI
int index = m_aircraft->airframesWidget->insertWidget(m_aircraft->airframesWidget->count(), vehiculeConfig);
int index = m_aircraft->airframesWidget->insertWidget(m_aircraft->airframesWidget->count(), vehicleConfig);
m_vehicleIndexMap[frameCategory] = index;
// and enable controls (needed?)
updateEnableControls();
}
int index = m_vehicleIndexMap.value(frameCategory);
vehiculeConfig = (VehicleConfig *)m_aircraft->airframesWidget->widget(index);
return vehiculeConfig;
vehicleConfig = (VehicleConfig *)m_aircraft->airframesWidget->widget(index);
return vehicleConfig;
}
VehicleConfig *ConfigVehicleTypeWidget::createVehicleConfigWidget(int frameCategory)
{
if (frameCategory == ConfigVehicleTypeWidget::FIXED_WING) {
return new ConfigFixedWingWidget();
} else if (frameCategory == ConfigVehicleTypeWidget::MULTIROTOR) {
return new ConfigMultiRotorWidget();
} else if (frameCategory == ConfigVehicleTypeWidget::HELICOPTER) {
return new ConfigCcpmWidget();
} else if (frameCategory == ConfigVehicleTypeWidget::GROUND) {
return new ConfigGroundVehicleWidget();
} else if (frameCategory == ConfigVehicleTypeWidget::CUSTOM) {
return new ConfigCustomWidget();
}
return NULL;
}
VehicleConfig *vehicleConfig;
/**
Opens the wiki from the user's default browser
*/
void ConfigVehicleTypeWidget::openHelp()
{
QDesktopServices::openUrl(QUrl(QString(WIKI_URL_ROOT) + QString("Vehicle+Configuration"),
QUrl::StrictMode));
switch (frameCategory) {
case ConfigVehicleTypeWidget::FIXED_WING:
vehicleConfig = new ConfigFixedWingWidget();
break;
case ConfigVehicleTypeWidget::MULTIROTOR:
vehicleConfig = new ConfigMultiRotorWidget();
break;
case ConfigVehicleTypeWidget::HELICOPTER:
vehicleConfig = new ConfigCcpmWidget();
break;
case ConfigVehicleTypeWidget::GROUND:
vehicleConfig = new ConfigGroundVehicleWidget();
break;
case ConfigVehicleTypeWidget::CUSTOM:
vehicleConfig = new ConfigCustomWidget();
break;
default:
vehicleConfig = NULL;
break;
}
if (vehicleConfig) {
// bind config widget "field" to this ConfigTaskWodget
// this is necessary to get "dirty" state management
vehicleConfig->registerWidgets(*this);
}
return vehicleConfig;
}

View File

@ -41,10 +41,7 @@ class Ui_AircraftWidget;
class QWidget;
/*
* This class derives from ConfigTaskWidget and overrides its default "binding" mechanism.
* This widget bypasses automatic synchronization of UAVObjects and UI by providing its own implementations of
* virtual void refreshWidgetsValues(UAVObject *obj = NULL);
* virtual void updateObjectsFromWidgets();
* This class derives from ConfigTaskWidget but almost bypasses the need its default "binding" mechanism.
*
* It does use the "dirty" state management and registers its relevant widgets with ConfigTaskWidget to do so.
*
@ -52,7 +49,6 @@ class QWidget;
* Note: for "dirty" state management it is important to register the fields of child widgets with the parent
* ConfigVehicleTypeWidget class.
*
* TODO consider to call "super" to benefit from default logic...
* TODO improve handling of relationship with VehicleConfig derived classes (i.e. ConfigTaskWidget within ConfigTaskWidget)
*/
class ConfigVehicleTypeWidget : public ConfigTaskWidget {
@ -64,9 +60,9 @@ public:
ConfigVehicleTypeWidget(QWidget *parent = 0);
~ConfigVehicleTypeWidget();
protected slots:
virtual void refreshWidgetsValues(UAVObject *object = NULL);
virtual void updateObjectsFromWidgets();
protected:
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
private:
Ui_AircraftWidget *m_aircraft;
@ -84,7 +80,6 @@ private:
private slots:
void switchAirframeType(int index);
void openHelp();
};
#endif // CONFIGVEHICLETYPEWIDGET_H

View File

@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>defaultattitude</class>
<widget class="QWidget" name="defaultattitude">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTextBrowser" name="textBrowser">
<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:'MS Shell Dlg 2'; font-size:8.25pt; 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:'Ubuntu'; font-size:11pt; font-weight:600;&quot;&gt;Attitude Calibration&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; font-family:'Ubuntu'; font-size:11pt; font-weight:600;&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:'Ubuntu'; font-size:11pt;&quot;&gt;This panel will be updated to provide the relevant controls to let you calibrate your flight controller, depending on the board which is detected once telemetry is connected and running.&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; font-family:'Ubuntu'; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</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>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<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>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,45 +0,0 @@
/**
******************************************************************************
*
* @file defaultattitudewidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Placeholder for attitude panel until board is connected.
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "defaultattitudewidget.h"
#include "ui_defaultattitude.h"
#include <QMutexLocker>
#include <QErrorMessage>
#include <QDebug>
DefaultAttitudeWidget::DefaultAttitudeWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui_defaultattitude)
{
ui->setupUi(this);
}
DefaultAttitudeWidget::~DefaultAttitudeWidget()
{
delete ui;
}

View File

@ -0,0 +1,267 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>defaultconfig</class>
<widget class="QWidget" name="defaultconfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>646</width>
<height>596</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>&lt;place holder - do not translate&gt;</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<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">
<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>622</width>
<height>519</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<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="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>25</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QTextBrowser" name="textBrowser">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="lineWrapMode">
<enum>QTextEdit::WidgetWidth</enum>
</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:'MS Shell Dlg 2'; font-size:8.25pt; 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-weight:600;&quot;&gt;This panel will be updated to provide the relevant controls to let you configure your device once it is connected and running.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>4</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>369</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="toolTip">
<string>Takes you to the wiki page</string>
</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>25</width>
<height>25</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="applyButton">
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveButton">
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../coreplugin/core.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file DefaultHwSettingsWidget.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file defaultconfigwidget.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Placeholder for attitude panel until board is connected.
* @brief Placeholder for config widget until board connected.
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -24,22 +24,24 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "defaulthwsettingswidget.h"
#include "defaultconfigwidget.h"
#include "ui_defaulthwsettings.h"
#include "ui_defaultconfig.h"
#include <QMutexLocker>
#include <QErrorMessage>
#include <QDebug>
DefaultHwSettingsWidget::DefaultHwSettingsWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui_defaulthwsettings)
DefaultConfigWidget::DefaultConfigWidget(QWidget *parent, QString title) : QWidget(parent)
{
ui = new Ui_defaultconfig();
ui->setupUi(this);
ui->tabWidget->setTabText(0, title);
ui->helpButton->setEnabled(false);
ui->saveButton->setEnabled(false);
ui->applyButton->setVisible(false);
ui->applyButton->setEnabled(false);
}
DefaultHwSettingsWidget::~DefaultHwSettingsWidget()
DefaultConfigWidget::~DefaultConfigWidget()
{
delete ui;
}

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file defaultccattitudewidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file defaultconfigwidget.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Placeholder for attitude settings widget until board connected.
* @brief Placeholder for config widget until board connected.
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -24,24 +24,22 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DEFAULTATTITUDEWIDGET_H
#define DEFAULTATTITUDEWIDGET_H
#ifndef DEFAULTCONFIGWIDGET_H
#define DEFAULTCONFIGWIDGET_H
#include <QWidget>
class Ui_defaultattitude;
class Ui_defaultconfig;
class DefaultAttitudeWidget : public QWidget {
class DefaultConfigWidget : public QWidget {
Q_OBJECT
public:
explicit DefaultAttitudeWidget(QWidget *parent = 0);
~DefaultAttitudeWidget();
private slots:
explicit DefaultConfigWidget(QWidget *parent, QString title);
~DefaultConfigWidget();
private:
Ui_defaultattitude *ui;
Ui_defaultconfig *ui;
};
#endif // DEFAULTATTITUDEWIDGET_H
#endif // DEFAULTCONFIGWIDGET_H

View File

@ -1,80 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>defaulthwsettings</class>
<widget class="QWidget" name="defaulthwsettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTextBrowser" name="textBrowser">
<property name="enabled">
<bool>true</bool>
</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:'MS Shell Dlg 2'; font-size:8.25pt; 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:'Ubuntu'; font-size:11pt; font-weight:600;&quot;&gt;Hardware Configuration&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; font-family:'Ubuntu'; font-size:11pt; font-weight:600;&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:'Ubuntu'; font-size:11pt;&quot;&gt;This panel will be updated to provide the relevant controls to let you configure your hardware once telemetry is connected and running.&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; font-family:'Ubuntu'; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</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>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<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>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,47 +0,0 @@
/**
******************************************************************************
*
* @file defaultccattitudewidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Placeholder for attitude settings widget until board connected.
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DEFAULTHWSETTINGSt_H
#define DEFAULTHWSETTINGSt_H
#include <QWidget>
class Ui_defaulthwsettings;
class DefaultHwSettingsWidget : public QWidget {
Q_OBJECT
public:
explicit DefaultHwSettingsWidget(QWidget *parent = 0);
~DefaultHwSettingsWidget();
private slots:
private:
Ui_defaulthwsettings *ui;
};
#endif // DEFAULTHWSETTINGSt_H

View File

@ -116,8 +116,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1220</width>
<height>655</height>
<width>1228</width>
<height>669</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
@ -547,8 +547,8 @@ font:bold;</string>
<rect>
<x>0</x>
<y>0</y>
<width>1220</width>
<height>655</height>
<width>773</width>
<height>587</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_7" rowstretch="1,0,0,0">
@ -2319,8 +2319,8 @@ font:bold;</string>
<rect>
<x>0</x>
<y>0</y>
<width>1220</width>
<height>655</height>
<width>616</width>
<height>351</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
@ -2591,8 +2591,8 @@ The failsafe is triggered differently for different receivers. Failsafe should a
<rect>
<x>0</x>
<y>0</y>
<width>1220</width>
<height>655</height>
<width>564</width>
<height>159</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@ -2761,7 +2761,7 @@ Set to 0 to disable (recommended for soaring fixed wings).</string>
</spacer>
</item>
<item>
<widget class="QPushButton" name="inputHelp">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -2793,10 +2793,13 @@ Set to 0 to disable (recommended for soaring fixed wings).</string>
<property name="flat">
<bool>true</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:help</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveRCInputToRAM">
<widget class="QPushButton" name="applyButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -2819,10 +2822,13 @@ Be sure to set the Neutral position on all sliders before sending!</string>
<property name="text">
<string>Apply</string>
</property>
<property name="objrelation" stdset="0">
<string>button:apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveRCInputToSD">
<widget class="QPushButton" name="saveButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -2845,6 +2851,9 @@ Applies and Saves all settings to SD</string>
<property name="text">
<string>Save</string>
</property>
<property name="objrelation" stdset="0">
<string>button:save</string>
</property>
</widget>
</item>
</layout>
@ -2856,9 +2865,9 @@ Applies and Saves all settings to SD</string>
<tabstop>deadband</tabstop>
<tabstop>armControl</tabstop>
<tabstop>armTimeout</tabstop>
<tabstop>inputHelp</tabstop>
<tabstop>saveRCInputToRAM</tabstop>
<tabstop>saveRCInputToSD</tabstop>
<tabstop>helpButton</tabstop>
<tabstop>applyButton</tabstop>
<tabstop>saveButton</tabstop>
</tabstops>
<resources>
<include location="../coreplugin/core.qrc"/>

View File

@ -49,8 +49,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>947</width>
<height>575</height>
<width>949</width>
<height>566</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
@ -1874,7 +1874,7 @@ Leave blank to use autogenerated Device ID.</string>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -1917,17 +1917,20 @@ Leave blank to use autogenerated Device ID.</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="Apply">
<widget class="QPushButton" name="applyButton">
<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>
<property name="objrelation" stdset="0">
<string>button:apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="Save">
<widget class="QPushButton" name="saveButton">
<property name="toolTip">
<string>Send settings to the board and save to the non-volatile memory.</string>
</property>
@ -1937,6 +1940,9 @@ Leave blank to use autogenerated Device ID.</string>
<property name="checked">
<bool>false</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:save</string>
</property>
</widget>
</item>
</layout>
@ -1946,8 +1952,8 @@ Leave blank to use autogenerated Device ID.</string>
<tabstops>
<tabstop>FirmwareVersion</tabstop>
<tabstop>SerialNumber</tabstop>
<tabstop>Apply</tabstop>
<tabstop>Save</tabstop>
<tabstop>applyButton</tabstop>
<tabstop>saveButton</tabstop>
</tabstops>
<resources>
<include location="../coreplugin/core.qrc"/>

View File

@ -123,7 +123,7 @@
<x>0</x>
<y>0</y>
<width>743</width>
<height>662</height>
<height>668</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,0,0">
@ -969,7 +969,7 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="outputHelp">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -1007,10 +1007,13 @@
<property name="flat">
<bool>true</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:help</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveRCOutputToRAM">
<widget class="QPushButton" name="applyButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -1033,10 +1036,13 @@ Be sure to set the Neutral position on all sliders before sending!</string>
<property name="text">
<string>Apply</string>
</property>
<property name="objrelation" stdset="0">
<string>button:apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveRCOutputToSD">
<widget class="QPushButton" name="saveButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -1059,6 +1065,9 @@ Applies and Saves all settings to SD</string>
<property name="text">
<string>Save</string>
</property>
<property name="objrelation" stdset="0">
<string>button:save</string>
</property>
</widget>
</item>
</layout>
@ -1066,8 +1075,8 @@ Applies and Saves all settings to SD</string>
</layout>
</widget>
<tabstops>
<tabstop>saveRCOutputToRAM</tabstop>
<tabstop>saveRCOutputToSD</tabstop>
<tabstop>applyButton</tabstop>
<tabstop>saveButton</tabstop>
</tabstops>
<resources>
<include location="../coreplugin/core.qrc"/>

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>935</width>
<width>954</width>
<height>726</height>
</rect>
</property>
@ -438,8 +438,8 @@
<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:'MS Shell Dlg 2'; font-size:10pt; font-weight:400; font-style:normal;&quot;&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; font-weight:600;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;&quot;&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; font-family:'MS Shell Dlg 2'; font-weight:600;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
@ -1157,10 +1157,10 @@ font:bold;</string>
<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:'Cantarell'; 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;The bargraphs show the difference between the onboard and auxiliary magnetometer measurements. &lt;/p&gt;
&lt;p align=&quot;justify&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;When the auxiliary magnetometer rotation is set correctlly, all bargraphs should show all zero (bargraph centered) &lt;a name=&quot;result_box&quot;&gt;&lt;/a&gt;whatever the vehicle's orientation.&lt;/p&gt;
&lt;p align=&quot;justify&quot; style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;This assumes both magnetometers are calibrated and without alarm.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&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:'Cantarell';&quot;&gt;The bargraphs show the difference between the onboard and auxiliary magnetometer measurements. &lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;justify&quot; 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:'Cantarell';&quot;&gt;When the auxiliary magnetometer rotation is set correctlly, all bargraphs should show all zero (bargraph centered) &lt;/span&gt;&lt;a name=&quot;result_box&quot;&gt;&lt;/a&gt;&lt;span style=&quot; font-family:'Cantarell';&quot;&gt;w&lt;/span&gt;&lt;span style=&quot; font-family:'Cantarell';&quot;&gt;hatever the vehicle's orientation.&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;justify&quot; 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:'Cantarell';&quot;&gt;This assumes both magnetometers are calibrated and without alarm.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
@ -1707,38 +1707,38 @@ font:bold;</string>
<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:'MS Shell Dlg 2'; font-size:8.25pt; 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-size:14pt; font-weight:600;&quot;&gt;Help&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; font-size:11pt;&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-size:11pt;&quot;&gt;Steps 1, 2 and 3 are necessary.&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-size:11pt;&quot;&gt;Step 4 is optional but may help achieve the best possible results.&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; font-size:11pt;&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-size:12pt; font-weight:600; font-style:italic;&quot;&gt;Step 1: Accelerometer and Magnetometer calibration&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; font-size:11pt;&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-size:11pt;&quot;&gt;This step will calibrate the scale for the Magnetometer and the Accelerometer sensors. &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-size:11pt;&quot;&gt;Press &lt;/span&gt;&lt;span style=&quot; font-size:11pt; font-style:italic;&quot;&gt;Start&lt;/span&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt; to begin, and follow the instructions for each step. &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-size:11pt;&quot;&gt;For best results with the accelerometer calibration, it is advised that it be performed with a free unmounted flight controller as this allows one to accurately position the board for each orientation in the sequence.&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; font-size:11pt;&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-size:11pt;&quot;&gt;The magnetometer calibration must be performed with the board mounted in the airframe in order for the measurements to incorporate any bias produced by local onboard metal/magnetic elements.&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; font-size:11pt;&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-size:11pt;&quot;&gt;Note 1: Before the magnetometer or the accelerometer calibration is performed your Home Location must be set. This step is needed in order to determine the local magnetic field vector (Be) and acceleration due to gravity (g_e).&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; font-size:11pt;&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-size:11pt;&quot;&gt;Note 2: There is no need to align the airframe exactly south, north, east or west during the individual steps. The directions indicated serve only to tell you in which direction the airframe should be positioned relative to some point. One can simply assume that North is in front of you, East is to the right, West is to the left and South is pointing at you.&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; font-size:11pt;&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-size:12pt; font-weight:600; font-style:italic;&quot;&gt;Step 2: Board level calibration&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; font-size:11pt;&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-size:11pt;&quot;&gt;This step will ensure that board leveling is accurate. Place the airframe as horizontally as possible (use a spirit level if necessary), then press &lt;/span&gt;&lt;span style=&quot; font-size:11pt; font-style:italic;&quot;&gt;Start&lt;/span&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;. Do not move the airframe at all until the end of the calibration.&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; font-size:11pt;&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-size:12pt; font-weight:600; font-style:italic;&quot;&gt;Step 3: Gyro bias calculation&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; font-size:11pt;&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-size:11pt;&quot;&gt;This step will allow you to calibrate the gyro measured value when the board is steady. To perform the calibration leave the board/airframe completely stationary and press &lt;/span&gt;&lt;span style=&quot; font-size:11pt; font-style:italic;&quot;&gt;Start&lt;/span&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;. &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; font-size:11pt;&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-size:12pt; font-weight:600; font-style:italic;&quot;&gt;Step 4: Thermal calibration&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; font-size:11pt;&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-size:11pt;&quot;&gt;The calibration will compute sensors bias variations at different temperatures while the board warms up.&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-size:11pt;&quot;&gt;This allows a certain amount of correction of those bias variations against temperature changes. It improves altitude hold accuracy and reduces yaw drift.&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-size:11pt;&quot;&gt;To perform this calibration disconnect any power from the board and leave it to cool down at room temperature for 15-20 minutes. Then attach the usb connector to the board and press &lt;/span&gt;&lt;span style=&quot; font-size:11pt; font-style:italic;&quot;&gt;Start&lt;/span&gt;&lt;span style=&quot; font-size:11pt;&quot;&gt;, leaving the board completely stationary. Wait until complete.&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; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&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:'MS Shell Dlg 2'; font-size:14pt; font-weight:600;&quot;&gt;Help&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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2';&quot;&gt;Steps 1, 2 and 3 are necessary.&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:'MS Shell Dlg 2';&quot;&gt;Step 4 is optional but may help achieve the best possible results.&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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;&quot;&gt;Step 1: Accelerometer and Magnetometer calibration&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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2';&quot;&gt;This step will calibrate the scale for the Magnetometer and the Accelerometer sensors. &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:'MS Shell Dlg 2';&quot;&gt;Press &lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-style:italic;&quot;&gt;Start&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2';&quot;&gt; to begin, and follow the instructions for each step. &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:'MS Shell Dlg 2';&quot;&gt;For best results with the accelerometer calibration, it is advised that it be performed with a free unmounted flight controller as this allows one to accurately position the board for each orientation in the sequence.&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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2';&quot;&gt;The magnetometer calibration must be performed with the board mounted in the airframe in order for the measurements to incorporate any bias produced by local onboard metal/magnetic elements.&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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2';&quot;&gt;Note 1: Before the magnetometer or the accelerometer calibration is performed your Home Location must be set. This step is needed in order to determine the local magnetic field vector (Be) and acceleration due to gravity (g_e).&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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2';&quot;&gt;Note 2: There is no need to align the airframe exactly south, north, east or west during the individual steps. The directions indicated serve only to tell you in which direction the airframe should be positioned relative to some point. One can simply assume that North is in front of you, East is to the right, West is to the left and South is pointing at you.&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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;&quot;&gt;Step 2: Board level calibration&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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2';&quot;&gt;This step will ensure that board leveling is accurate. Place the airframe as horizontally as possible (use a spirit level if necessary), then press &lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-style:italic;&quot;&gt;Start&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2';&quot;&gt;. Do not move the airframe at all until the end of the calibration.&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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;&quot;&gt;Step 3: Gyro bias calculation&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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2';&quot;&gt;This step will allow you to calibrate the gyro measured value when the board is steady. To perform the calibration leave the board/airframe completely stationary and press &lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-style:italic;&quot;&gt;Start&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2';&quot;&gt;. &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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2'; font-size:12pt; font-weight:600; font-style:italic;&quot;&gt;Step 4: Thermal calibration&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; font-family:'MS Shell Dlg 2';&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:'MS Shell Dlg 2';&quot;&gt;The calibration will compute sensors bias variations at different temperatures while the board warms up.&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:'MS Shell Dlg 2';&quot;&gt;This allows a certain amount of correction of those bias variations against temperature changes. It improves altitude hold accuracy and reduces yaw drift.&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:'MS Shell Dlg 2';&quot;&gt;To perform this calibration disconnect any power from the board and leave it to cool down at room temperature for 15-20 minutes. Then attach the usb connector to the board and press &lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-style:italic;&quot;&gt;Start&lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2';&quot;&gt;, leaving the board completely stationary. Wait until complete.&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; font-family:'MS Shell Dlg 2';&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
@ -1751,6 +1751,9 @@ p, li { white-space: pre-wrap; }
</item>
<item>
<layout class="QHBoxLayout" name="submitButtons">
<property name="spacing">
<number>4</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@ -1765,7 +1768,7 @@ p, li { white-space: pre-wrap; }
</spacer>
</item>
<item>
<widget class="QPushButton" name="attitudeHelp">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -1805,10 +1808,13 @@ p, li { white-space: pre-wrap; }
<property name="flat">
<bool>true</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:help</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="revoCalSettingsSaveRAM">
<widget class="QPushButton" name="applyButton">
<property name="toolTip">
<string>Save settings to the board (RAM only).
@ -1824,7 +1830,7 @@ specific calibration button on top of the screen.</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="revoCalSettingsSaveSD">
<widget class="QPushButton" name="saveButton">
<property name="toolTip">
<string>Send settings to the board, and save to the non-volatile memory.</string>
</property>

View File

@ -136,8 +136,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>877</width>
<height>764</height>
<width>863</width>
<height>821</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
@ -7932,8 +7932,8 @@ border-radius: 5;</string>
<rect>
<x>0</x>
<y>0</y>
<width>877</width>
<height>765</height>
<width>776</width>
<height>706</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_29">
@ -17354,8 +17354,8 @@ border-radius: 5;</string>
<rect>
<x>0</x>
<y>0</y>
<width>877</width>
<height>671</height>
<width>797</width>
<height>604</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8" stretch="0,0,0,0,0,0">
@ -23200,8 +23200,8 @@ font:bold;</string>
<rect>
<x>0</x>
<y>0</y>
<width>877</width>
<height>671</height>
<width>500</width>
<height>600</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_18">
@ -26214,7 +26214,7 @@ border-radius: 5;</string>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton_23">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -26263,7 +26263,7 @@ border-radius: 5;</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="stabilizationReloadBoardData_6">
<widget class="QPushButton" name="reloadButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -26307,7 +26307,7 @@ Useful if you have accidentally changed some settings.</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveStabilizationToRAM_6">
<widget class="QPushButton" name="applyButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -26343,7 +26343,7 @@ Useful if you have accidentally changed some settings.</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveStabilizationToSD_6">
<widget class="QPushButton" name="saveButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -26520,10 +26520,10 @@ Useful if you have accidentally changed some settings.</string>
<tabstop>AltThrRateSlider_2</tabstop>
<tabstop>AltThrRate_2</tabstop>
<tabstop>realTimeUpdates_7</tabstop>
<tabstop>pushButton_23</tabstop>
<tabstop>stabilizationReloadBoardData_6</tabstop>
<tabstop>saveStabilizationToRAM_6</tabstop>
<tabstop>saveStabilizationToSD_6</tabstop>
<tabstop>helpButton</tabstop>
<tabstop>reloadButton</tabstop>
<tabstop>applyButton</tabstop>
<tabstop>saveButton</tabstop>
<tabstop>checkBoxLinkAcroFactors</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>AttitudeResponsivenessSlider</tabstop>

View File

@ -118,9 +118,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-317</y>
<width>748</width>
<height>724</height>
<y>0</y>
<width>751</width>
<height>768</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@ -1426,7 +1426,7 @@ font:bold;</string>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<widget class="QPushButton" name="helpButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -1484,7 +1484,7 @@ font:bold;</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="Apply">
<widget class="QPushButton" name="applyButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -1500,10 +1500,13 @@ font:bold;</string>
<property name="text">
<string>Apply</string>
</property>
<property name="objrelation" stdset="0">
<string>button:apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="Save">
<widget class="QPushButton" name="saveButton">
<property name="minimumSize">
<size>
<width>0</width>
@ -1522,6 +1525,9 @@ font:bold;</string>
<property name="checked">
<bool>false</bool>
</property>
<property name="objrelation" stdset="0">
<string>button:save</string>
</property>
</widget>
</item>
</layout>
@ -1529,8 +1535,8 @@ font:bold;</string>
</layout>
</widget>
<tabstops>
<tabstop>Apply</tabstop>
<tabstop>Save</tabstop>
<tabstop>applyButton</tabstop>
<tabstop>saveButton</tabstop>
<tabstop>scrollArea</tabstop>
<tabstop>PID1</tabstop>
<tabstop>Input1</tabstop>

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file connectionmanager.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
* @addtogroup GCSPlugins GCS Plugins
* @{
@ -71,9 +72,11 @@ ConnectionManager::ConnectionManager(Internal::MainWindow *mainWindow) :
QObject::connect(m_availableDevList, SIGNAL(currentIndexChanged(int)), this, SLOT(onDeviceSelectionChanged(int)));
// setup our reconnect timers
// TODO these are never started because telemetryConnected is not called anymore
reconnect = new QTimer(this);
reconnectCheck = new QTimer(this);
connect(reconnect, SIGNAL(timeout()), this, SLOT(reconnectSlot()));
reconnectCheck = new QTimer(this);
connect(reconnectCheck, SIGNAL(timeout()), this, SLOT(reconnectCheckSlot()));
}
@ -91,7 +94,6 @@ void ConnectionManager::init()
QObject::connect(ExtensionSystem::PluginManager::instance(), SIGNAL(aboutToRemoveObject(QObject *)), this, SLOT(aboutToRemoveObject(QObject *)));
}
// TODO needs documentation?
void ConnectionManager::addWidget(QWidget *widget)
{
@ -271,7 +273,7 @@ void ConnectionManager::onConnectClicked()
*/
void ConnectionManager::telemetryConnected()
{
qDebug() << "TelemetryMonitor: connected";
qDebug() << "ConnectionManager::telemetryConnected";
if (reconnectCheck->isActive()) {
reconnectCheck->stop();
@ -283,7 +285,7 @@ void ConnectionManager::telemetryConnected()
*/
void ConnectionManager::telemetryDisconnected()
{
qDebug() << "TelemetryMonitor: disconnected";
qDebug() << "ConnectionManager::telemetryDisconnected";
if (m_ioDev) {
if (m_connectionDevice.connection->shortName() == "Serial") {
@ -296,17 +298,18 @@ void ConnectionManager::telemetryDisconnected()
void ConnectionManager::reconnectSlot()
{
qDebug() << "reconnect";
qDebug() << "ConnectionManager::reconnectSlot";
if (m_ioDev->isOpen()) {
m_ioDev->close();
}
if (m_ioDev->open(QIODevice::ReadWrite)) {
qDebug() << "reconnect successfull";
qDebug() << "ConnectionManager::reconnectSlot - reconnect successful";
reconnect->stop();
reconnectCheck->start(20000);
} else {
qDebug() << "reconnect NOT successfull";
qDebug() << "ConnectionManager::reconnectSlot - reconnect NOT successful";
}
}
@ -327,7 +330,7 @@ DevListItem ConnectionManager::findDevice(const QString &devName)
}
}
qDebug() << "findDevice: cannot find " << devName << " in device list";
qWarning() << "ConnectionManager::findDevice - cannot find " << devName << " in device list";
DevListItem d;
d.connection = NULL;

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file monitorgadgetfactory.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup telemetryplugin
@ -57,11 +58,11 @@ MonitorWidget *MonitorGadgetFactory::createMonitorWidget(QWidget *parent)
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
TelemetryManager *tm = pm->getObject<TelemetryManager>();
connect(tm, SIGNAL(connected()), widget, SLOT(telemetryConnected()));
connect(tm, SIGNAL(disconnected()), widget, SLOT(telemetryDisconnected()));
// connect(tm, SIGNAL(connected()), widget, SLOT(telemetryConnected()));
// connect(tm, SIGNAL(disconnected()), widget, SLOT(telemetryDisconnected()));
connect(tm, SIGNAL(telemetryUpdated(double, double)), widget, SLOT(telemetryUpdated(double, double)));
// and connect widget to connection manager (for retro compatibility)
// connect widget to connection manager
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
connect(cm, SIGNAL(deviceConnected(QIODevice *)), widget, SLOT(telemetryConnected()));

View File

@ -1,3 +1,30 @@
/**
******************************************************************************
*
* @file monitorwidget.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup telemetryplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "monitorwidget.h"
#include <utils/stylehelper.h>
@ -200,7 +227,7 @@ MonitorWidget::~MonitorWidget()
void MonitorWidget::telemetryConnected()
{
qDebug() << "telemetry connected";
qDebug() << "MonitorWidget::telemetryConnected";
if (!connected) {
// flash the lights
setToolTip(tr("Connected"));
@ -211,7 +238,7 @@ void MonitorWidget::telemetryConnected()
void MonitorWidget::telemetryDisconnected()
{
qDebug() << "telemetry disconnected";
qDebug() << "MonitorWidget::telemetryDisconnected";
if (connected) {
connected = false;

View File

@ -1,3 +1,30 @@
/**
******************************************************************************
*
* @file monitorwidget.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup telemetryplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MONITORWIDGET_H
#define MONITORWIDGET_H

View File

@ -27,10 +27,12 @@
*/
#include "configtaskwidget.h"
#include <coreplugin/generalsettings.h>
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "uavobjectutilmanager.h"
#include "uavtalk/telemetrymanager.h"
#include "uavtalk/oplinkmanager.h"
#include "uavsettingsimportexport/uavsettingsimportexportfactory.h"
#include "smartsavebutton.h"
#include "mixercurvewidget.h"
@ -41,25 +43,68 @@
#include <QLabel>
#include <QLineEdit>
#include <QSpinBox>
#include <QProgressBar>
#include <QTableWidget>
#include <QToolButton>
#include <QUrl>
#include <QWidget>
ConfigTaskWidget::ConfigTaskWidget(QWidget *parent) : QWidget(parent), m_currentBoardId(-1), m_isConnected(false), m_isWidgetUpdatesAllowed(true), m_wikiURL("Welcome"),
m_saveButton(NULL), m_isDirty(false), m_outOfLimitsStyle("background-color: rgb(255, 0, 0);"), m_realtimeUpdateTimer(NULL)
ConfigTaskWidget::ConfigTaskWidget(QWidget *parent, bool autopilot) : QWidget(parent),
m_currentBoardId(-1), m_isConnected(false), m_isWidgetUpdatesAllowed(true), m_isDirty(false), m_refreshing(false),
m_wikiURL("Welcome"), m_saveButton(NULL), m_outOfLimitsStyle("background-color: rgb(255, 0, 0);"), m_realtimeUpdateTimer(NULL)
{
m_autopilot = autopilot;
m_pluginManager = ExtensionSystem::PluginManager::instance();
TelemetryManager *telMngr = m_pluginManager->getObject<TelemetryManager>();
m_objectUtilManager = m_pluginManager->getObject<UAVObjectUtilManager>();
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()), Qt::UniqueConnection);
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()), Qt::UniqueConnection);
connect(telMngr, SIGNAL(connected()), this, SIGNAL(autoPilotConnected()), Qt::UniqueConnection);
connect(telMngr, SIGNAL(disconnected()), this, SIGNAL(autoPilotDisconnected()), Qt::UniqueConnection);
UAVSettingsImportExportFactory *importexportplugin = m_pluginManager->getObject<UAVSettingsImportExportFactory>();
connect(importexportplugin, SIGNAL(importAboutToBegin()), this, SLOT(invalidateObjects()));
m_saveButton = new SmartSaveButton(this);
connect(m_saveButton, SIGNAL(preProcessOperations()), this, SLOT(updateObjectsFromWidgets()));
connect(m_saveButton, SIGNAL(saveSuccessfull()), this, SLOT(clearDirty()));
connect(m_saveButton, SIGNAL(beginOp()), this, SLOT(disableObjectUpdates()));
connect(m_saveButton, SIGNAL(endOp()), this, SLOT(enableObjectUpdates()));
if (m_autopilot) {
// connect to telemetry manager
TelemetryManager *tm = m_pluginManager->getObject<TelemetryManager>();
connect(tm, SIGNAL(connected()), this, SLOT(onConnect()));
connect(tm, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
} else {
// connect to oplink manager
OPLinkManager *om = m_pluginManager->getObject<OPLinkManager>();
connect(om, SIGNAL(connected()), this, SLOT(onConnect()));
connect(om, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
}
}
ConfigTaskWidget::~ConfigTaskWidget()
{
if (m_saveButton) {
delete m_saveButton;
}
QSet<WidgetBinding *> deleteSet = m_widgetBindingsPerWidget.values().toSet();
foreach(WidgetBinding * binding, deleteSet) {
if (binding) {
delete binding;
}
}
if (m_realtimeUpdateTimer) {
delete m_realtimeUpdateTimer;
m_realtimeUpdateTimer = NULL;
}
}
bool ConfigTaskWidget::expertMode() const
{
Core::Internal::GeneralSettings *settings = m_pluginManager->getObject<Core::Internal::GeneralSettings>();
return settings->useExpertMode();
}
void ConfigTaskWidget::addWidget(QWidget *widget)
{
addWidgetBinding("", "", widget);
@ -136,10 +181,14 @@ void ConfigTaskWidget::addWidgetBinding(QString objectName, QString fieldName, Q
void ConfigTaskWidget::doAddWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index, double scale,
bool isLimited, QList<int> *reloadGroupIDs, quint32 instID)
{
// add a shadow binding to an existing binding (if any)
if (addShadowWidgetBinding(objectName, fieldName, widget, index, scale, isLimited, reloadGroupIDs, instID)) {
// no need to go further if successful
return;
}
// qDebug() << "ConfigTaskWidget::doAddWidgetBinding - add binding for " << objectName << fieldName << widget;
UAVObject *object = NULL;
UAVObjectField *field = NULL;
if (!objectName.isEmpty()) {
@ -190,7 +239,7 @@ void ConfigTaskWidget::setWidgetBindingObjectEnabled(QString objectName, bool en
Q_ASSERT(object);
bool dirtyBack = isDirty();
m_refreshing = true;
foreach(WidgetBinding * binding, m_widgetBindingsPerObject.values(object)) {
binding->setIsEnabled(enabled);
@ -202,24 +251,8 @@ void ConfigTaskWidget::setWidgetBindingObjectEnabled(QString objectName, bool en
}
}
}
setDirty(dirtyBack);
}
ConfigTaskWidget::~ConfigTaskWidget()
{
if (m_saveButton) {
delete m_saveButton;
}
QSet<WidgetBinding *> deleteSet = m_widgetBindingsPerWidget.values().toSet();
foreach(WidgetBinding * binding, deleteSet) {
if (binding) {
delete binding;
}
}
if (m_realtimeUpdateTimer) {
delete m_realtimeUpdateTimer;
m_realtimeUpdateTimer = NULL;
}
m_refreshing = true;
}
bool ConfigTaskWidget::isComboboxOptionSelected(QComboBox *combo, int optionValue)
@ -260,80 +293,70 @@ void ConfigTaskWidget::enableComboBoxOptionItem(QComboBox *combo, int optionValu
!enable ? QVariant(0) : QVariant(1 | 32), Qt::UserRole - 1);
}
void ConfigTaskWidget::saveObjectToSD(UAVObject *obj)
{
// saveObjectToSD is now handled by the UAVUtils plugin in one
// central place (and one central queue)
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
utilMngr->saveObjectToSD(obj);
}
UAVObjectManager *ConfigTaskWidget::getObjectManager()
{
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objMngr = pm->getObject<UAVObjectManager>();
UAVObjectManager *objMngr = m_pluginManager->getObject<UAVObjectManager>();
Q_ASSERT(objMngr);
return objMngr;
}
bool ConfigTaskWidget::isConnected() const
{
bool connected = false;
void ConfigTaskWidget::onAutopilotDisconnect()
if (m_autopilot) {
TelemetryManager *tm = m_pluginManager->getObject<TelemetryManager>();
connected = tm->isConnected();
} else {
OPLinkManager *om = m_pluginManager->getObject<OPLinkManager>();
connected = om->isConnected();
}
return connected;
}
// dynamic widgets don't receive the connected signal. This should be called instead.
void ConfigTaskWidget::bind()
{
if (isConnected()) {
onConnect();
} else {
refreshWidgetsValues();
updateEnableControls();
}
}
void ConfigTaskWidget::onConnect()
{
if (m_autopilot) {
m_currentBoardId = m_objectUtilManager->getBoardModel();
}
m_isConnected = true;
invalidateObjects();
resetLimits();
updateEnableControls();
emit connected();
refreshWidgetsValues();
setDirty(false);
}
void ConfigTaskWidget::onDisconnect()
{
m_isConnected = false;
// Reset board ID and clear bound combo box lists to force repopulation
// when we get another connected signal. This means that we get the
// correct values in combo boxes bound to fields with limits applied.
emit disconnected();
updateEnableControls();
invalidateObjects();
// reset board ID
m_currentBoardId = -1;
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
QComboBox *cb;
if (binding->widget() && (cb = qobject_cast<QComboBox *>(binding->widget()))) {
cb->clear();
}
}
enableControls(false);
invalidateObjects();
}
// dynamic widgets don't recieve the connected signal. This should be called instead.
void ConfigTaskWidget::forceConnectedState()
{
if (m_objectUtilManager) {
m_currentBoardId = m_objectUtilManager->getBoardModel();
}
m_isConnected = true;
setDirty(false);
}
void ConfigTaskWidget::onAutopilotConnect()
{
if (m_objectUtilManager) {
m_currentBoardId = m_objectUtilManager->getBoardModel();
}
invalidateObjects();
m_isConnected = true;
setDirty(false);
enableControls(true);
refreshWidgetsValues();
}
void ConfigTaskWidget::populateWidgets()
{
bool dirtyBack = isDirty();
emit populateWidgetsRequested();
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
if (binding->isEnabled() && binding->object() != NULL && binding->field() != NULL && binding->widget() != NULL) {
setWidgetFromField(binding->widget(), binding->field(), binding);
}
}
setDirty(dirtyBack);
}
void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj)
@ -342,11 +365,11 @@ void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj)
return;
}
bool dirtyBack = isDirty();
emit refreshWidgetsValuesRequested();
m_refreshing = true;
QList<WidgetBinding *> bindings = obj == NULL ? m_widgetBindingsPerObject.values() : m_widgetBindingsPerObject.values(obj);
foreach(WidgetBinding * binding, bindings) {
if (binding->field() != NULL && binding->widget() != NULL) {
if (binding->field() && binding->widget()) {
if (binding->isEnabled()) {
setWidgetFromField(binding->widget(), binding->field(), binding);
} else {
@ -354,18 +377,23 @@ void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj)
}
}
}
setDirty(dirtyBack);
// call specific implementation
refreshWidgetsValuesImpl(obj);
m_refreshing = false;
}
void ConfigTaskWidget::updateObjectsFromWidgets()
{
emit updateObjectsFromWidgetsRequested();
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
if (binding->object() != NULL && binding->field() != NULL) {
if (binding->object() && binding->field()) {
binding->updateObjectFieldFromValue();
}
}
// call specific implementation
updateObjectsFromWidgetsImpl();
}
void ConfigTaskWidget::helpButtonPressed()
@ -377,26 +405,15 @@ void ConfigTaskWidget::helpButtonPressed()
}
}
void ConfigTaskWidget::addApplySaveButtons(QPushButton *update, QPushButton *save)
void ConfigTaskWidget::addApplyButton(QPushButton *button)
{
if (!m_saveButton) {
m_saveButton = new SmartSaveButton(this);
connect(m_saveButton, SIGNAL(preProcessOperations()), this, SLOT(updateObjectsFromWidgets()));
connect(m_saveButton, SIGNAL(saveSuccessfull()), this, SLOT(clearDirty()));
connect(m_saveButton, SIGNAL(beginOp()), this, SLOT(disableObjectUpdates()));
connect(m_saveButton, SIGNAL(endOp()), this, SLOT(enableObjectUpdates()));
}
if (update && save) {
m_saveButton->addButtons(save, update);
} else if (update) {
m_saveButton->addApplyButton(update);
} else if (save) {
m_saveButton->addSaveButton(save);
}
foreach(WidgetBinding * binding, m_widgetBindingsPerWidget) {
m_saveButton->addObject((UAVDataObject *)binding->object());
}
updateEnableControls();
m_saveButton->addApplyButton(button);
button->setVisible(expertMode());
}
void ConfigTaskWidget::addSaveButton(QPushButton *button)
{
m_saveButton->addSaveButton(button);
}
void ConfigTaskWidget::enableControls(bool enable)
@ -417,6 +434,7 @@ void ConfigTaskWidget::enableControls(bool enable)
}
}
}
emit enableControlsChanged(enable);
}
@ -426,28 +444,6 @@ bool ConfigTaskWidget::shouldObjectBeSaved(UAVObject *object)
return true;
}
void ConfigTaskWidget::forceShadowUpdates()
{
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
if (!binding->isEnabled()) {
continue;
}
QVariant widgetValue = getVariantFromWidget(binding->widget(), binding);
foreach(ShadowWidgetBinding * shadow, binding->shadows()) {
disconnectWidgetUpdatesToSlot(shadow->widget(), SLOT(widgetsContentsChanged()));
checkWidgetsLimits(shadow->widget(), binding->field(), binding->index(), shadow->isLimited(), widgetValue, shadow->scale());
WidgetBinding tmpBinding(shadow->widget(), binding->object(), binding->field(), binding->index(), shadow->scale(), shadow->isLimited());
setWidgetFromVariant(shadow->widget(), widgetValue, &tmpBinding);
emit widgetContentsChanged(shadow->widget());
connectWidgetUpdatesToSlot(shadow->widget(), SLOT(widgetsContentsChanged()));
}
}
setDirty(true);
}
void ConfigTaskWidget::widgetsContentsChanged()
{
@ -510,6 +506,9 @@ void ConfigTaskWidget::clearDirty()
void ConfigTaskWidget::setDirty(bool value)
{
if (m_refreshing) {
return;
}
m_isDirty = value;
}
@ -552,7 +551,10 @@ bool ConfigTaskWidget::allObjectsUpdated()
bool result = true;
foreach(UAVObject * object, m_updatedObjects.keys()) {
result = result & m_updatedObjects[object];
result &= m_updatedObjects[object];
if (!result) {
break;
}
}
return result;
}
@ -597,6 +599,7 @@ bool ConfigTaskWidget::addShadowWidgetBinding(QString objectName, QString fieldN
continue;
}
if (binding->matches(objectName, fieldName, index, instID)) {
// qDebug() << "ConfigTaskWidget::addShadowWidgetBinding - add shadow binding for " << objectName << fieldName << widget;
binding->addShadow(widget, scale, isLimited);
m_widgetBindingsPerWidget.insert(widget, binding);
@ -613,10 +616,9 @@ bool ConfigTaskWidget::addShadowWidgetBinding(QString objectName, QString fieldN
return false;
}
void ConfigTaskWidget::autoLoadWidgets()
void ConfigTaskWidget::addAutoBindings()
{
QPushButton *saveButtonWidget = NULL;
QPushButton *applyButtonWidget = NULL;
// qDebug() << "ConfigTaskWidget::addAutoBindings() - auto binding" << this;
foreach(QWidget * widget, this->findChildren<QWidget *>()) {
QVariant info = widget->property("objrelation");
@ -672,19 +674,19 @@ void ConfigTaskWidget::autoLoadWidgets()
uiRelation.url = str.mid(str.indexOf(":") + 1);
}
}
if (!(uiRelation.buttonType == none)) {
if (uiRelation.buttonType != none) {
QPushButton *button = NULL;
switch (uiRelation.buttonType) {
case save_button:
saveButtonWidget = qobject_cast<QPushButton *>(widget);
if (saveButtonWidget) {
addApplySaveButtons(NULL, saveButtonWidget);
button = qobject_cast<QPushButton *>(widget);
if (button) {
addSaveButton(button);
}
break;
case apply_button:
applyButtonWidget = qobject_cast<QPushButton *>(widget);
if (applyButtonWidget) {
addApplySaveButtons(applyButtonWidget, NULL);
button = qobject_cast<QPushButton *>(widget);
if (button) {
addApplyButton(button);
}
break;
case default_button:
@ -720,12 +722,18 @@ void ConfigTaskWidget::autoLoadWidgets()
}
}
}
foreach(WidgetBinding * binding, m_widgetBindingsPerWidget) {
if (binding->object()) {
m_saveButton->addObject((UAVDataObject *)binding->object());
}
}
}
refreshWidgetsValues();
forceShadowUpdates();
// qDebug() << "ConfigTaskWidget::addAutoBindings() - auto binding done for" << this;
}
/*
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
void ConfigTaskWidget::dumpBindings()
{
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
if (binding->widget()) {
qDebug() << "Binding :" << binding->widget()->objectName();
qDebug() << " Object :" << binding->object()->getName();
@ -739,8 +747,7 @@ void ConfigTaskWidget::autoLoadWidgets()
qDebug() << " Scale :" << shadow->scale();
}
}
}
*/
}
}
void ConfigTaskWidget::addWidgetToReloadGroups(QWidget *widget, QList<int> *reloadGroupIDs)
@ -811,7 +818,7 @@ void ConfigTaskWidget::reloadButtonClicked()
QList<objectComparator> temp;
foreach(WidgetBinding * binding, bindings) {
if (binding->isEnabled() && binding->object() != NULL) {
if (binding->isEnabled() && binding->object()) {
objectComparator value;
value.objid = binding->object()->getObjID();
value.objinstid = binding->object()->getInstID();
@ -873,8 +880,12 @@ void ConfigTaskWidget::connectWidgetUpdatesToSlot(QWidget *widget, const char *f
connect(cb, SIGNAL(clicked()), this, function, Qt::UniqueConnection);
} else if (QToolButton * cb = qobject_cast<QToolButton *>(widget)) {
connect(cb, SIGNAL(clicked()), this, function, Qt::UniqueConnection);
} else if (qobject_cast<QLabel *>(widget)) {
// read only
} else if (qobject_cast<QProgressBar *>(widget)) {
// read only
} else {
qDebug() << __FUNCTION__ << "widget binding not implemented" << widget->metaObject()->className();
qDebug() << __FUNCTION__ << "widget binding not implemented for" << widget->metaObject()->className();
}
}
@ -903,8 +914,12 @@ void ConfigTaskWidget::disconnectWidgetUpdatesToSlot(QWidget *widget, const char
disconnect(cb, SIGNAL(clicked()), this, function);
} else if (QToolButton * cb = qobject_cast<QToolButton *>(widget)) {
disconnect(cb, SIGNAL(clicked()), this, function);
} else if (qobject_cast<QLabel *>(widget)) {
// read only
} else if (qobject_cast<QProgressBar *>(widget)) {
// read only
} else {
qDebug() << __FUNCTION__ << "widget binding not implemented" << widget->metaObject()->className();
qDebug() << __FUNCTION__ << "widget binding not implemented for" << widget->metaObject()->className();
}
}
@ -916,7 +931,7 @@ QVariant ConfigTaskWidget::getVariantFromWidget(QWidget *widget, WidgetBinding *
if (binding->isInteger()) {
return QVariant(getComboboxSelectedOption(cb));
}
return (QString)cb->currentText();
return cb->currentText();
} else if (QDoubleSpinBox * cb = qobject_cast<QDoubleSpinBox *>(widget)) {
return (double)(cb->value() * scale);
} else if (QSpinBox * cb = qobject_cast<QSpinBox *>(widget)) {
@ -924,18 +939,17 @@ QVariant ConfigTaskWidget::getVariantFromWidget(QWidget *widget, WidgetBinding *
} else if (QSlider * cb = qobject_cast<QSlider *>(widget)) {
return (double)(cb->value() * scale);
} else if (QCheckBox * cb = qobject_cast<QCheckBox *>(widget)) {
return (QString)(cb->isChecked() ? "True" : "False");
return cb->isChecked() ? "True" : "False";
} else if (QLineEdit * cb = qobject_cast<QLineEdit *>(widget)) {
QString value = (QString)cb->displayText();
QString value = cb->displayText();
if (binding->units() == "hex") {
bool ok;
return value.toUInt(&ok, 16);
} else {
return value;
}
} else {
return QVariant();
}
return QVariant();
}
bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, WidgetBinding *binding)
@ -951,10 +965,19 @@ bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, Wid
}
return ok;
} else if (QLabel * cb = qobject_cast<QLabel *>(widget)) {
if (scale == 0) {
cb->setText(value.toString());
if ((scale == 0) || (scale == 1)) {
if (binding->units() == "hex") {
if (value.toUInt()) {
cb->setText(QString::number(value.toUInt(), 16).toUpper());
} else {
// display 0 as an empty string
cb->setText("");
}
} else {
cb->setText(value.toString());
}
} else {
cb->setText(QString::number((value.toDouble() / scale)));
cb->setText(QString::number(value.toDouble() / scale));
}
return true;
} else if (QDoubleSpinBox * cb = qobject_cast<QDoubleSpinBox *>(widget)) {
@ -967,23 +990,26 @@ bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, Wid
cb->setValue((int)qRound(value.toDouble() / scale));
return true;
} else if (QCheckBox * cb = qobject_cast<QCheckBox *>(widget)) {
bool bvalue = value.toString() == "True";
cb->setChecked(bvalue);
cb->setChecked(value.toString() == "True");
return true;
} else if (QLineEdit * cb = qobject_cast<QLineEdit *>(widget)) {
if ((scale == 0) || (scale == 1)) {
if (binding->units() == "hex") {
cb->setText(QString::number(value.toUInt(), 16).toUpper());
if (value.toUInt()) {
cb->setText(QString::number(value.toUInt(), 16).toUpper());
} else {
// display 0 as an empty string
cb->setText("");
}
} else {
cb->setText(value.toString());
}
} else {
cb->setText(QString::number((value.toDouble() / scale)));
cb->setText(QString::number(value.toDouble() / scale));
}
return true;
} else {
return false;
}
return false;
}
bool ConfigTaskWidget::setWidgetFromField(QWidget *widget, UAVObjectField *field, WidgetBinding *binding)
@ -1002,11 +1028,25 @@ bool ConfigTaskWidget::setWidgetFromField(QWidget *widget, UAVObjectField *field
if (result) {
return true;
} else {
qDebug() << __FUNCTION__ << "widget to uavobject relation not implemented" << widget->metaObject()->className();
qDebug() << __FUNCTION__ << "widget to uavobject relation not implemented for" << widget->metaObject()->className();
return false;
}
}
void ConfigTaskWidget::resetLimits()
{
// clear bound combo box lists to force repopulation
// when we get another connected signal. This means that we get the
// correct values in combo boxes bound to fields with limits applied.
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
QComboBox *cb;
if (binding->widget() && (cb = qobject_cast<QComboBox *>(binding->widget()))) {
cb->clear();
}
}
}
void ConfigTaskWidget::checkWidgetsLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, QVariant value, double scale)
{
if (!hasLimits) {
@ -1100,19 +1140,17 @@ QString ConfigTaskWidget::mapObjectName(const QString objectName)
void ConfigTaskWidget::updateEnableControls()
{
TelemetryManager *telMngr = m_pluginManager->getObject<TelemetryManager>();
Q_ASSERT(telMngr);
enableControls(telMngr->isConnected());
enableControls(isConnected());
}
void ConfigTaskWidget::buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits)
{
QStringList options = field->getOptions();
// qDebug() << "buildOptionComboBox" << field << applyLimits << m_currentBoardId;
for (int optionIndex = 0; optionIndex < options.count(); optionIndex++) {
if (applyLimits) {
// qDebug() << " " << options.at(optionIndex) << field->isWithinLimits(options.at(optionIndex), index, m_currentBoardId);
if (m_currentBoardId > -1 && field->isWithinLimits(options.at(optionIndex), index, m_currentBoardId)) {
combo->addItem(options.at(optionIndex), QVariant(optionIndex));
}
@ -1252,11 +1290,6 @@ QVariant WidgetBinding::value() const
void WidgetBinding::setValue(const QVariant &value)
{
m_value = value;
/*
if (m_object && m_field) {
qDebug() << "WidgetBinding" << m_object->getName() << ":" << m_field->getName() << "value =" << value.toString();
}
*/
}
void WidgetBinding::updateObjectFieldFromValue()

View File

@ -29,12 +29,13 @@
#include "uavobjectwidgetutils_global.h"
#include "extensionsystem/pluginmanager.h"
#include <QWidget>
#include <QList>
#include <QVariant>
namespace ExtensionSystem {
class PluginManager;
}
class UAVObject;
class UAVObjectField;
class UAVObjectManager;
@ -99,9 +100,17 @@ class UAVOBJECTWIDGETUTILS_EXPORT ConfigTaskWidget : public QWidget {
Q_OBJECT
public:
ConfigTaskWidget(QWidget *parent = 0);
ConfigTaskWidget(QWidget *parent = 0, bool autopilot = true);
virtual ~ConfigTaskWidget();
void bind();
bool isDirty();
void setDirty(bool value);
virtual bool shouldObjectBeSaved(UAVObject *object);
protected:
// Combobox helper functions
static bool isComboboxOptionSelected(QComboBox *combo, int optionValue);
static int getComboboxSelectedOption(QComboBox *combo);
@ -112,12 +121,13 @@ public:
void disableMouseWheelEvents();
bool eventFilter(QObject *obj, QEvent *evt);
void saveObjectToSD(UAVObject *obj);
UAVObjectManager *getObjectManager();
void addUAVObject(QString objectName, QList<int> *reloadGroups = NULL);
void addUAVObject(UAVObject *objectName, QList<int> *reloadGroups = NULL);
// TODO should be protected (see VehicleConfig::registerWidgets(ConfigTaskWidget &parent)
public:
void addWidget(QWidget *widget);
void addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index = 0, double scale = 1,
@ -125,6 +135,9 @@ public:
void addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, int index = 0, double scale = 1,
bool isLimited = false, QList<int> *reloadGroupIDs = 0, quint32 instID = 0);
protected:
void addAutoBindings();
void addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, QString elementName, double scale,
bool isLimited = false, QList<int> *reloadGroupIDs = 0, quint32 instID = 0);
void addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, QString elementName, double scale,
@ -133,20 +146,11 @@ public:
void addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, QString elementName);
void addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, QString elementName);
void addApplySaveButtons(QPushButton *update, QPushButton *save);
void addReloadButton(QPushButton *button, int buttonGroup);
void addDefaultButton(QPushButton *button, int buttonGroup);
void addWidgetToReloadGroups(QWidget *widget, QList<int> *reloadGroupIDs);
bool addShadowWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index = 0, double scale = 1,
bool isLimited = false, QList<int> *m_reloadGroups = NULL, quint32 instID = 0);
void autoLoadWidgets();
bool isDirty();
virtual void setDirty(bool value);
bool allObjectsUpdated();
void setOutOfLimitsStyle(QString style)
{
@ -154,38 +158,56 @@ public:
}
void addHelpButton(QPushButton *button, QString url);
void setWikiURL(QString url);
void forceShadowUpdates();
void forceConnectedState();
virtual bool shouldObjectBeSaved(UAVObject *object);
public slots:
void onAutopilotDisconnect();
void onAutopilotConnect();
void invalidateObjects();
protected slots:
void apply();
void save();
void setWidgetBindingObjectEnabled(QString objectName, bool enabled);
signals:
// fired when a widgets contents changes
void connected();
void disconnected();
void widgetContentsChanged(QWidget *widget);
// fired when the framework requests that the widgets values be populated, use for custom behaviour
void populateWidgetsRequested();
// fired when the framework requests that the widgets values be refreshed, use for custom behaviour
void refreshWidgetsValuesRequested();
// fired when the framework requests that the UAVObject values be updated from the widgets value, use for custom behaviour
void updateObjectsFromWidgetsRequested();
// fired when the autopilot connects
void autoPilotConnected();
// fired when the autopilot disconnects
void autoPilotDisconnected();
void defaultRequested(int group);
void enableControlsChanged(bool enable);
protected:
int boardModel() const
{
return m_currentBoardId;
}
bool expertMode() const;
virtual void enableControls(bool enable);
virtual QString mapObjectName(const QString objectName);
virtual UAVObject *getObject(const QString name, quint32 instId = 0);
virtual void buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits);
void updateEnableControls();
bool isConnected() const;
virtual void refreshWidgetsValuesImpl(UAVObject *) {};
virtual void updateObjectsFromWidgetsImpl() {};
protected slots:
void setWidgetBindingObjectEnabled(QString objectName, bool enabled);
void clearDirty();
virtual void widgetsContentsChanged();
// void populateWidgets();
void refreshWidgetsValues(UAVObject *obj = NULL);
void updateObjectsFromWidgets();
private slots:
void onConnect();
void onDisconnect();
void disableObjectUpdates();
void enableObjectUpdates();
void objectUpdated(UAVObject *object);
void invalidateObjects();
void defaultButtonClicked();
void reloadButtonClicked();
void helpButtonPressed();
private:
struct objectComparator {
@ -210,12 +232,22 @@ private:
bool haslimits;
};
// indicates if this is an "autopilot" widget (CC3D, Revolution, ...) or an OPLink widget
// TODO the logic that this flag controls should be moved to derived classes
bool m_autopilot;
// only valid for "autopilot" widgets
int m_currentBoardId;
bool m_isConnected;
bool m_isWidgetUpdatesAllowed;
bool m_isDirty;
bool m_refreshing;
QStringList m_objects;
QString m_wikiURL; // Wiki address for help button
// Concatenated with WIKI_URL_ROOT
// Wiki address for help button (will be concatenated with WIKI_URL_ROOT)
QString m_wikiURL;
QMultiHash<int, WidgetBinding *> m_reloadGroups;
QMultiHash<QWidget *, WidgetBinding *> m_widgetBindingsPerWidget;
@ -223,11 +255,13 @@ private:
ExtensionSystem::PluginManager *m_pluginManager;
UAVObjectUtilManager *m_objectUtilManager;
SmartSaveButton *m_saveButton;
QHash<UAVObject *, bool> m_updatedObjects;
SmartSaveButton *m_saveButton;
QHash<QPushButton *, QString> m_helpButtons;
QList<QPushButton *> m_reloadButtons;
bool m_isDirty;
QString m_outOfLimitsStyle;
QTimer *m_realtimeUpdateTimer;
@ -239,30 +273,23 @@ private:
void connectWidgetUpdatesToSlot(QWidget *widget, const char *function);
void disconnectWidgetUpdatesToSlot(QWidget *widget, const char *function);
void resetLimits();
void loadWidgetLimits(QWidget *widget, UAVObjectField *field, int index, bool applyLimits, double scale);
void checkWidgetsLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, QVariant value, double scale);
void dumpBindings();
int fieldIndexFromElementName(QString objectName, QString fieldName, QString elementName);
void doAddWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index = 0, double scale = 1,
bool isLimited = false, QList<int> *reloadGroupIDs = 0, quint32 instID = 0);
protected slots:
virtual void disableObjectUpdates();
virtual void enableObjectUpdates();
virtual void clearDirty();
virtual void widgetsContentsChanged();
virtual void populateWidgets();
virtual void refreshWidgetsValues(UAVObject *obj = NULL);
virtual void updateObjectsFromWidgets();
virtual void helpButtonPressed();
protected:
virtual void enableControls(bool enable);
virtual QString mapObjectName(const QString objectName);
virtual UAVObject *getObject(const QString name, quint32 instId = 0);
virtual void buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits);
void checkWidgetsLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, QVariant value, double scale);
void updateEnableControls();
void addApplyButton(QPushButton *button);
void addSaveButton(QPushButton *button);
void addReloadButton(QPushButton *button, int buttonGroup);
void addDefaultButton(QPushButton *button, int buttonGroup);
};
#endif // CONFIGTASKWIDGET_H

View File

@ -30,23 +30,18 @@
SmartSaveButton::SmartSaveButton(ConfigTaskWidget *configTaskWidget) : configWidget(configTaskWidget)
{}
void SmartSaveButton::addButtons(QPushButton *save, QPushButton *apply)
{
buttonList.insert(save, save_button);
buttonList.insert(apply, apply_button);
connect(save, SIGNAL(clicked()), this, SLOT(processClick()));
connect(apply, SIGNAL(clicked()), this, SLOT(processClick()));
}
void SmartSaveButton::addApplyButton(QPushButton *apply)
{
buttonList.insert(apply, apply_button);
connect(apply, SIGNAL(clicked()), this, SLOT(processClick()));
}
void SmartSaveButton::addSaveButton(QPushButton *save)
{
buttonList.insert(save, save_button);
connect(save, SIGNAL(clicked()), this, SLOT(processClick()));
}
void SmartSaveButton::processClick()
{
emit beginOp();
@ -76,6 +71,9 @@ void SmartSaveButton::processOperation(QPushButton *button, bool save)
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
foreach(UAVDataObject * obj, objects) {
if (!obj) {
continue;
}
UAVObject::Metadata mdata = obj->getMetadata();
// Should we really save this object to the board?
@ -165,24 +163,29 @@ void SmartSaveButton::setObjects(QList<UAVDataObject *> list)
void SmartSaveButton::addObject(UAVDataObject *obj)
{
Q_ASSERT(obj);
if (!objects.contains(obj)) {
if (obj && !objects.contains(obj)) {
objects.append(obj);
}
}
void SmartSaveButton::removeObject(UAVDataObject *obj)
{
if (objects.contains(obj)) {
Q_ASSERT(obj);
if (obj && objects.contains(obj)) {
objects.removeAll(obj);
}
}
void SmartSaveButton::removeAllObjects()
{
objects.clear();
}
void SmartSaveButton::clearObjects()
{
objects.clear();
}
void SmartSaveButton::transaction_finished(UAVObject *obj, bool result)
{
if (current_object == obj) {

View File

@ -46,7 +46,6 @@ public:
public:
SmartSaveButton(ConfigTaskWidget *configTaskWidget);
void addButtons(QPushButton *save, QPushButton *apply);
void setObjects(QList<UAVDataObject *>);
void addObject(UAVDataObject *);
void clearObjects();

View File

@ -0,0 +1,131 @@
/**
******************************************************************************
*
* @file oplinkmanager.cpp
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVTalkPlugin UAVTalk Plugin
* @{
* @brief The UAVTalk protocol plugin
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "oplinkmanager.h"
#include <coreplugin/icore.h>
#include <coreplugin/connectionmanager.h>
#include <extensionsystem/pluginmanager.h>
#include <uavobjects/uavobjectmanager.h>
#include <oplinkstatus.h>
#include <QDebug>
OPLinkManager::OPLinkManager() : QObject(), m_isConnected(false), m_opLinkType(OPLinkManager::OPLINK_UNKNOWN)
{
// connect to the connection manager
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
connect(cm, SIGNAL(deviceConnected(QIODevice *)), this, SLOT(onDeviceConnect()));
connect(cm, SIGNAL(deviceDisconnected()), this, SLOT(onDeviceDisconnect()));
if (cm->isConnected()) {
onDeviceConnect();
}
}
OPLinkManager::~OPLinkManager()
{}
bool OPLinkManager::isConnected() const
{
return m_isConnected;
}
void OPLinkManager::onDeviceConnect()
{
if (m_isConnected) {
return;
}
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Q_ASSERT(pm);
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
Q_ASSERT(objManager);
m_opLinkStatus = OPLinkStatus::GetInstance(objManager);
Q_ASSERT(m_opLinkStatus);
// start monitoring OPLinkStatus
connect(m_opLinkStatus, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(onOPLinkStatusUpdate()), Qt::UniqueConnection);
}
void OPLinkManager::onDeviceDisconnect()
{
onOPLinkDisconnect();
}
void OPLinkManager::onOPLinkStatusUpdate()
{
int type = m_opLinkStatus->boardType();
switch (type) {
case 0x03:
m_opLinkType = OPLINK_MINI;
onOPLinkConnect();
break;
case 0x09:
m_opLinkType = OPLINK_REVOLUTION;
onOPLinkConnect();
break;
case 0x92:
m_opLinkType = OPLINK_SPARKY2;
onOPLinkConnect();
break;
default:
m_opLinkType = OPLINK_UNKNOWN;
// stop monitoring status updates...
m_opLinkStatus->disconnect(this);
break;
}
}
void OPLinkManager::onOPLinkConnect()
{
if (m_isConnected) {
return;
}
// stop monitoring status updates...
m_opLinkStatus->disconnect(this);
m_isConnected = true;
emit connected();
}
void OPLinkManager::onOPLinkDisconnect()
{
if (!m_isConnected) {
return;
}
// stop monitoring status updates...
m_opLinkStatus->disconnect(this);
m_isConnected = false;
emit disconnected();
}

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file oplinkwatchdog.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup [Group]
* @file oplinkmanager.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup OPLinkWatchdog
* @addtogroup UAVTalkPlugin UAVTalk Plugin
* @{
* @brief [Brief]
* @brief The UAVTalk protocol plugin
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -25,46 +25,51 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef OPLINKWATCHDOG_H
#define OPLINKWATCHDOG_H
#ifndef OPLINK_MANAGER_H
#define OPLINK_MANAGER_H
#include <QTimer>
#include "uavtalk_global.h"
#include <QObject>
class OPLinkStatus;
class OPLinkWatchdog : public QObject {
class UAVTALK_EXPORT OPLinkManager : public QObject {
Q_OBJECT
public:
enum OPLinkType {
OPLINK_UNKNOWN,
OPLINK_MINI,
OPLINK_REVOLUTION,
OPLINK_UNKNOWN
OPLINK_SPARKY2
};
OPLinkWatchdog();
~OPLinkWatchdog();
bool isConnected() const
{
return m_isConnected;
}
OPLinkWatchdog::OPLinkType opLinkType() const
OPLinkManager();
~OPLinkManager();
OPLinkManager::OPLinkType opLinkType() const
{
return m_opLinkType;
}
bool isConnected() const;
signals:
void connected();
void opLinkMiniConnected();
void opLinkRevolutionConnected();
void disconnected();
private slots:
void onDeviceConnect();
void onDeviceDisconnect();
void onOPLinkStatusUpdate();
void onTimeout();
void onOPLinkConnect();
void onOPLinkDisconnect();
private:
bool m_isConnected;
OPLinkType m_opLinkType;
QTimer *m_watchdog;
OPLinkStatus *m_opLinkStatus;
};
#endif // OPLINKWATCHDOG_H
#endif // OPLINK_MANAGER_H

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file telemetrymanager.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVTalkPlugin UAVTalk Plugin
@ -32,9 +33,10 @@
#include <coreplugin/icore.h>
#include <coreplugin/threadmanager.h>
TelemetryManager::TelemetryManager() : m_connectionState(TELEMETRY_DISCONNECTED)
TelemetryManager::TelemetryManager() : QObject(), m_connectionState(TELEMETRY_DISCONNECTED)
{
moveToThread(Core::ICore::instance()->threadManager()->getRealTimeThread());
// Get UAVObjectManager instance
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
m_uavobjectManager = pm->getObject<UAVObjectManager>();

View File

@ -1,8 +1,9 @@
/**
******************************************************************************
*
* @file telemetrymanager.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file telemetrymanager.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVTalkPlugin UAVTalk Plugin
@ -25,8 +26,8 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TELEMETRYMANAGER_H
#define TELEMETRYMANAGER_H
#ifndef TELEMETRY_MANAGER_H
#define TELEMETRY_MANAGER_H
#include "uavtalk_global.h"
#include "uavtalk.h"
@ -94,4 +95,4 @@ public slots:
void read();
};
#endif // TELEMETRYMANAGER_H
#endif // TELEMETRY_MANAGER_H

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file telemetrymonitor.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVTalkPlugin UAVTalk Plugin
@ -88,8 +89,7 @@ void TelemetryMonitor::startRetrievingObjects()
}
}
// Start retrieving
qDebug() << tr("Starting to retrieve meta and settings objects from the autopilot (%1 objects)")
.arg(queue.length());
qDebug() << "TelemetryMonitor::startRetrievingObjects - retrieving" << queue.length() << "objects";
retrieveNextObject();
}
@ -98,7 +98,7 @@ void TelemetryMonitor::startRetrievingObjects()
*/
void TelemetryMonitor::stopRetrievingObjects()
{
qDebug("Object retrieval has been cancelled");
qDebug() << "TelemetryMonitor::stopRetrievingObjects - object retrieval has been cancelled";
queue.clear();
}
@ -109,7 +109,7 @@ void TelemetryMonitor::retrieveNextObject()
{
// If queue is empty return
if (queue.isEmpty()) {
qDebug("Object retrieval completed");
qDebug() << "TelemetryMonitor::retrieveNextObject - object retrieval completed";
if (firmwareIAPObj->getBoardType()) {
emit connected();
} else {
@ -142,14 +142,16 @@ void TelemetryMonitor::transactionCompleted(UAVObject *obj, bool success)
// Disconnect from sending object
obj->disconnect(this);
objPending = NULL;
// Process next object if telemetry is still available
GCSTelemetryStats::DataFields gcsStats = gcsStatsObj->getData();
if (gcsStats.Status == GCSTelemetryStats::STATUS_CONNECTED) {
retrieveNextObject();
} else {
stopRetrievingObjects();
}
} else {
qCritical() << "TelemetryMonitor::retrieveNextObject - unexpected object" << obj;
}
}
@ -252,13 +254,12 @@ void TelemetryMonitor::processStatsUpdates()
// Act on new connections or disconnections
if (gcsStats.Status == GCSTelemetryStats::STATUS_CONNECTED && gcsStats.Status != oldStatus) {
statsTimer->setInterval(STATS_UPDATE_PERIOD_MS);
qDebug("Connection with the autopilot established");
qDebug() << "TelemetryMonitor::processStatsUpdates - connection with the autopilot established";
startRetrievingObjects();
}
if (gcsStats.Status == GCSTelemetryStats::STATUS_DISCONNECTED && gcsStats.Status != oldStatus) {
statsTimer->setInterval(STATS_CONNECT_PERIOD_MS);
qDebug("Connection with the autopilot lost");
qDebug("Trying to connect to the autopilot");
qDebug() << "TelemetryMonitor::processStatsUpdates - connection with the autopilot lost";
emit disconnected();
}
}

View File

@ -12,18 +12,20 @@ include(../../plugin.pri)
include(uavtalk_dependencies.pri)
HEADERS += \
uavtalk_global.h \
uavtalk.h \
uavtalkplugin.h \
telemetry.h \
telemetrymonitor.h \
telemetrymanager.h \
uavtalk_global.h \
telemetry.h
oplinkmanager.h \
uavtalkplugin.h
SOURCES += \
uavtalk.cpp \
uavtalkplugin.cpp \
telemetry.cpp \
telemetrymonitor.cpp \
telemetrymanager.cpp \
telemetry.cpp
oplinkmanager.cpp \
uavtalkplugin.cpp
OTHER_FILES += UAVTalk.pluginspec

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file uavtalkplugin.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVTalkPlugin UAVTalk Plugin
@ -26,14 +27,18 @@
*/
#include "uavtalkplugin.h"
#include "telemetrymanager.h"
#include "oplinkmanager.h"
#include <coreplugin/icore.h>
#include <coreplugin/connectionmanager.h>
UAVTalkPlugin::UAVTalkPlugin()
UAVTalkPlugin::UAVTalkPlugin() : telemetryManager(0)
{}
UAVTalkPlugin::~UAVTalkPlugin()
{}
/**
* Called once all the plugins which depend on us have been loaded
*/
@ -50,15 +55,18 @@ bool UAVTalkPlugin::initialize(const QStringList & arguments, QString *errorStri
Q_UNUSED(errorString);
// Create TelemetryManager
telMngr = new TelemetryManager();
addAutoReleasedObject(telMngr);
telemetryManager = new TelemetryManager();
addAutoReleasedObject(telemetryManager);
// Create OPLinkManager
OPLinkManager *opLinkManager = new OPLinkManager();
addAutoReleasedObject(opLinkManager);
// Connect to connection manager so we get notified when the user connect to his device
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
QObject::connect(cm, SIGNAL(deviceConnected(QIODevice *)),
this, SLOT(onDeviceConnect(QIODevice *)));
QObject::connect(cm, SIGNAL(deviceAboutToDisconnect()),
this, SLOT(onDeviceDisconnect()));
QObject::connect(cm, SIGNAL(deviceConnected(QIODevice *)), this, SLOT(onDeviceConnect(QIODevice *)));
QObject::connect(cm, SIGNAL(deviceAboutToDisconnect()), this, SLOT(onDeviceDisconnect()));
return true;
}
@ -67,10 +75,10 @@ void UAVTalkPlugin::shutdown()
void UAVTalkPlugin::onDeviceConnect(QIODevice *dev)
{
telMngr->start(dev);
telemetryManager->start(dev);
}
void UAVTalkPlugin::onDeviceDisconnect()
{
telMngr->stop();
telemetryManager->stop();
}

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file uavtalkplugin.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVTalkPlugin UAVTalk Plugin
@ -28,10 +29,9 @@
#define UAVTALKPLUGIN_H
#include <extensionsystem/iplugin.h>
#include <extensionsystem/pluginmanager.h>
#include <QtPlugin>
#include "uavtalk.h"
#include "telemetrymanager.h"
class TelemetryManager;
class UAVTALK_EXPORT UAVTalkPlugin : public ExtensionSystem::IPlugin {
Q_OBJECT
@ -50,7 +50,7 @@ protected slots:
void onDeviceDisconnect();
private:
TelemetryManager *telMngr;
TelemetryManager *telemetryManager;
};
#endif // UAVTALKPLUGIN_H

View File

@ -1,90 +0,0 @@
/**
******************************************************************************
*
* @file oplinkwatchdog.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
* @addtogroup [Group]
* @{
* @addtogroup OPLinkWatchdog
* @{
* @brief [Brief]
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "oplinkwatchdog.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjects/uavobjectmanager.h"
#include "oplinkstatus.h"
#include <QDebug>
OPLinkWatchdog::OPLinkWatchdog() : QObject(),
m_isConnected(false)
{
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Q_ASSERT(pm);
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
Q_ASSERT(objManager);
m_opLinkStatus = OPLinkStatus::GetInstance(objManager);
Q_ASSERT(m_opLinkStatus);
connect(m_opLinkStatus, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(onOPLinkStatusUpdate()));
m_watchdog = new QTimer(this);
connect(m_watchdog, SIGNAL(timeout()), this, SLOT(onTimeout()));
onOPLinkStatusUpdate();
}
OPLinkWatchdog::~OPLinkWatchdog()
{}
void OPLinkWatchdog::onOPLinkStatusUpdate()
{
m_watchdog->stop();
quint8 type = m_opLinkStatus->getBoardType();
if (!m_isConnected) {
switch (type) {
case 3:
m_opLinkType = OPLINK_MINI;
m_isConnected = true;
emit connected();
emit opLinkMiniConnected();
break;
case 9:
m_opLinkType = OPLINK_REVOLUTION;
m_isConnected = true;
emit connected();
emit opLinkRevolutionConnected();
break;
default:
m_isConnected = false;
m_opLinkType = OPLINK_UNKNOWN;
return;
}
qDebug() << "OPLinkWatchdog - OPLink connected";
}
m_watchdog->start(m_opLinkStatus->getMetadata().flightTelemetryUpdatePeriod * 3);
}
void OPLinkWatchdog::onTimeout()
{
if (m_isConnected) {
m_isConnected = false;
m_opLinkType = OPLINK_UNKNOWN;
qDebug() << "OPLinkWatchdog - OPLink disconnected";
emit disconnected();
}
}

View File

@ -33,8 +33,7 @@ HEADERS += \
runningdevicewidget.h \
uploader_global.h \
enums.h \
rebootdialog.h \
oplinkwatchdog.h
rebootdialog.h
SOURCES += \
uploadergadget.cpp \
@ -50,8 +49,7 @@ SOURCES += \
SSP/qssp.cpp \
SSP/qsspt.cpp \
runningdevicewidget.cpp \
rebootdialog.cpp \
oplinkwatchdog.cpp
rebootdialog.cpp
OTHER_FILES += Uploader.pluginspec

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file uploadergadgetoptionspage.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup YModemUploader YModem Serial Uploader Plugin
@ -26,7 +27,9 @@
*/
#include "uploadergadgetoptionspage.h"
#include "uploadergadgetconfiguration.h"
#include <QLabel>
#include <QSpinBox>
#include <QDoubleSpinBox>

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file uploadergadgetoptionspage.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup YModemUploader YModem Serial Uploader Plugin
@ -27,19 +28,19 @@
#ifndef UPLOADERGADGETOPTIONSPAGE_H
#define UPLOADERGADGETOPTIONSPAGE_H
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include "uploader_global.h"
#include "coreplugin/dialogs/ioptionspage.h"
#include "QString"
#include <QEventLoop>
#include <QString>
#include <QStringList>
#include <QDebug>
#include "uploader_global.h"
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
namespace Core {
class IUAVGadgetConfiguration;
}
class UploaderGadgetConfiguration;
class QTextEdit;
class QComboBox;
class QSpinBox;

View File

@ -27,8 +27,9 @@
*/
#include "uploadergadgetwidget.h"
#include "ui_uploader.h"
#include "flightstatus.h"
#include "oplinkstatus.h"
#include "delay.h"
#include "devicewidget.h"
#include "runningdevicewidget.h"
@ -38,12 +39,13 @@
#include <coreplugin/coreconstants.h>
#include <coreplugin/connectionmanager.h>
#include <uavtalk/telemetrymanager.h>
#include <uavtalk/oplinkmanager.h>
#include "rebootdialog.h"
#include <QDesktopServices>
#include <QMessageBox>
#include <QProgressBar>
#include <QDebug>
#include "rebootdialog.h"
#define DFU_DEBUG true
@ -675,16 +677,21 @@ bool UploaderGadgetWidget::autoUpdateCapable()
bool UploaderGadgetWidget::autoUpdate(bool erase)
{
if (m_oplinkwatchdog.isConnected() &&
m_oplinkwatchdog.opLinkType() == OPLinkWatchdog::OPLINK_MINI) {
ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
Q_ASSERT(pluginManager);
OPLinkManager *opLinkManager = pluginManager->getObject<OPLinkManager>();
Q_ASSERT(opLinkManager);
if (opLinkManager->isConnected() &&
opLinkManager->opLinkType() == OPLinkManager::OPLINK_MINI) {
emit progressUpdate(FAILURE, QVariant(tr("To upgrade the OPLinkMini board please disconnect it from the USB port, "
"press the Upgrade again button and follow instructions on screen.")));
"press the Upgrade button again and follow instructions on screen.")));
emit autoUpdateFailed();
return false;
}
ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
Q_ASSERT(pluginManager);
TelemetryManager *telemetryManager = pluginManager->getObject<TelemetryManager>();
Q_ASSERT(telemetryManager);
@ -824,11 +831,11 @@ bool UploaderGadgetWidget::autoUpdate(bool erase)
// Wait for board to connect to GCS again after boot and erase
// For older board like CC3D this can take some time
// Theres a special case with OPLink
if (!telemetryManager->isConnected() && !m_oplinkwatchdog.isConnected()) {
if (!telemetryManager->isConnected() && !opLinkManager->isConnected()) {
progressUpdate(erase ? BOOTING_AND_ERASING : BOOTING, QVariant());
ResultEventLoop eventLoop;
connect(telemetryManager, SIGNAL(connected()), &eventLoop, SLOT(success()));
connect(&m_oplinkwatchdog, SIGNAL(opLinkMiniConnected()), &eventLoop, SLOT(success()));
connect(opLinkManager, SIGNAL(connected()), &eventLoop, SLOT(success()));
if (eventLoop.run(REBOOT_TIMEOUT + (erase ? ERASE_TIMEOUT : 0)) != 0) {
emit progressUpdate(FAILURE, QVariant(tr("Timed out while booting.")));
@ -836,7 +843,7 @@ bool UploaderGadgetWidget::autoUpdate(bool erase)
return false;
}
disconnect(&m_oplinkwatchdog, SIGNAL(opLinkMiniConnected()), &eventLoop, SLOT(success()));
disconnect(opLinkManager, SIGNAL(connected()), &eventLoop, SLOT(success()));
disconnect(telemetryManager, SIGNAL(connected()), &eventLoop, SLOT(success()));
}

View File

@ -28,22 +28,21 @@
#ifndef UPLOADERGADGETWIDGET_H
#define UPLOADERGADGETWIDGET_H
#include "ui_uploader.h"
#include "uploader_global.h"
#include "enums.h"
#include "op_dfu.h"
#include <QEventLoop>
#include <QProgressDialog>
#include "oplinkwatchdog.h"
using namespace OP_DFU;
using namespace uploader;
class Ui_UploaderWidget;
class FlightStatus;
class UAVObject;
class OPLinkStatus;
class OPLinkWatchdog;
class TimedDialog : public QProgressDialog {
Q_OBJECT
@ -146,7 +145,6 @@ private:
DFUObject *m_dfu;
IAPStep m_currentIAPStep;
bool m_resetOnly;
OPLinkWatchdog m_oplinkwatchdog;
bool m_autoUpdateClosing;
void clearLog();