Commit 432ce330 authored by Lorenz Meier's avatar Lorenz Meier

Added RC calibration stub, ready for testing and fine-tuning

parent a563f89c
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
id="svg2"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="Neues Dokument 1">
<defs
id="defs4">
<linearGradient
id="linearGradient3875">
<stop
id="stop3877"
offset="0"
style="stop-color:#515151;stop-opacity:1;" />
<stop
id="stop3879"
offset="1"
style="stop-color:#d8d8d8;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3835">
<stop
style="stop-color:#e4e4e4;stop-opacity:1;"
offset="0"
id="stop3837" />
<stop
style="stop-color:#858585;stop-opacity:1;"
offset="1"
id="stop3839" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3835"
id="radialGradient3848"
gradientUnits="userSpaceOnUse"
cx="507.5188"
cy="526.42236"
fx="507.5188"
fy="526.42236"
r="16.973413" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3875"
id="radialGradient3873"
cx="518.49976"
cy="531.7298"
fx="518.49976"
fy="531.7298"
r="99.30201"
gradientTransform="matrix(1.0073545,0,0,1.0067087,-3.1153029,-1.0662221)"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.8756036"
inkscape:cx="524.60569"
inkscape:cy="520"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1005"
inkscape:window-height="710"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="fill:url(#radialGradient3873);fill-opacity:1.0;stroke:#565656;stroke-width:3.96477031999999996;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3865"
width="196.03523"
height="196.03523"
x="421.18015"
y="436.21313"
rx="25"
ry="25" />
<path
sodipodi:type="arc"
style="fill:none;stroke:#343434;stroke-width:15.91826248;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3050"
sodipodi:cx="551.3158"
sodipodi:cy="551.04639"
sodipodi:rx="95.394737"
sodipodi:ry="95.394737"
d="m 646.71053,551.04639 a 95.394737,95.394737 0 1 1 -190.78947,0 95.394737,95.394737 0 1 1 190.78947,0 z"
transform="matrix(0.88583873,0,0,0.88583873,30.820877,46.09252)" />
<g
id="g3860"
style="fill:#7a7a7a;fill-opacity:1"
transform="translate(1.2311668,-0.09085464)">
<rect
ry="8.5346909"
rx="8.5346909"
y="491.34589"
x="456.7894"
height="85.951439"
width="122.35439"
id="rect3850"
style="fill:#7a7a7a;fill-opacity:1;stroke:#565656;stroke-width:4;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
id="path3854"
d="m 475.58024,492.00923 0,84.23955"
style="fill:#7a7a7a;fill-opacity:1;stroke:#565656;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
id="path3858"
d="m 560.88612,491.47606 0,83.70639"
style="fill:#7a7a7a;fill-opacity:1;stroke:#565656;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
<rect
style="fill:#626262;fill-opacity:1;stroke:none"
id="rect3881"
width="78.374771"
height="28.790731"
x="480.01038"
y="519.83539"
rx="6.893404"
ry="6.9829288" />
<g
id="lever"
transform="translate(14.122572,5.5527487)"
inkscape:label="#g3843"
style="stroke:#dedede;stroke-opacity:1">
<path
transform="translate(-2.443609,2.2556391)"
d="m 523.68421,526.42236 c 0,8.92791 -7.2375,16.16542 -16.16541,16.16542 -8.92791,0 -16.16541,-7.23751 -16.16541,-16.16542 0,-8.92791 7.2375,-16.16541 16.16541,-16.16541 8.92791,0 16.16541,7.2375 16.16541,16.16541 z"
sodipodi:ry="16.165413"
sodipodi:rx="16.165413"
sodipodi:cy="526.42236"
sodipodi:cx="507.5188"
id="path3824"
style="fill:url(#radialGradient3848);fill-opacity:1;stroke:#dedede;stroke-width:1.61600006;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
<path
transform="matrix(0.37071886,0,0,0.37071886,324.67091,335.10189)"
inkscape:transform-center-y="-1.8038121"
inkscape:transform-center-x="0.34073505"
d="m 520.79209,543.94636 -12.66136,-2.06656 3.15141,12.4358 -11.19098,-6.27236 -1.29194,12.76367 -8.3708,-9.72164 -5.57946,11.55206 -4.54099,-11.99833 -9.19402,8.9471 -0.16345,-12.82786 -11.69964,5.26298 4.23378,-12.11014 -12.7941,0.94407 8.12037,-9.93177 -12.34542,-3.48871 11.02751,-6.55548 -10.40769,-7.50069 12.60458,-2.38851 -7.21464,-10.60798 12.66135,2.06655 -3.1514,-12.4358 11.19097,6.27237 1.29195,-12.76367 8.37079,9.72163 5.57947,-11.55205 4.54098,11.99833 9.19402,-8.9471 0.16346,12.82785 11.69963,-5.26297 -4.23378,12.11014 12.79411,-0.94407 -8.12037,9.93177 12.34542,3.4887 -11.02752,6.55549 10.40769,7.50069 -12.60458,2.38851 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="false"
sodipodi:arg2="0.74219935"
sodipodi:arg1="0.56766642"
sodipodi:r2="29.168983"
sodipodi:r1="40.512478"
sodipodi:cy="522.16418"
sodipodi:cx="486.63367"
sodipodi:sides="18"
id="path3820"
style="fill:none;stroke:#dedede;stroke-width:4.23310757;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="star" />
<path
sodipodi:type="arc"
style="fill:none;stroke:#dedede;stroke-width:2.47939396;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3828"
sodipodi:cx="507.5188"
sodipodi:cy="526.42236"
sodipodi:rx="16.165413"
sodipodi:ry="16.165413"
d="m 523.68421,526.42236 c 0,8.92791 -7.2375,16.16542 -16.16541,16.16542 -8.92791,0 -16.16541,-7.23751 -16.16541,-16.16542 0,-8.92791 7.2375,-16.16541 16.16541,-16.16541 8.92791,0 16.16541,7.2375 16.16541,16.16541 z"
transform="matrix(0.59537333,0,0,0.59537333,202.91203,215.26017)" />
</g>
<path
transform="matrix(0.94625779,0,0,0.94625779,-2.4891051,12.798815)"
d="m 646.71053,551.04639 a 95.394737,95.394737 0 1 1 -190.78947,0 95.394737,95.394737 0 1 1 190.78947,0 z"
sodipodi:ry="95.394737"
sodipodi:rx="95.394737"
sodipodi:cy="551.04639"
sodipodi:cx="551.3158"
id="path3852"
style="fill:none;stroke:#5d5d5d;stroke-width:4.37090206;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="200"
height="200"
id="svg2"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="rc_stick.svg">
<defs
id="defs4">
<linearGradient
id="linearGradient3875">
<stop
id="stop3877"
offset="0"
style="stop-color:#515151;stop-opacity:1;" />
<stop
id="stop3879"
offset="1"
style="stop-color:#d8d8d8;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3835">
<stop
style="stop-color:#e4e4e4;stop-opacity:1;"
offset="0"
id="stop3837" />
<stop
style="stop-color:#858585;stop-opacity:1;"
offset="1"
id="stop3839" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3835"
id="radialGradient3848"
gradientUnits="userSpaceOnUse"
cx="507.5188"
cy="526.42236"
fx="507.5188"
fy="526.42236"
r="16.973413" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3875"
id="radialGradient3873"
cx="518.49976"
cy="531.7298"
fx="518.49976"
fy="531.7298"
r="99.30201"
gradientTransform="matrix(1.0073545,0,0,1.0067087,-3.1153029,-1.0662221)"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.8756036"
inkscape:cx="105.40793"
inkscape:cy="101.86857"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1005"
inkscape:window-height="710"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-419.19776,-434.23075)">
<rect
style="fill:url(#radialGradient3873);fill-opacity:1;stroke:#565656;stroke-width:3.96477032;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3865"
width="196.03523"
height="196.03523"
x="421.18015"
y="436.21313"
rx="25"
ry="25" />
<path
sodipodi:type="arc"
style="fill:none;stroke:#343434;stroke-width:15.91826248;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3050"
sodipodi:cx="551.3158"
sodipodi:cy="551.04639"
sodipodi:rx="95.394737"
sodipodi:ry="95.394737"
d="m 646.71053,551.04639 c 0,52.68506 -42.70968,95.39473 -95.39473,95.39473 -52.68506,0 -95.39474,-42.70967 -95.39474,-95.39473 0,-52.68506 42.70968,-95.39474 95.39474,-95.39474 52.68505,0 95.39473,42.70968 95.39473,95.39474 z"
transform="matrix(0.88583873,0,0,0.88583873,30.820877,46.09252)" />
<g
id="g3860"
style="fill:#7a7a7a;fill-opacity:1"
transform="translate(1.2311668,-0.09085464)">
<rect
ry="8.5346909"
rx="8.5346909"
y="491.34589"
x="456.7894"
height="85.951439"
width="122.35439"
id="rect3850"
style="fill:#7a7a7a;fill-opacity:1;stroke:#565656;stroke-width:4;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
id="path3854"
d="m 475.58024,492.00923 0,84.23955"
style="fill:#7a7a7a;fill-opacity:1;stroke:#565656;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
inkscape:connector-curvature="0"
id="path3858"
d="m 560.88612,491.47606 0,83.70639"
style="fill:#7a7a7a;fill-opacity:1;stroke:#565656;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
<rect
style="fill:#626262;fill-opacity:1;stroke:none"
id="rect3881"
width="78.374771"
height="28.790731"
x="480.01038"
y="519.83539"
rx="6.893404"
ry="6.9829288" />
<g
id="lever"
transform="translate(14.122572,5.5527487)"
inkscape:label="#g3843"
style="stroke:#dedede;stroke-opacity:1">
<path
transform="translate(-2.443609,2.2556391)"
d="m 523.68421,526.42236 c 0,8.92791 -7.2375,16.16542 -16.16541,16.16542 -8.92791,0 -16.16541,-7.23751 -16.16541,-16.16542 0,-8.92791 7.2375,-16.16541 16.16541,-16.16541 8.92791,0 16.16541,7.2375 16.16541,16.16541 z"
sodipodi:ry="16.165413"
sodipodi:rx="16.165413"
sodipodi:cy="526.42236"
sodipodi:cx="507.5188"
id="path3824"
style="fill:url(#radialGradient3848);fill-opacity:1;stroke:#dedede;stroke-width:1.61600006;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
<path
transform="matrix(0.37071886,0,0,0.37071886,324.67091,335.10189)"
inkscape:transform-center-y="-1.8038121"
inkscape:transform-center-x="0.34073505"
d="m 520.79209,543.94636 -12.66136,-2.06656 3.15141,12.4358 -11.19098,-6.27236 -1.29194,12.76367 -8.3708,-9.72164 -5.57946,11.55206 -4.54099,-11.99833 -9.19402,8.9471 -0.16345,-12.82786 -11.69964,5.26298 4.23378,-12.11014 -12.7941,0.94407 8.12037,-9.93177 -12.34542,-3.48871 11.02751,-6.55548 -10.40769,-7.50069 12.60458,-2.38851 -7.21464,-10.60798 12.66135,2.06655 -3.1514,-12.4358 11.19097,6.27237 1.29195,-12.76367 8.37079,9.72163 5.57947,-11.55205 4.54098,11.99833 9.19402,-8.9471 0.16346,12.82785 11.69963,-5.26297 -4.23378,12.11014 12.79411,-0.94407 -8.12037,9.93177 12.34542,3.4887 -11.02752,6.55549 10.40769,7.50069 -12.60458,2.38851 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="false"
sodipodi:arg2="0.74219935"
sodipodi:arg1="0.56766642"
sodipodi:r2="29.168983"
sodipodi:r1="40.512478"
sodipodi:cy="522.16418"
sodipodi:cx="486.63367"
sodipodi:sides="18"
id="path3820"
style="fill:none;stroke:#dedede;stroke-width:4.23310757;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="star" />
<path
sodipodi:type="arc"
style="fill:none;stroke:#dedede;stroke-width:2.47939396;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3828"
sodipodi:cx="507.5188"
sodipodi:cy="526.42236"
sodipodi:rx="16.165413"
sodipodi:ry="16.165413"
d="m 523.68421,526.42236 c 0,8.92791 -7.2375,16.16542 -16.16541,16.16542 -8.92791,0 -16.16541,-7.23751 -16.16541,-16.16542 0,-8.92791 7.2375,-16.16541 16.16541,-16.16541 8.92791,0 16.16541,7.2375 16.16541,16.16541 z"
transform="matrix(0.59537333,0,0,0.59537333,202.91203,215.26017)" />
</g>
<path
transform="matrix(0.94625779,0,0,0.94625779,-1.9559434,14.3983)"
d="m 646.71053,551.04639 c 0,52.68506 -42.70968,95.39473 -95.39473,95.39473 -52.68506,0 -95.39474,-42.70967 -95.39474,-95.39473 0,-52.68506 42.70968,-95.39474 95.39474,-95.39474 52.68505,0 95.39473,42.70968 95.39473,95.39474 z"
sodipodi:ry="95.394737"
sodipodi:rx="95.394737"
sodipodi:cy="551.04639"
sodipodi:cx="551.3158"
id="path3852"
style="fill:none;stroke:#5d5d5d;stroke-width:4.37090206;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc" />
</g>
</svg>
......@@ -88,6 +88,7 @@
<file>files/images/contrib/slugs.png</file>
<file>files/styles/style-outdoor.css</file>
<file>files/images/patterns/lenna.jpg</file>
<file>files/images/rc_stick.svg</file>
</qresource>
<qresource prefix="/general">
<file alias="vera.ttf">files/styles/Vera.ttf</file>
......
......@@ -290,25 +290,35 @@ void UASManager::removeUAS(QObject* uas)
if (mav) {
int listindex = systems.indexOf(mav);
if (mav == activeUAS) {
if (systems.count() > 1) {
if (mav == activeUAS)
{
if (systems.count() > 1)
{
// We only set a new UAS if more than one is present
if (listindex != 0) {
if (listindex != 0)
{
// The system to be removed is not at position 1
// set position one as new active system
setActiveUAS(systems.first());
} else {
}
else
{
// The system to be removed is at position 1,
// select the next system
setActiveUAS(systems.at(1));
}
} else {
}
else
{
// TODO send a null pointer if no UAS is present any more
// This has to be proberly tested however, since it might
// This has to be properly tested however, since it might
// crash code parts not handling null pointers correctly.
activeUAS = NULL;
// XXX Not emitting the null pointer yet
}
}
systems.removeAt(listindex);
emit UASDeleted(mav);
}
}
......
......@@ -258,7 +258,10 @@ protected:
signals:
/** A new system was created */
void UASCreated(UASInterface* UAS);
/** A system was deleted */
void UASDeleted(UASInterface* UAS);
/** @brief The UAS currently under main operator control changed */
void activeUASSet(UASInterface* UAS);
/** @brief The UAS currently under main operator control changed */
......
......@@ -1214,6 +1214,12 @@ void MainWindow::UASSpecsChanged(int uas)
ui.menuUnmanned_System->setTitle(activeUAS->getUASName());
}
}
else
{
// Last system deleted
ui.menuUnmanned_System->setTitle(tr("No System"));
ui.menuUnmanned_System->setEnabled(false);
}
}
void MainWindow::UASCreated(UASInterface* uas)
......@@ -1374,11 +1380,31 @@ void MainWindow::UASCreated(UASInterface* uas)
//}
if (!ui.menuConnected_Systems->isEnabled()) ui.menuConnected_Systems->setEnabled(true);
if (!ui.menuUnmanned_System->isEnabled()) ui.menuUnmanned_System->setEnabled(true);
// Reload view state in case new widgets were added
loadViewState();
}
void MainWindow::UASDeleted(UASInterface* uas)
{
if (UASManager::instance()->getUASList().count() == 0)
{
// Last system deleted
ui.menuUnmanned_System->setTitle(tr("No System"));
ui.menuUnmanned_System->setEnabled(false);
}
QAction* act;
QList<QAction*> actions = ui.menuConnected_Systems->actions();
foreach (act, actions)
{
if (act->text().contains(uas->getUASName()))
ui.menuConnected_Systems->removeAction(act);
}
}
/**
* Stores the current view state
*/
......
......@@ -144,6 +144,8 @@ public slots:
/** @brief Add a new UAS */
void UASCreated(UASInterface* uas);
/** Delete an UAS */
void UASDeleted(UASInterface* uas);
/** @brief Update system specs of a UAS */
void UASSpecsChanged(int uas);
void startVideoCapture();
......
......@@ -30,7 +30,7 @@
<string>Mute all audio output</string>
</property>
<property name="icon">
<iconset resource="../../mavground.qrc">
<iconset resource="../../qgroundcontrol.qrc">
<normaloff>:/files/images/status/audio-volume-muted.svg</normaloff>:/files/images/status/audio-volume-muted.svg</iconset>
</property>
</widget>
......@@ -41,7 +41,7 @@
<string>Automatically reconnect last link on application startup</string>
</property>
<property name="icon">
<iconset resource="../../mavground.qrc">
<iconset resource="../../qgroundcontrol.qrc">
<normaloff>:/files/images/devices/network-wireless.svg</normaloff>:/files/images/devices/network-wireless.svg</iconset>
</property>
</widget>
......@@ -97,7 +97,7 @@
</layout>
</widget>
<resources>
<include location="../../mavground.qrc"/>
<include location="../../qgroundcontrol.qrc"/>
</resources>
<connections>
<connection>
......
#include <limits.h>
#include <QTimer>
#include "QGCVehicleConfig.h"
#include "QGC.h"
#include "ui_QGCVehicleConfig.h"
QGCVehicleConfig::QGCVehicleConfig(QWidget *parent) :
QWidget(parent),
mav(NULL),
changed(true),
ui(new Ui::QGCVehicleConfig)
{
setObjectName("QGC_VEHICLECONFIG");
ui->setupUi(this);
requestCalibrationRC();
if (mav) mav->requestParameter(0, "RC_TYPE");
connect(ui->rcCalibrationButton, SIGNAL(clicked(bool)), this, SLOT(toggleCalibrationRC(bool)));
connect(ui->storeButton, SIGNAL(clicked()), this, SLOT(writeParameters()));
}
QGCVehicleConfig::~QGCVehicleConfig()
{
delete ui;
}
void QGCVehicleConfig::toggleCalibrationRC(bool enabled)
{
if (enabled)
{
startCalibrationRC();
}
else
{
stopCalibrationRC();
}
}
void QGCVehicleConfig::startCalibrationRC()
{
ui->rcTypeComboBox->setEnabled(false);
resetCalibrationRC();
}
void QGCVehicleConfig::stopCalibrationRC()
{
ui->rcTypeComboBox->setEnabled(true);
}
void QGCVehicleConfig::setActiveUAS(UASInterface* active)
{
// Do nothing if system is the same or NULL
if ((active == NULL) || mav == active) return;
if (mav)
{
// Disconnect old system
disconnect(mav, SIGNAL(remoteControlChannelRawChanged(int,float)), this,
SLOT(remoteControlChannelRawChanged(int,float)));
disconnect(mav, SIGNAL(parameterChanged(int,int,QString,QVariant)), this,
SLOT(parameterChanged(int,int,QString,QVariant)));
resetCalibrationRC();
}
// Connect new system
mav = active;
connect(active, SIGNAL(statusChanged(UASInterface*,QString,QString)), this, SLOT(updateState(UASInterface*, QString,QString)));
}
void QGCVehicleConfig::resetCalibrationRC()
{
for (unsigned int i = 0; i < chanMax; ++i)
{
rcMin[i] = INT_MAX;
rcMax[i] = INT_MIN;
}
}
/**
* Sends the RC calibration to the vehicle and stores it in EEPROM
*/
void QGCVehicleConfig::writeCalibrationRC()
{
if (!mav) return;
QString minTpl("RC%1_MIN");
QString maxTpl("RC%1_MAX");
QString trimTpl("RC%1_TRIM");
QString revTpl("RC%1_REV");
// Do not write the RC type, as these values depend on this
// active onboard parameter
for (unsigned int i = 0; i < chanMax; ++i)
{
mav->setParameter(0, minTpl.arg(i), rcMin[i]);
mav->setParameter(0, trimTpl.arg(i), rcTrim[i]);
mav->setParameter(0, maxTpl.arg(i), rcMax[i]);
mav->setParameter(0, revTpl.arg(i), (rcRev[i]) ? -1 : 1);
}
// Write mappings
mav->setParameter(0, "RC_MAP_ROLL", rcMapping[0]);
mav->setParameter(0, "RC_MAP_PITCH", rcMapping[1]);
mav->setParameter(0, "RC_MAP_THROTTLE", rcMapping[2]);
mav->setParameter(0, "RC_MAP_YAW", rcMapping[3]);
mav->setParameter(0, "RC_MAP_MODE_SW", rcMapping[4]);
mav->setParameter(0, "RC_MAP_AUX1", rcMapping[5]);
mav->setParameter(0, "RC_MAP_AUX2", rcMapping[6]);
mav->setParameter(0, "RC_MAP_AUX3", rcMapping[7]);
}
void QGCVehicleConfig::requestCalibrationRC()
{
if (!mav) return;
QString minTpl("RC%1_MIN");
QString maxTpl("RC%1_MAX");
QString trimTpl("RC%1_TRIM");
QString revTpl("RC%1_REV");
// Do not request the RC type, as these values depend on this
// active onboard parameter
for (unsigned int i = 0; i < chanMax; ++i)
{
mav->requestParameter(0, minTpl.arg(i));
usleep(5000);
mav->requestParameter(0, trimTpl.arg(i));
usleep(5000);
mav->requestParameter(0, maxTpl.arg(i));
usleep(5000);
mav->requestParameter(0, revTpl.arg(i));
usleep(5000);
}
}
void QGCVehicleConfig::writeParameters()
{
updateStatus(tr("Writing all onboard parameters."));
writeCalibrationRC();
}
void QGCVehicleConfig::remoteControlChannelRawChanged(int chan, float val)
{
if (chan < 0 || static_cast<unsigned int>(chan) >= chanMax)
return;
if (chan == rcMapping[0])
{
// ROLL
if (rcRoll > rcTrim[chan])
{
rcRoll = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
}
else
{
rcRoll = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
}
rcRoll = qBound(-1.0f, rcRoll, 1.0f);
}
else if (chan == rcMapping[1])
{
// PITCH
if (rcPitch > rcTrim[chan])
{
rcPitch = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
}
else
{
rcPitch = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
}
rcPitch = qBound(-1.0f, rcPitch, 1.0f);
}
else if (chan == rcMapping[2])
{
// YAW
if (rcYaw > rcTrim[chan])
{
rcYaw = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
}
else
{
rcYaw = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
}
rcYaw = qBound(-1.0f, rcYaw, 1.0f);
}
else if (chan == rcMapping[3])
{
// THROTTLE
if (rcThrottle > rcTrim[chan])
{
rcThrottle = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
}
else
{
rcThrottle = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
}
rcThrottle = qBound(-1.0f, rcThrottle, 1.0f);
}
else if (chan == rcMapping[4])
{
// MODE SWITCH
if (rcMode > rcTrim[chan])
{
rcMode = (val - rcTrim[chan])/(rcMax[chan] - rcTrim[chan]);
}
else
{
rcMode = (val - rcMin[chan])/(rcTrim[chan] - rcMin[chan]);
}
rcMode = qBound(-1.0f, rcMode, 1.0f);
}
else if (chan == rcMapping[5])
{
// AUX1
rcAux1 = val;
}
else if (chan == rcMapping[6])
{
// AUX2
rcAux2 = val;
}
else if (chan == rcMapping[7])
{
// AUX3
rcAux3 = val;
}
changed = true;
qDebug() << "RC CHAN:" << chan << "PPM:" << val;
}
void QGCVehicleConfig::parameterChanged(int uas, int component, QString parameterName, QVariant value)
{
Q_UNUSED(uas);
Q_UNUSED(component);
if (rcTypeUpdateRequested > 0 && parameterName == QString("RC_TYPE"))
{
rcTypeUpdateRequested = 0;
updateStatus(tr("Received RC type update, setting parameters based on model."));
rcType = value.toInt();
// Request all other parameters as well
requestCalibrationRC();
}
}
void QGCVehicleConfig::updateStatus(const QString& str)
{
ui->statusLabel->setText(str);
ui->statusLabel->setStyleSheet("");
}
void QGCVehicleConfig::updateError(const QString& str)
{
ui->statusLabel->setText(str);
ui->statusLabel->setStyleSheet(QString("QLabel { margin: 0px 2px; font: 14px; color: %1; background-color: %2; }").arg(QGC::colorDarkWhite.name()).arg(QGC::colorMagenta.name()));
}
void QGCVehicleConfig::setRCType(int type)
{
if (!mav) return;
// XXX TODO Add handling of RC_TYPE vs non-RC_TYPE here
mav->setParameter(0, "RC_TYPE", type);
rcTypeUpdateRequested = QGC::groundTimeMilliseconds();
QTimer::singleShot(rcTypeTimeout+100, this, SLOT(checktimeOuts()));
}
void QGCVehicleConfig::checktimeOuts()
{
if (rcTypeUpdateRequested > 0)
{
if (QGC::groundTimeMilliseconds() - rcTypeUpdateRequested > rcTypeTimeout)
{
updateError(tr("Setting remote control timed out - is the system connected?"));
}
}
}
void QGCVehicleConfig::updateView()
{
if (changed)
{
ui->rollSlider->setValue(rcRoll);
ui->pitchSlider->setValue(rcPitch);
ui->yawSlider->setValue(rcYaw);
ui->throttleSlider->setValue(rcThrottle);
changed = false;
}
}
......@@ -3,6 +3,8 @@
#include <QWidget>
#include "UASInterface.h"
namespace Ui {
class QGCVehicleConfig;
}
......@@ -14,9 +16,66 @@ class QGCVehicleConfig : public QWidget
public:
explicit QGCVehicleConfig(QWidget *parent = 0);
~QGCVehicleConfig();
public slots:
/** Set the MAV currently being calibrated */
void setActiveUAS(UASInterface* active);
/** Start the RC calibration routine */
void startCalibrationRC();
/** Stop the RC calibration routine */
void stopCalibrationRC();
/** Start/stop the RC calibration routine */
void toggleCalibrationRC(bool enabled);
/** Render the data updated */
void updateView();
protected slots:
/** Reset the RC calibration */
void resetCalibrationRC();
/** Write the RC calibration */
void writeCalibrationRC();
/** Request the RC calibration */
void requestCalibrationRC();
/** Store all parameters in onboard EEPROM */
void writeParameters();
/** Receive remote control updates from MAV */
void remoteControlChannelRawChanged(int chan, float val);
/** Parameter changed onboard */
void parameterChanged(int uas, int component, QString parameterName, QVariant value);
void updateStatus(const QString& str);
void updateError(const QString& str);
void setRCType(int type);
/** Check timeouts */
void checktimeOuts();
protected:
UASInterface* mav; ///< The current MAV
static const unsigned int chanMax = 8; ///< Maximum number of channels
int rcType; ///< Type of the remote control
quint64 rcTypeUpdateRequested; ///< Zero if not requested, non-zero if requested
static const unsigned int rcTypeTimeout = 5000; ///< 5 seconds timeout, in milliseconds
int rcMin[chanMax]; ///< Minimum values
int rcMax[chanMax]; ///< Maximum values
int rcTrim[chanMax]; ///< Zero-position (center for roll/pitch/yaw, 0 throttle for throttle)
int rcMapping[chanMax]; ///< PWM to function mappings
bool rcRev[chanMax]; ///< Channel reverse
float rcRoll; ///< PPM input channel used as roll control input
float rcPitch; ///< PPM input channel used as pitch control input
float rcYaw; ///< PPM input channel used as yaw control input
float rcThrottle; ///< PPM input channel used as throttle control input
float rcMode; ///< PPM input channel used as mode switch control input
float rcAux1; ///< PPM input channel used as aux 1 input
float rcAux2; ///< PPM input channel used as aux 1 input
float rcAux3; ///< PPM input channel used as aux 1 input
bool rcCalChanged; ///< Set if the calibration changes (and needs to be written)
bool changed; ///< Set if any of the input data changed
private:
Ui::QGCVehicleConfig *ui;
signals:
void visibilityChanged(bool visible);
};
#endif // QGCVEHICLECONFIG_H
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment