1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-05 21:52:10 +01:00

Merge branch 'master' into heli_improvements

Conflicts:
	shared/uavobjectdefinition/manualcontrolsettings.xml
This commit is contained in:
Oleg Semyonov 2011-06-09 10:11:27 +03:00
commit f766642f0d
63 changed files with 1988 additions and 1433 deletions

View File

@ -14,7 +14,7 @@
height="80.827866" height="80.827866"
id="svg10068" id="svg10068"
version="1.1" version="1.1"
inkscape:version="0.47 r22583" inkscape:version="0.48.1 r9760"
sodipodi:docname="flightmode-status.svg" sodipodi:docname="flightmode-status.svg"
inkscape:export-filename="H:\Documents\Hobbies\W433\My Gauges\vbat-001.png" inkscape:export-filename="H:\Documents\Hobbies\W433\My Gauges\vbat-001.png"
inkscape:export-xdpi="103.61" inkscape:export-xdpi="103.61"
@ -949,6 +949,94 @@
fx="29.77438" fx="29.77438"
fy="7.0922189" fy="7.0922189"
r="25.380436" /> r="25.380436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5224-4"
id="radialGradient3197"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
cx="14.5"
cy="26.6875"
fx="14.5"
fy="26.6875"
r="10" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5224-4"
id="radialGradient3199"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
cx="14.5"
cy="26.6875"
fx="14.5"
fy="26.6875"
r="10" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5237-2"
id="radialGradient3201"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5354369,0,0,1.5485894,-15.737913,-10.36738)"
cx="29.392656"
cy="18.898249"
fx="29.392656"
fy="18.898249"
r="29.699959" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5300-7"
id="radialGradient3203"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.2469896,0,0,2.2469896,-37.128341,-8.8439229)"
cx="29.77438"
cy="7.0922189"
fx="29.77438"
fy="7.0922189"
r="25.380436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5224-4"
id="radialGradient3231"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
cx="14.5"
cy="26.6875"
fx="14.5"
fy="26.6875"
r="10" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5224-4"
id="radialGradient3233"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
cx="14.5"
cy="26.6875"
fx="14.5"
fy="26.6875"
r="10" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5237-2"
id="radialGradient3235"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5354369,0,0,1.5485894,-15.737913,-10.36738)"
cx="29.392656"
cy="18.898249"
fx="29.392656"
fy="18.898249"
r="29.699959" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5300-7"
id="radialGradient3237"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.2469896,0,0,2.2469896,-37.128341,-8.8439229)"
cx="29.77438"
cy="7.0922189"
fx="29.77438"
fy="7.0922189"
r="25.380436" />
</defs> </defs>
<sodipodi:namedview <sodipodi:namedview
id="base" id="base"
@ -958,13 +1046,13 @@
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="1.979899" inkscape:zoom="1.979899"
inkscape:cx="56.191298" inkscape:cx="-7.1957738"
inkscape:cy="90.710362" inkscape:cy="90.710362"
inkscape:document-units="px" inkscape:document-units="px"
inkscape:current-layer="layer1" inkscape:current-layer="layer1"
showgrid="false" showgrid="false"
inkscape:window-width="1280" inkscape:window-width="1366"
inkscape:window-height="725" inkscape:window-height="691"
inkscape:window-x="0" inkscape:window-x="0"
inkscape:window-y="24" inkscape:window-y="24"
inkscape:window-maximized="1" inkscape:window-maximized="1"
@ -1090,13 +1178,13 @@
style="opacity:0.98000004;fill:#ffffff;fill-opacity:1;stroke:#e31717;stroke-width:3.18836617;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" style="opacity:0.98000004;fill:#ffffff;fill-opacity:1;stroke:#e31717;stroke-width:3.18836617;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="value" id="value"
width="132.66878" width="132.66878"
height="20.899738" height="13.323594"
x="15.425945" x="15.425945"
y="29.964067" y="33.75214"
ry="5.4077783" ry="3.4474616"
inkscape:label="#rect2989" /> inkscape:label="#rect2989" />
<g <g
id="symbol-Stabilized" id="symbol-Stabilized1"
inkscape:label="#g3832" inkscape:label="#g3832"
transform="matrix(1.2181818,0,0,1.2181818,-416.7342,39.213763)"> transform="matrix(1.2181818,0,0,1.2181818,-416.7342,39.213763)">
<g <g
@ -1297,7 +1385,7 @@
</g> </g>
</g> </g>
<g <g
id="symbol-Auto" id="symbol-VelocityControl"
inkscape:label="#g4229" inkscape:label="#g4229"
transform="matrix(1.2181818,0,0,1.2181818,-132.92733,94.550987)"> transform="matrix(1.2181818,0,0,1.2181818,-132.92733,94.550987)">
<g <g
@ -1354,5 +1442,245 @@
inkscape:export-xdpi="103.61" inkscape:export-xdpi="103.61"
inkscape:export-ydpi="103.61" /> inkscape:export-ydpi="103.61" />
</g> </g>
<g
transform="matrix(1.2181818,0,0,1.2181818,-488.7342,39.213763)"
inkscape:label="#g3832"
id="symbol-Stabilized2">
<g
style="display:inline"
id="g3173"
inkscape:label="#g4504"
transform="matrix(1.6946172,0,0,1.6946172,90.69312,69.91641)">
<path
d="m 24.5,26.6875 c 0,1.622336 -4.477153,2.9375 -10,2.9375 -5.5228475,0 -10,-1.315164 -10,-2.9375 0,-1.622336 4.4771525,-2.9375 10,-2.9375 5.522847,0 10,1.315164 10,2.9375 z"
id="path3175"
sodipodi:cx="14.5"
sodipodi:cy="26.6875"
sodipodi:rx="10"
sodipodi:ry="2.9375"
sodipodi:type="arc"
style="opacity:0.53012049;color:#000000;fill:url(#radialGradient3197);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296-2);enable-background:accumulate"
transform="matrix(1.3565115,0,0,1.3564842,148.6163,-105.84566)" />
<path
d="m 24.5,26.6875 c 0,1.622336 -4.477153,2.9375 -10,2.9375 -5.5228475,0 -10,-1.315164 -10,-2.9375 0,-1.622336 4.4771525,-2.9375 10,-2.9375 5.522847,0 10,1.315164 10,2.9375 z"
id="path3177"
sodipodi:cx="14.5"
sodipodi:cy="26.6875"
sodipodi:rx="10"
sodipodi:ry="2.9375"
sodipodi:type="arc"
style="opacity:0.80120479;color:#000000;fill:url(#radialGradient3199);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296-2);enable-background:accumulate"
transform="matrix(0.8476709,0,0,0.8476539,155.99448,-91.479567)" />
<path
d="m 58.403591,29.207693 c 0,16.022297 -12.988638,29.010935 -29.010935,29.010935 -16.022297,0 -29.0109345,-12.988638 -29.0109345,-29.010935 0,-16.022297 12.9886375,-29.01093473 29.0109345,-29.01093473 16.022297,0 29.010935,12.98863773 29.010935,29.01093473 z"
id="path3179"
sodipodi:cx="29.392656"
sodipodi:cy="29.207693"
sodipodi:rx="29.010935"
sodipodi:ry="29.010935"
sodipodi:type="arc"
style="fill:url(#radialGradient3201);fill-opacity:1;fill-rule:evenodd;stroke:#d4d0d0;stroke-width:2.19046068;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
transform="matrix(0.4552142,0,0,0.4578395,154.92379,-94.080092)" />
<path
d="m 53.950159,30.352861 c 0,13.351915 -10.823865,24.17578 -24.175779,24.17578 -13.351915,0 -24.1757796,-10.823865 -24.1757796,-24.17578 0,-13.351914 10.8238646,-24.1757789 24.1757796,-24.1757789 13.351914,0 24.175779,10.8238649 24.175779,24.1757789 z"
id="path3181"
sodipodi:cx="29.77438"
sodipodi:cy="30.352861"
sodipodi:rx="24.175779"
sodipodi:ry="24.175779"
sodipodi:type="arc"
style="fill:none;stroke:url(#radialGradient3203);stroke-width:1.98282218;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
transform="matrix(0.5041973,0,0,0.5044661,153.2742,-96.019639)" />
</g>
<g
style="stroke-width:5.32037735;stroke-miterlimit:4;stroke-dasharray:none"
id="g3183"
transform="matrix(0.33832187,0,0,0.33832187,410.06766,-39.187259)">
<path
sodipodi:open="true"
sodipodi:type="arc"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.56557703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
id="path3185"
sodipodi:cx="-102.85714"
sodipodi:cy="-85.6007"
sodipodi:rx="21.428572"
sodipodi:ry="5.7142859"
d="m -124.28571,-85.600701 c 0,-3.155913 9.5939,-5.714285 21.42857,-5.714285 11.834674,0 21.428572,2.558373 21.428572,5.714286"
transform="matrix(0.9559435,0,0,0.9559435,-2.74581,-3.77127)"
sodipodi:start="3.1415927"
sodipodi:end="6.2831853" />
<path
transform="translate(0,-0.35714)"
d="m -51.42857,-85.243561 c 0,6.50907 -22.225864,11.785714 -49.64286,11.785714 -27.41699,0 -49.64285,-5.276644 -49.64285,-11.785714 0,-6.50907 22.22586,-11.785714 49.64285,-11.785714 27.416996,0 49.64286,5.276644 49.64286,11.785714 z"
sodipodi:ry="11.785714"
sodipodi:rx="49.642857"
sodipodi:cy="-85.243561"
sodipodi:cx="-101.07143"
id="path3187"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
sodipodi:type="arc" />
<path
id="path3189"
d="m -101.07143,-37.895278 0,-96.382562"
style="fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
sodipodi:open="true"
transform="matrix(0.9559435,0,0,0.9559435,-2.7458124,-3.7712673)"
d="m -81.428568,-85.6007 c 0,3.155913 -9.593898,5.714285 -21.428572,5.714285 -11.83467,0 -21.42857,-2.558372 -21.42857,-5.714285 0,0 0,-10e-7 0,-10e-7"
sodipodi:ry="5.7142859"
sodipodi:rx="21.428572"
sodipodi:cy="-85.6007"
sodipodi:cx="-102.85714"
id="path3191"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.56557703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc"
sodipodi:start="0"
sodipodi:end="3.1415927" />
<path
transform="matrix(1.0062564,0,0,1,1.3510971,0)"
d="m -81.42857,-85.6007 c 0,21.6969 -9.114203,39.285713 -20.35714,39.285713 -11.24294,0 -20.35715,-17.588813 -20.35715,-39.285713 0,-21.6969 9.11421,-39.28571 20.35715,-39.28571 11.242937,0 20.35714,17.58881 20.35714,39.28571 z"
sodipodi:ry="39.285713"
sodipodi:rx="20.357143"
sodipodi:cy="-85.6007"
sodipodi:cx="-101.78571"
id="path3193"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.30381203;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc" />
<path
sodipodi:open="true"
sodipodi:end="3.1415927"
sodipodi:start="0"
sodipodi:type="arc"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3195"
sodipodi:cx="-101.07143"
sodipodi:cy="-85.243561"
sodipodi:rx="49.642857"
sodipodi:ry="11.785714"
d="m -51.42857,-85.243561 c 0,6.50907 -22.225864,11.785714 -49.64286,11.785714 -27.41699,0 -49.64285,-5.276644 -49.64285,-11.785714 0,0 0,0 0,0"
transform="translate(0,-0.35713959)" />
</g>
</g>
<g
id="symbol-Stabilized3"
inkscape:label="#g3832"
transform="matrix(1.2181818,0,0,1.2181818,-488.7342,-34.786237)">
<g
transform="matrix(1.6946172,0,0,1.6946172,90.69312,69.91641)"
inkscape:label="#g4504"
id="g3207"
style="display:inline">
<path
transform="matrix(1.3565115,0,0,1.3564842,148.6163,-105.84566)"
style="opacity:0.53012049;color:#000000;fill:url(#radialGradient3231);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296-2);enable-background:accumulate"
sodipodi:type="arc"
sodipodi:ry="2.9375"
sodipodi:rx="10"
sodipodi:cy="26.6875"
sodipodi:cx="14.5"
id="path3209"
d="m 24.5,26.6875 c 0,1.622336 -4.477153,2.9375 -10,2.9375 -5.5228475,0 -10,-1.315164 -10,-2.9375 0,-1.622336 4.4771525,-2.9375 10,-2.9375 5.522847,0 10,1.315164 10,2.9375 z" />
<path
transform="matrix(0.8476709,0,0,0.8476539,155.99448,-91.479567)"
style="opacity:0.80120479;color:#000000;fill:url(#radialGradient3233);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296-2);enable-background:accumulate"
sodipodi:type="arc"
sodipodi:ry="2.9375"
sodipodi:rx="10"
sodipodi:cy="26.6875"
sodipodi:cx="14.5"
id="path3211"
d="m 24.5,26.6875 c 0,1.622336 -4.477153,2.9375 -10,2.9375 -5.5228475,0 -10,-1.315164 -10,-2.9375 0,-1.622336 4.4771525,-2.9375 10,-2.9375 5.522847,0 10,1.315164 10,2.9375 z" />
<path
transform="matrix(0.4552142,0,0,0.4578395,154.92379,-94.080092)"
style="fill:url(#radialGradient3235);fill-opacity:1;fill-rule:evenodd;stroke:#d4d0d0;stroke-width:2.19046068;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc"
sodipodi:ry="29.010935"
sodipodi:rx="29.010935"
sodipodi:cy="29.207693"
sodipodi:cx="29.392656"
id="path3213"
d="m 58.403591,29.207693 c 0,16.022297 -12.988638,29.010935 -29.010935,29.010935 -16.022297,0 -29.0109345,-12.988638 -29.0109345,-29.010935 0,-16.022297 12.9886375,-29.01093473 29.0109345,-29.01093473 16.022297,0 29.010935,12.98863773 29.010935,29.01093473 z" />
<path
transform="matrix(0.5041973,0,0,0.5044661,153.2742,-96.019639)"
style="fill:none;stroke:url(#radialGradient3237);stroke-width:1.98282218;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc"
sodipodi:ry="24.175779"
sodipodi:rx="24.175779"
sodipodi:cy="30.352861"
sodipodi:cx="29.77438"
id="path3215"
d="m 53.950159,30.352861 c 0,13.351915 -10.823865,24.17578 -24.175779,24.17578 -13.351915,0 -24.1757796,-10.823865 -24.1757796,-24.17578 0,-13.351914 10.8238646,-24.1757789 24.1757796,-24.1757789 13.351914,0 24.175779,10.8238649 24.175779,24.1757789 z" />
</g>
<g
transform="matrix(0.33832187,0,0,0.33832187,410.06766,-39.187259)"
id="g3217"
style="stroke-width:5.32037735;stroke-miterlimit:4;stroke-dasharray:none">
<path
sodipodi:end="6.2831853"
sodipodi:start="3.1415927"
transform="matrix(0.9559435,0,0,0.9559435,-2.74581,-3.77127)"
d="m -124.28571,-85.600701 c 0,-3.155913 9.5939,-5.714285 21.42857,-5.714285 11.834674,0 21.428572,2.558373 21.428572,5.714286"
sodipodi:ry="5.7142859"
sodipodi:rx="21.428572"
sodipodi:cy="-85.6007"
sodipodi:cx="-102.85714"
id="path3219"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.56557703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
sodipodi:type="arc"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
id="path3221"
sodipodi:cx="-101.07143"
sodipodi:cy="-85.243561"
sodipodi:rx="49.642857"
sodipodi:ry="11.785714"
d="m -51.42857,-85.243561 c 0,6.50907 -22.225864,11.785714 -49.64286,11.785714 -27.41699,0 -49.64285,-5.276644 -49.64285,-11.785714 0,-6.50907 22.22586,-11.785714 49.64285,-11.785714 27.416996,0 49.64286,5.276644 49.64286,11.785714 z"
transform="translate(0,-0.35714)" />
<path
inkscape:connector-curvature="0"
style="fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m -101.07143,-37.895278 0,-96.382562"
id="path3223" />
<path
sodipodi:end="3.1415927"
sodipodi:start="0"
sodipodi:type="arc"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.56557703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3225"
sodipodi:cx="-102.85714"
sodipodi:cy="-85.6007"
sodipodi:rx="21.428572"
sodipodi:ry="5.7142859"
d="m -81.428568,-85.6007 c 0,3.155913 -9.593898,5.714285 -21.428572,5.714285 -11.83467,0 -21.42857,-2.558372 -21.42857,-5.714285 0,0 0,-10e-7 0,-10e-7"
transform="matrix(0.9559435,0,0,0.9559435,-2.7458124,-3.7712673)"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.30381203;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3227"
sodipodi:cx="-101.78571"
sodipodi:cy="-85.6007"
sodipodi:rx="20.357143"
sodipodi:ry="39.285713"
d="m -81.42857,-85.6007 c 0,21.6969 -9.114203,39.285713 -20.35714,39.285713 -11.24294,0 -20.35715,-17.588813 -20.35715,-39.285713 0,-21.6969 9.11421,-39.28571 20.35715,-39.28571 11.242937,0 20.35714,17.58881 20.35714,39.28571 z"
transform="matrix(1.0062564,0,0,1,1.3510971,0)" />
<path
transform="translate(0,-0.35713959)"
d="m -51.42857,-85.243561 c 0,6.50907 -22.225864,11.785714 -49.64286,11.785714 -27.41699,0 -49.64285,-5.276644 -49.64285,-11.785714 0,0 0,0 0,0"
sodipodi:ry="11.785714"
sodipodi:rx="49.642857"
sodipodi:cy="-85.243561"
sodipodi:cx="-101.07143"
id="path3229"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc"
sodipodi:start="0"
sodipodi:end="3.1415927"
sodipodi:open="true" />
</g>
</g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -14,7 +14,7 @@
height="80.827866" height="80.827866"
id="svg10068" id="svg10068"
version="1.1" version="1.1"
inkscape:version="0.47 r22583" inkscape:version="0.48.1 r9760"
sodipodi:docname="flightmode-status.svg" sodipodi:docname="flightmode-status.svg"
inkscape:export-filename="H:\Documents\Hobbies\W433\My Gauges\vbat-001.png" inkscape:export-filename="H:\Documents\Hobbies\W433\My Gauges\vbat-001.png"
inkscape:export-xdpi="103.61" inkscape:export-xdpi="103.61"
@ -949,6 +949,94 @@
fx="29.77438" fx="29.77438"
fy="7.0922189" fy="7.0922189"
r="25.380436" /> r="25.380436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5224-4"
id="radialGradient3197"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
cx="14.5"
cy="26.6875"
fx="14.5"
fy="26.6875"
r="10" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5224-4"
id="radialGradient3199"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
cx="14.5"
cy="26.6875"
fx="14.5"
fy="26.6875"
r="10" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5237-2"
id="radialGradient3201"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5354369,0,0,1.5485894,-15.737913,-10.36738)"
cx="29.392656"
cy="18.898249"
fx="29.392656"
fy="18.898249"
r="29.699959" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5300-7"
id="radialGradient3203"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.2469896,0,0,2.2469896,-37.128341,-8.8439229)"
cx="29.77438"
cy="7.0922189"
fx="29.77438"
fy="7.0922189"
r="25.380436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5224-4"
id="radialGradient3231"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
cx="14.5"
cy="26.6875"
fx="14.5"
fy="26.6875"
r="10" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5224-4"
id="radialGradient3233"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.29375,0,18.848047)"
cx="14.5"
cy="26.6875"
fx="14.5"
fy="26.6875"
r="10" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5237-2"
id="radialGradient3235"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5354369,0,0,1.5485894,-15.737913,-10.36738)"
cx="29.392656"
cy="18.898249"
fx="29.392656"
fy="18.898249"
r="29.699959" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5300-7"
id="radialGradient3237"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.2469896,0,0,2.2469896,-37.128341,-8.8439229)"
cx="29.77438"
cy="7.0922189"
fx="29.77438"
fy="7.0922189"
r="25.380436" />
</defs> </defs>
<sodipodi:namedview <sodipodi:namedview
id="base" id="base"
@ -958,13 +1046,13 @@
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="1.979899" inkscape:zoom="1.979899"
inkscape:cx="56.191298" inkscape:cx="-7.1957738"
inkscape:cy="90.710362" inkscape:cy="90.710362"
inkscape:document-units="px" inkscape:document-units="px"
inkscape:current-layer="layer1" inkscape:current-layer="layer1"
showgrid="false" showgrid="false"
inkscape:window-width="1280" inkscape:window-width="1366"
inkscape:window-height="725" inkscape:window-height="691"
inkscape:window-x="0" inkscape:window-x="0"
inkscape:window-y="24" inkscape:window-y="24"
inkscape:window-maximized="1" inkscape:window-maximized="1"
@ -1090,13 +1178,13 @@
style="opacity:0.98000004;fill:#ffffff;fill-opacity:1;stroke:#e31717;stroke-width:3.18836617;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" style="opacity:0.98000004;fill:#ffffff;fill-opacity:1;stroke:#e31717;stroke-width:3.18836617;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="value" id="value"
width="132.66878" width="132.66878"
height="20.899738" height="13.323594"
x="15.425945" x="15.425945"
y="29.964067" y="33.75214"
ry="5.4077783" ry="3.4474616"
inkscape:label="#rect2989" /> inkscape:label="#rect2989" />
<g <g
id="symbol-Stabilized" id="symbol-Stabilized1"
inkscape:label="#g3832" inkscape:label="#g3832"
transform="matrix(1.2181818,0,0,1.2181818,-416.7342,39.213763)"> transform="matrix(1.2181818,0,0,1.2181818,-416.7342,39.213763)">
<g <g
@ -1297,7 +1385,7 @@
</g> </g>
</g> </g>
<g <g
id="symbol-Auto" id="symbol-VelocityControl"
inkscape:label="#g4229" inkscape:label="#g4229"
transform="matrix(1.2181818,0,0,1.2181818,-132.92733,94.550987)"> transform="matrix(1.2181818,0,0,1.2181818,-132.92733,94.550987)">
<g <g
@ -1354,5 +1442,245 @@
inkscape:export-xdpi="103.61" inkscape:export-xdpi="103.61"
inkscape:export-ydpi="103.61" /> inkscape:export-ydpi="103.61" />
</g> </g>
<g
transform="matrix(1.2181818,0,0,1.2181818,-488.7342,39.213763)"
inkscape:label="#g3832"
id="symbol-Stabilized2">
<g
style="display:inline"
id="g3173"
inkscape:label="#g4504"
transform="matrix(1.6946172,0,0,1.6946172,90.69312,69.91641)">
<path
d="m 24.5,26.6875 c 0,1.622336 -4.477153,2.9375 -10,2.9375 -5.5228475,0 -10,-1.315164 -10,-2.9375 0,-1.622336 4.4771525,-2.9375 10,-2.9375 5.522847,0 10,1.315164 10,2.9375 z"
id="path3175"
sodipodi:cx="14.5"
sodipodi:cy="26.6875"
sodipodi:rx="10"
sodipodi:ry="2.9375"
sodipodi:type="arc"
style="opacity:0.53012049;color:#000000;fill:url(#radialGradient3197);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296-2);enable-background:accumulate"
transform="matrix(1.3565115,0,0,1.3564842,148.6163,-105.84566)" />
<path
d="m 24.5,26.6875 c 0,1.622336 -4.477153,2.9375 -10,2.9375 -5.5228475,0 -10,-1.315164 -10,-2.9375 0,-1.622336 4.4771525,-2.9375 10,-2.9375 5.522847,0 10,1.315164 10,2.9375 z"
id="path3177"
sodipodi:cx="14.5"
sodipodi:cy="26.6875"
sodipodi:rx="10"
sodipodi:ry="2.9375"
sodipodi:type="arc"
style="opacity:0.80120479;color:#000000;fill:url(#radialGradient3199);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296-2);enable-background:accumulate"
transform="matrix(0.8476709,0,0,0.8476539,155.99448,-91.479567)" />
<path
d="m 58.403591,29.207693 c 0,16.022297 -12.988638,29.010935 -29.010935,29.010935 -16.022297,0 -29.0109345,-12.988638 -29.0109345,-29.010935 0,-16.022297 12.9886375,-29.01093473 29.0109345,-29.01093473 16.022297,0 29.010935,12.98863773 29.010935,29.01093473 z"
id="path3179"
sodipodi:cx="29.392656"
sodipodi:cy="29.207693"
sodipodi:rx="29.010935"
sodipodi:ry="29.010935"
sodipodi:type="arc"
style="fill:url(#radialGradient3201);fill-opacity:1;fill-rule:evenodd;stroke:#d4d0d0;stroke-width:2.19046068;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
transform="matrix(0.4552142,0,0,0.4578395,154.92379,-94.080092)" />
<path
d="m 53.950159,30.352861 c 0,13.351915 -10.823865,24.17578 -24.175779,24.17578 -13.351915,0 -24.1757796,-10.823865 -24.1757796,-24.17578 0,-13.351914 10.8238646,-24.1757789 24.1757796,-24.1757789 13.351914,0 24.175779,10.8238649 24.175779,24.1757789 z"
id="path3181"
sodipodi:cx="29.77438"
sodipodi:cy="30.352861"
sodipodi:rx="24.175779"
sodipodi:ry="24.175779"
sodipodi:type="arc"
style="fill:none;stroke:url(#radialGradient3203);stroke-width:1.98282218;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
transform="matrix(0.5041973,0,0,0.5044661,153.2742,-96.019639)" />
</g>
<g
style="stroke-width:5.32037735;stroke-miterlimit:4;stroke-dasharray:none"
id="g3183"
transform="matrix(0.33832187,0,0,0.33832187,410.06766,-39.187259)">
<path
sodipodi:open="true"
sodipodi:type="arc"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.56557703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
id="path3185"
sodipodi:cx="-102.85714"
sodipodi:cy="-85.6007"
sodipodi:rx="21.428572"
sodipodi:ry="5.7142859"
d="m -124.28571,-85.600701 c 0,-3.155913 9.5939,-5.714285 21.42857,-5.714285 11.834674,0 21.428572,2.558373 21.428572,5.714286"
transform="matrix(0.9559435,0,0,0.9559435,-2.74581,-3.77127)"
sodipodi:start="3.1415927"
sodipodi:end="6.2831853" />
<path
transform="translate(0,-0.35714)"
d="m -51.42857,-85.243561 c 0,6.50907 -22.225864,11.785714 -49.64286,11.785714 -27.41699,0 -49.64285,-5.276644 -49.64285,-11.785714 0,-6.50907 22.22586,-11.785714 49.64285,-11.785714 27.416996,0 49.64286,5.276644 49.64286,11.785714 z"
sodipodi:ry="11.785714"
sodipodi:rx="49.642857"
sodipodi:cy="-85.243561"
sodipodi:cx="-101.07143"
id="path3187"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
sodipodi:type="arc" />
<path
id="path3189"
d="m -101.07143,-37.895278 0,-96.382562"
style="fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
sodipodi:open="true"
transform="matrix(0.9559435,0,0,0.9559435,-2.7458124,-3.7712673)"
d="m -81.428568,-85.6007 c 0,3.155913 -9.593898,5.714285 -21.428572,5.714285 -11.83467,0 -21.42857,-2.558372 -21.42857,-5.714285 0,0 0,-10e-7 0,-10e-7"
sodipodi:ry="5.7142859"
sodipodi:rx="21.428572"
sodipodi:cy="-85.6007"
sodipodi:cx="-102.85714"
id="path3191"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.56557703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc"
sodipodi:start="0"
sodipodi:end="3.1415927" />
<path
transform="matrix(1.0062564,0,0,1,1.3510971,0)"
d="m -81.42857,-85.6007 c 0,21.6969 -9.114203,39.285713 -20.35714,39.285713 -11.24294,0 -20.35715,-17.588813 -20.35715,-39.285713 0,-21.6969 9.11421,-39.28571 20.35715,-39.28571 11.242937,0 20.35714,17.58881 20.35714,39.28571 z"
sodipodi:ry="39.285713"
sodipodi:rx="20.357143"
sodipodi:cy="-85.6007"
sodipodi:cx="-101.78571"
id="path3193"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.30381203;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc" />
<path
sodipodi:open="true"
sodipodi:end="3.1415927"
sodipodi:start="0"
sodipodi:type="arc"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3195"
sodipodi:cx="-101.07143"
sodipodi:cy="-85.243561"
sodipodi:rx="49.642857"
sodipodi:ry="11.785714"
d="m -51.42857,-85.243561 c 0,6.50907 -22.225864,11.785714 -49.64286,11.785714 -27.41699,0 -49.64285,-5.276644 -49.64285,-11.785714 0,0 0,0 0,0"
transform="translate(0,-0.35713959)" />
</g>
</g>
<g
id="symbol-Stabilized3"
inkscape:label="#g3832"
transform="matrix(1.2181818,0,0,1.2181818,-488.7342,-34.786237)">
<g
transform="matrix(1.6946172,0,0,1.6946172,90.69312,69.91641)"
inkscape:label="#g4504"
id="g3207"
style="display:inline">
<path
transform="matrix(1.3565115,0,0,1.3564842,148.6163,-105.84566)"
style="opacity:0.53012049;color:#000000;fill:url(#radialGradient3231);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296-2);enable-background:accumulate"
sodipodi:type="arc"
sodipodi:ry="2.9375"
sodipodi:rx="10"
sodipodi:cy="26.6875"
sodipodi:cx="14.5"
id="path3209"
d="m 24.5,26.6875 c 0,1.622336 -4.477153,2.9375 -10,2.9375 -5.5228475,0 -10,-1.315164 -10,-2.9375 0,-1.622336 4.4771525,-2.9375 10,-2.9375 5.522847,0 10,1.315164 10,2.9375 z" />
<path
transform="matrix(0.8476709,0,0,0.8476539,155.99448,-91.479567)"
style="opacity:0.80120479;color:#000000;fill:url(#radialGradient3233);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5296-2);enable-background:accumulate"
sodipodi:type="arc"
sodipodi:ry="2.9375"
sodipodi:rx="10"
sodipodi:cy="26.6875"
sodipodi:cx="14.5"
id="path3211"
d="m 24.5,26.6875 c 0,1.622336 -4.477153,2.9375 -10,2.9375 -5.5228475,0 -10,-1.315164 -10,-2.9375 0,-1.622336 4.4771525,-2.9375 10,-2.9375 5.522847,0 10,1.315164 10,2.9375 z" />
<path
transform="matrix(0.4552142,0,0,0.4578395,154.92379,-94.080092)"
style="fill:url(#radialGradient3235);fill-opacity:1;fill-rule:evenodd;stroke:#d4d0d0;stroke-width:2.19046068;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
sodipodi:type="arc"
sodipodi:ry="29.010935"
sodipodi:rx="29.010935"
sodipodi:cy="29.207693"
sodipodi:cx="29.392656"
id="path3213"
d="m 58.403591,29.207693 c 0,16.022297 -12.988638,29.010935 -29.010935,29.010935 -16.022297,0 -29.0109345,-12.988638 -29.0109345,-29.010935 0,-16.022297 12.9886375,-29.01093473 29.0109345,-29.01093473 16.022297,0 29.010935,12.98863773 29.010935,29.01093473 z" />
<path
transform="matrix(0.5041973,0,0,0.5044661,153.2742,-96.019639)"
style="fill:none;stroke:url(#radialGradient3237);stroke-width:1.98282218;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc"
sodipodi:ry="24.175779"
sodipodi:rx="24.175779"
sodipodi:cy="30.352861"
sodipodi:cx="29.77438"
id="path3215"
d="m 53.950159,30.352861 c 0,13.351915 -10.823865,24.17578 -24.175779,24.17578 -13.351915,0 -24.1757796,-10.823865 -24.1757796,-24.17578 0,-13.351914 10.8238646,-24.1757789 24.1757796,-24.1757789 13.351914,0 24.175779,10.8238649 24.175779,24.1757789 z" />
</g>
<g
transform="matrix(0.33832187,0,0,0.33832187,410.06766,-39.187259)"
id="g3217"
style="stroke-width:5.32037735;stroke-miterlimit:4;stroke-dasharray:none">
<path
sodipodi:end="6.2831853"
sodipodi:start="3.1415927"
transform="matrix(0.9559435,0,0,0.9559435,-2.74581,-3.77127)"
d="m -124.28571,-85.600701 c 0,-3.155913 9.5939,-5.714285 21.42857,-5.714285 11.834674,0 21.428572,2.558373 21.428572,5.714286"
sodipodi:ry="5.7142859"
sodipodi:rx="21.428572"
sodipodi:cy="-85.6007"
sodipodi:cx="-102.85714"
id="path3219"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.56557703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
sodipodi:type="arc"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
id="path3221"
sodipodi:cx="-101.07143"
sodipodi:cy="-85.243561"
sodipodi:rx="49.642857"
sodipodi:ry="11.785714"
d="m -51.42857,-85.243561 c 0,6.50907 -22.225864,11.785714 -49.64286,11.785714 -27.41699,0 -49.64285,-5.276644 -49.64285,-11.785714 0,-6.50907 22.22586,-11.785714 49.64285,-11.785714 27.416996,0 49.64286,5.276644 49.64286,11.785714 z"
transform="translate(0,-0.35714)" />
<path
inkscape:connector-curvature="0"
style="fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m -101.07143,-37.895278 0,-96.382562"
id="path3223" />
<path
sodipodi:end="3.1415927"
sodipodi:start="0"
sodipodi:type="arc"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.56557703;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3225"
sodipodi:cx="-102.85714"
sodipodi:cy="-85.6007"
sodipodi:rx="21.428572"
sodipodi:ry="5.7142859"
d="m -81.428568,-85.6007 c 0,3.155913 -9.593898,5.714285 -21.428572,5.714285 -11.83467,0 -21.42857,-2.558372 -21.42857,-5.714285 0,0 0,-10e-7 0,-10e-7"
transform="matrix(0.9559435,0,0,0.9559435,-2.7458124,-3.7712673)"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.30381203;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3227"
sodipodi:cx="-101.78571"
sodipodi:cy="-85.6007"
sodipodi:rx="20.357143"
sodipodi:ry="39.285713"
d="m -81.42857,-85.6007 c 0,21.6969 -9.114203,39.285713 -20.35714,39.285713 -11.24294,0 -20.35715,-17.588813 -20.35715,-39.285713 0,-21.6969 9.11421,-39.28571 20.35715,-39.28571 11.242937,0 20.35714,17.58881 20.35714,39.28571 z"
transform="matrix(1.0062564,0,0,1,1.3510971,0)" />
<path
transform="translate(0,-0.35713959)"
d="m -51.42857,-85.243561 c 0,6.50907 -22.225864,11.785714 -49.64286,11.785714 -27.41699,0 -49.64285,-5.276644 -49.64285,-11.785714 0,0 0,0 0,0"
sodipodi:ry="11.785714"
sodipodi:rx="49.642857"
sodipodi:cy="-85.243561"
sodipodi:cx="-101.07143"
id="path3229"
style="opacity:0.98000004;fill:none;stroke:#ff4e34;stroke-width:5.32037735;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
sodipodi:type="arc"
sodipodi:start="0"
sodipodi:end="3.1415927"
sodipodi:open="true" />
</g>
</g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -673,16 +673,6 @@ new home location unless it is in indoor mode.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="ahrsSettingsRequest">
<property name="toolTip">
<string>Refresh this screen with current values from the board.</string>
</property>
<property name="text">
<string>Request</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="ahrsSettingsSaveRAM"> <widget class="QPushButton" name="ahrsSettingsSaveRAM">
<property name="toolTip"> <property name="toolTip">

View File

@ -1962,16 +1962,6 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="getAircraftCurrent">
<property name="toolTip">
<string>Retrieve settings from OpenPilot</string>
</property>
<property name="text">
<string>Get Current</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="saveAircraftToRAM"> <widget class="QPushButton" name="saveAircraftToRAM">
<property name="toolTip"> <property name="toolTip">
@ -2316,16 +2306,6 @@ p, li { white-space: pre-wrap; }
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="QPushButton" name="ffGetCurrent">
<property name="toolTip">
<string>Request current settings from the board.</string>
</property>
<property name="text">
<string>Get Current</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="ffApply"> <widget class="QPushButton" name="ffApply">
<property name="toolTip"> <property name="toolTip">

View File

@ -325,13 +325,6 @@ arming it in that case!</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="getCurrentButton">
<property name="text">
<string>Get Current</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="applyButton"> <widget class="QPushButton" name="applyButton">
<property name="text"> <property name="text">

View File

@ -216,18 +216,25 @@ ConfigAHRSWidget::ConfigAHRSWidget(QWidget *parent) : ConfigTaskWidget(parent)
// Connect the signals // Connect the signals
connect(m_ahrs->ahrsCalibStart, SIGNAL(clicked()), this, SLOT(launchAHRSCalibration())); connect(m_ahrs->ahrsCalibStart, SIGNAL(clicked()), this, SLOT(launchAHRSCalibration()));
connect(m_ahrs->accelBiasStart, SIGNAL(clicked()), this, SLOT(launchAccelBiasCalibration())); connect(m_ahrs->accelBiasStart, SIGNAL(clicked()), this, SLOT(launchAccelBiasCalibration()));
connect(m_ahrs->ahrsSettingsRequest, SIGNAL(clicked()), this, SLOT(ahrsSettingsRequest()));
/* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSSettings")));
connect(m_ahrs->algorithm, SIGNAL(currentIndexChanged(int)), this, SLOT(ahrsSettingsSave())); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(refreshValues()));
connect(m_ahrs->indoorFlight, SIGNAL(stateChanged(int)), this, SLOT(homeLocationSave())); obj = getObjectManager()->getObject(QString("HomeLocation"));
connect(m_ahrs->homeLocation, SIGNAL(clicked()), this, SLOT(homeLocationSaveSD())); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(refreshValues()));
*/
connect(m_ahrs->ahrsSettingsSaveRAM, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveRAM())); connect(m_ahrs->ahrsSettingsSaveRAM, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveRAM()));
connect(m_ahrs->ahrsSettingsSaveSD, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveSD())); connect(m_ahrs->ahrsSettingsSaveSD, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveSD()));
connect(m_ahrs->sixPointsStart, SIGNAL(clicked()), this, SLOT(multiPointCalibrationMode())); connect(m_ahrs->sixPointsStart, SIGNAL(clicked()), this, SLOT(multiPointCalibrationMode()));
connect(m_ahrs->sixPointsSave, SIGNAL(clicked()), this, SLOT(savePositionData())); connect(m_ahrs->sixPointsSave, SIGNAL(clicked()), this, SLOT(savePositionData()));
connect(m_ahrs->startDriftCalib, SIGNAL(clicked()),this, SLOT(launchGyroDriftCalibration())); connect(m_ahrs->startDriftCalib, SIGNAL(clicked()),this, SLOT(launchGyroDriftCalibration()));
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(ahrsSettingsRequest()));
// Order is important: 1st request the settings (it will also enable the controls)
// then explicitely disable them. They will be re-enabled right afterwards by the
// configgadgetwidget if the autopilot is actually connected.
refreshValues();
// when the AHRS Widget is instanciated, the autopilot is always connected // enableControls(false);
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
connect(parent, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()));
// Connect the help button // Connect the help button
connect(m_ahrs->ahrsHelp, SIGNAL(clicked()), this, SLOT(openHelp())); connect(m_ahrs->ahrsHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
@ -256,6 +263,13 @@ void ConfigAHRSWidget::resizeEvent(QResizeEvent *event)
m_ahrs->sixPointsHelp->fitInView(paperplane,Qt::KeepAspectRatio); m_ahrs->sixPointsHelp->fitInView(paperplane,Qt::KeepAspectRatio);
} }
void ConfigAHRSWidget::enableControls(bool enable)
{
//m_ahrs->ahrsSettingsSaveRAM->setEnabled(enable);
m_ahrs->ahrsSettingsSaveSD->setEnabled(enable);
}
/** /**
Starts an accelerometer bias calibration. Starts an accelerometer bias calibration.
*/ */
@ -274,7 +288,7 @@ void ConfigAHRSWidget::launchAccelBiasCalibration()
accel_accum_y.clear(); accel_accum_y.clear();
accel_accum_z.clear(); accel_accum_z.clear();
UAVDataObject* ahrsCalib = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSCalibration"))); // UAVDataObject* ahrsCalib = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSCalibration")));
// ahrsCalib->getField("accel_bias")->setDouble(0,0); // ahrsCalib->getField("accel_bias")->setDouble(0,0);
// ahrsCalib->getField("accel_bias")->setDouble(0,1); // ahrsCalib->getField("accel_bias")->setDouble(0,1);
// ahrsCalib->getField("accel_bias")->setDouble(0,2); // ahrsCalib->getField("accel_bias")->setDouble(0,2);
@ -409,6 +423,7 @@ void ConfigAHRSWidget::launchGyroDriftCalibration()
*/ */
void ConfigAHRSWidget::driftCalibrationAttitudeRawUpdated(UAVObject* obj) { void ConfigAHRSWidget::driftCalibrationAttitudeRawUpdated(UAVObject* obj) {
Q_UNUSED(obj)
// This is necessary to prevent a race condition on disconnect signal and another update // This is necessary to prevent a race condition on disconnect signal and another update
if (collectingData == true) { if (collectingData == true) {
/** /**
@ -568,8 +583,7 @@ void ConfigAHRSWidget::saveAHRSCalibration()
UAVObjectField *field = obj->getField(QString("measure_var")); UAVObjectField *field = obj->getField(QString("measure_var"));
field->setValue("SET"); field->setValue("SET");
obj->updated(); obj->updated();
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj); saveObjectToSD(obj);
} }
FORCE_ALIGN_FUNC FORCE_ALIGN_FUNC
@ -1136,17 +1150,16 @@ void ConfigAHRSWidget::drawVariancesGraph()
/** /**
Request current settings from the AHRS Request current settings from the AHRS
*/ */
void ConfigAHRSWidget::ahrsSettingsRequest() void ConfigAHRSWidget::refreshValues()
{ {
UAVObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSSettings"))); UAVObject *obj = getObjectManager()->getObject(QString("AHRSSettings"));
obj->requestUpdate();
UAVObjectField *field = obj->getField(QString("Algorithm")); UAVObjectField *field = obj->getField(QString("Algorithm"));
if (field) if (field)
m_ahrs->algorithm->setCurrentIndex(m_ahrs->algorithm->findText(field->getValue().toString())); m_ahrs->algorithm->setCurrentIndex(m_ahrs->algorithm->findText(field->getValue().toString()));
drawVariancesGraph(); drawVariancesGraph();
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("HomeLocation"))); obj = getObjectManager()->getObject(QString("HomeLocation"));
field = obj->getField(QString("Set")); field = obj->getField(QString("Set"));
if (field) if (field)
m_ahrs->homeLocationSet->setEnabled(field->getValue().toBool()); m_ahrs->homeLocationSet->setEnabled(field->getValue().toBool());

View File

@ -55,6 +55,7 @@ public:
private: private:
void drawVariancesGraph(); void drawVariancesGraph();
void displayPlane(QString elementID); void displayPlane(QString elementID);
virtual void enableControls(bool enable);
Ui_AHRSWidget *m_ahrs; Ui_AHRSWidget *m_ahrs;
QGraphicsSvgItem *paperplane; QGraphicsSvgItem *paperplane;
@ -130,7 +131,9 @@ private slots:
void launchAccelBiasCalibration(); void launchAccelBiasCalibration();
void calibPhase2(); void calibPhase2();
void incrementProgress(); void incrementProgress();
void ahrsSettingsRequest();
virtual void refreshValues();
//void ahrsSettingsRequest();
void ahrsSettingsSaveRAM(); void ahrsSettingsSaveRAM();
void ahrsSettingsSaveSD(); void ahrsSettingsSaveSD();
void savePositionData(); void savePositionData();

View File

@ -166,14 +166,12 @@ ConfigAirframeWidget::ConfigAirframeWidget(QWidget *parent) : ConfigTaskWidget(p
connect(m_aircraft->saveAircraftToSD, SIGNAL(clicked()), this, SLOT(saveAircraftUpdate())); connect(m_aircraft->saveAircraftToSD, SIGNAL(clicked()), this, SLOT(saveAircraftUpdate()));
connect(m_aircraft->saveAircraftToRAM, SIGNAL(clicked()), this, SLOT(sendAircraftUpdate())); connect(m_aircraft->saveAircraftToRAM, SIGNAL(clicked()), this, SLOT(sendAircraftUpdate()));
connect(m_aircraft->getAircraftCurrent, SIGNAL(clicked()), this, SLOT(requestAircraftUpdate()));
connect(m_aircraft->ffSave, SIGNAL(clicked()), this, SLOT(saveAircraftUpdate())); connect(m_aircraft->ffSave, SIGNAL(clicked()), this, SLOT(saveAircraftUpdate()));
connect(m_aircraft->ffApply, SIGNAL(clicked()), this, SLOT(sendAircraftUpdate())); connect(m_aircraft->ffApply, SIGNAL(clicked()), this, SLOT(sendAircraftUpdate()));
connect(m_aircraft->ffGetCurrent, SIGNAL(clicked()), this, SLOT(requestAircraftUpdate()));
connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString))); connect(m_aircraft->fixedWingType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString)));
connect(m_aircraft->multirotorFrameType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString))); connect(m_aircraft->multirotorFrameType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString)));
connect(m_aircraft->aircraftType, SIGNAL(currentIndexChanged(int)), this, SLOT(switchAirframeType(int))); connect(m_aircraft->aircraftType, SIGNAL(currentIndexChanged(int)), this, SLOT(switchAirframeType(int)));
requestAircraftUpdate();
connect(m_aircraft->fwThrottleReset, SIGNAL(clicked()), this, SLOT(resetFwMixer())); connect(m_aircraft->fwThrottleReset, SIGNAL(clicked()), this, SLOT(resetFwMixer()));
connect(m_aircraft->mrThrottleCurveReset, SIGNAL(clicked()), this, SLOT(resetMrMixer())); connect(m_aircraft->mrThrottleCurveReset, SIGNAL(clicked()), this, SLOT(resetMrMixer()));
@ -192,10 +190,22 @@ ConfigAirframeWidget::ConfigAirframeWidget(QWidget *parent) : ConfigTaskWidget(p
connect(m_aircraft->ffTestBox2, SIGNAL(clicked(bool)), this, SLOT(enableFFTest())); connect(m_aircraft->ffTestBox2, SIGNAL(clicked(bool)), this, SLOT(enableFFTest()));
connect(m_aircraft->ffTestBox3, SIGNAL(clicked(bool)), this, SLOT(enableFFTest())); connect(m_aircraft->ffTestBox3, SIGNAL(clicked(bool)), this, SLOT(enableFFTest()));
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestAircraftUpdate())); enableControls(false);
refreshValues();
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
connect(parent, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()));
// Register for ManualControlSettings changes:
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings")));
connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
// Connect the help button // Connect the help button
connect(m_aircraft->airframeHelp, SIGNAL(clicked()), this, SLOT(openHelp())); connect(m_aircraft->airframeHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
} }
ConfigAirframeWidget::~ConfigAirframeWidget() ConfigAirframeWidget::~ConfigAirframeWidget()
@ -203,6 +213,18 @@ ConfigAirframeWidget::~ConfigAirframeWidget()
// Do nothing // Do nothing
} }
/**
Enable or disable controls depending on whether we're ronnected or not
*/
void ConfigAirframeWidget::enableControls(bool enable)
{
//m_aircraft->saveAircraftToRAM->setEnabled(enable);
m_aircraft->saveAircraftToSD->setEnabled(enable);
//m_aircraft->ffApply->setEnabled(enable);
m_aircraft->ffSave->setEnabled(enable);
}
/** /**
Slot for switching the airframe type. We do it explicitely Slot for switching the airframe type. We do it explicitely
rather than a signal in the UI, because we want to force a fitInView of the quad shapes. rather than a signal in the UI, because we want to force a fitInView of the quad shapes.
@ -440,14 +462,13 @@ void ConfigAirframeWidget::updateCustomThrottle2CurveValue(QList<double> list, d
* Aircraft settings * Aircraft settings
**************************/ **************************/
/** /**
Request the current value of the SystemSettings which holds the aircraft type Refreshes the current value of the SystemSettings which holds the aircraft type
*/ */
void ConfigAirframeWidget::requestAircraftUpdate() void ConfigAirframeWidget::refreshValues()
{ {
// Get the Airframe type from the system settings: // Get the Airframe type from the system settings:
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings"))); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
obj->requestUpdate();
UAVObjectField *field = obj->getField(QString("AirframeType")); UAVObjectField *field = obj->getField(QString("AirframeType"));
Q_ASSERT(field); Q_ASSERT(field);
// At this stage, we will need to have some hardcoded settings in this code, this // At this stage, we will need to have some hardcoded settings in this code, this
@ -457,7 +478,6 @@ void ConfigAirframeWidget::requestAircraftUpdate()
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings"))); obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
obj->requestUpdate();
field = obj->getField(QString("ThrottleCurve1")); field = obj->getField(QString("ThrottleCurve1"));
Q_ASSERT(field); Q_ASSERT(field);
QList<double> curveValues; QList<double> curveValues;
@ -1524,7 +1544,7 @@ bool ConfigAirframeWidget::setupMixer(double mixerFactors[8][3])
setupQuadMotor(channel, mixerFactors[i][0]*pFactor, setupQuadMotor(channel, mixerFactors[i][0]*pFactor,
rFactor*mixerFactors[i][1], yFactor*mixerFactors[i][2]); rFactor*mixerFactors[i][1], yFactor*mixerFactors[i][2]);
} }
obj->updated(); // obj->updated();
return true; return true;
} }
@ -1568,7 +1588,7 @@ void ConfigAirframeWidget::setupMotors(QList<QString> motorList)
field = obj->getField(motor); field = obj->getField(motor);
field->setValue(mmList.takeFirst()->currentText()); field->setValue(mmList.takeFirst()->currentText());
} }
obj->updated(); // Save... //obj->updated(); // Save...
} }
@ -2026,14 +2046,12 @@ void ConfigAirframeWidget::sendAircraftUpdate()
m_aircraft->mrStatusLabel->setText("Error: Assign a Yaw channel"); m_aircraft->mrStatusLabel->setText("Error: Assign a Yaw channel");
return; return;
} }
motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorS";
setupMotors(motorList);
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings"))); obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
field = obj->getField("FixedWingYaw1"); field = obj->getField("FixedWingYaw1");
field->setValue(m_aircraft->triYawChannel->currentText()); field->setValue(m_aircraft->triYawChannel->currentText());
// No need to send a obj->updated() here because setupMotors
// will do it.
motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorS";
setupMotors(motorList);
// Motor 1 to 6, Y6 Layout: // Motor 1 to 6, Y6 Layout:
// pitch roll yaw // pitch roll yaw
@ -2112,10 +2130,13 @@ void ConfigAirframeWidget::sendAircraftUpdate()
field->setValue(m_aircraft->customMixerTable->item(5,i)->text(),ti); field->setValue(m_aircraft->customMixerTable->item(5,i)->text(),ti);
} }
obj->updated();
} }
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings"))); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
obj->updated();
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
obj->updated();
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings")));
UAVObjectField* field = obj->getField(QString("AirframeType")); UAVObjectField* field = obj->getField(QString("AirframeType"));
field->setValue(airframeType); field->setValue(airframeType);
obj->updated(); obj->updated();

View File

@ -32,6 +32,7 @@
#include "extensionsystem/pluginmanager.h" #include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h" #include "uavobjectmanager.h"
#include "uavobject.h" #include "uavobject.h"
#include "uavtalk/telemetrymanager.h"
#include <QtGui/QWidget> #include <QtGui/QWidget>
#include <QList> #include <QList>
#include <QItemDelegate> #include <QItemDelegate>
@ -57,6 +58,7 @@ private:
void updateCustomAirframeUI(); void updateCustomAirframeUI();
bool setupMixer(double mixerFactors[8][3]); bool setupMixer(double mixerFactors[8][3]);
void setupMotors(QList<QString> motorList); void setupMotors(QList<QString> motorList);
virtual void enableControls(bool enable);
void resetField(UAVObjectField * field); void resetField(UAVObjectField * field);
void resetMixer (MixerCurveWidget *mixer, int numElements); void resetMixer (MixerCurveWidget *mixer, int numElements);
@ -72,7 +74,7 @@ private:
UAVObject::Metadata accInitialData; UAVObject::Metadata accInitialData;
private slots: private slots:
void requestAircraftUpdate(); virtual void refreshValues();
void sendAircraftUpdate(); void sendAircraftUpdate();
void saveAircraftUpdate(); void saveAircraftUpdate();
void setupAirframeUI(QString type); void setupAirframeUI(QString type);

View File

@ -41,14 +41,20 @@ ConfigCCAttitudeWidget::ConfigCCAttitudeWidget(QWidget *parent) :
connect(ui->zeroBias,SIGNAL(clicked()),this,SLOT(startAccelCalibration())); connect(ui->zeroBias,SIGNAL(clicked()),this,SLOT(startAccelCalibration()));
connect(ui->saveButton,SIGNAL(clicked()),this,SLOT(saveAttitudeSettings())); connect(ui->saveButton,SIGNAL(clicked()),this,SLOT(saveAttitudeSettings()));
connect(ui->applyButton,SIGNAL(clicked()),this,SLOT(applyAttitudeSettings())); connect(ui->applyButton,SIGNAL(clicked()),this,SLOT(applyAttitudeSettings()));
connect(ui->getCurrentButton,SIGNAL(clicked()),this,SLOT(getCurrentAttitudeSettings()));
// Make it smart: // Make it smart:
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(getCurrentAttitudeSettings())); connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
getCurrentAttitudeSettings(); // The 1st time this panel is instanciated, the autopilot is already connected. connect(parent, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()));
enableControls(true);
refreshValues(); // The 1st time this panel is instanciated, the autopilot is already connected.
UAVObject * settings = getObjectManager()->getObject(QString("AttitudeSettings"));
connect(settings,SIGNAL(objectUpdated(UAVObject*)), this, SLOT(refreshValues()));
// Connect the help button // Connect the help button
connect(ui->ccAttitudeHelp, SIGNAL(clicked()), this, SLOT(openHelp())); connect(ui->ccAttitudeHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
} }
ConfigCCAttitudeWidget::~ConfigCCAttitudeWidget() ConfigCCAttitudeWidget::~ConfigCCAttitudeWidget()
@ -56,6 +62,12 @@ ConfigCCAttitudeWidget::~ConfigCCAttitudeWidget()
delete ui; delete ui;
} }
void ConfigCCAttitudeWidget::enableControls(bool enable)
{
//ui->applyButton->setEnabled(enable);
ui->saveButton->setEnabled(enable);
}
void ConfigCCAttitudeWidget::attitudeRawUpdated(UAVObject * obj) { void ConfigCCAttitudeWidget::attitudeRawUpdated(UAVObject * obj) {
QMutexLocker locker(&startStop); QMutexLocker locker(&startStop);
@ -126,9 +138,8 @@ void ConfigCCAttitudeWidget::applyAttitudeSettings() {
settings->updated(); settings->updated();
} }
void ConfigCCAttitudeWidget::getCurrentAttitudeSettings() { void ConfigCCAttitudeWidget::refreshValues() {
UAVDataObject * settings = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AttitudeSettings"))); UAVDataObject * settings = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AttitudeSettings")));
settings->requestUpdate();
UAVObjectField * field = settings->getField("BoardRotation"); UAVObjectField * field = settings->getField("BoardRotation");
ui->rollBias->setValue(field->getDouble(0)); ui->rollBias->setValue(field->getDouble(0));
ui->pitchBias->setValue(field->getDouble(1)); ui->pitchBias->setValue(field->getDouble(1));

View File

@ -52,7 +52,7 @@ private slots:
void startAccelCalibration(); void startAccelCalibration();
void saveAttitudeSettings(); void saveAttitudeSettings();
void applyAttitudeSettings(); void applyAttitudeSettings();
void getCurrentAttitudeSettings(); virtual void refreshValues();
void openHelp(); void openHelp();
private: private:
@ -67,6 +67,8 @@ private:
static const int NUM_ACCEL_UPDATES = 60; static const int NUM_ACCEL_UPDATES = 60;
static const float ACCEL_SCALE = 0.004f * 9.81f; static const float ACCEL_SCALE = 0.004f * 9.81f;
virtual void enableControls(bool enable);
}; };
#endif // CCATTITUDEWIDGET_H #endif // CCATTITUDEWIDGET_H

View File

@ -1195,11 +1195,9 @@ void ConfigccpmWidget::saveccpmUpdate()
ShowDisclaimer(0); ShowDisclaimer(0);
// Send update so that the latest value is saved // Send update so that the latest value is saved
sendccpmUpdate(); sendccpmUpdate();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("MixerSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj); saveObjectToSD(obj);
} }
void ConfigccpmWidget::resizeEvent(QResizeEvent* event) void ConfigccpmWidget::resizeEvent(QResizeEvent* event)
@ -1276,7 +1274,7 @@ void ConfigccpmWidget::SwashLvlStartButtonPressed()
// Get the channel assignements: // Get the channel assignements:
obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings"))); obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
obj->requestUpdate(); // obj->requestUpdate();
MinField = obj->getField(QString("ChannelMin")); MinField = obj->getField(QString("ChannelMin"));
NeutralField = obj->getField(QString("ChannelNeutral")); NeutralField = obj->getField(QString("ChannelNeutral"));
MaxField = obj->getField(QString("ChannelMax")); MaxField = obj->getField(QString("ChannelMax"));
@ -1506,8 +1504,7 @@ void ConfigccpmWidget::SwashLvlFinishButtonPressed()
} }
obj->updated(); obj->updated();
saveObjectToSD(obj);
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj);
//restore Flight control of ActuatorCommand //restore Flight control of ActuatorCommand
enableSwashplateLevellingControl(false); enableSwashplateLevellingControl(false);
@ -1536,7 +1533,7 @@ int ConfigccpmWidget::ShowDisclaimer(int messageID)
break; break;
case 1: case 1:
// Not Tested disclaimer // Not Tested disclaimer
msgBox.setInformativeText("<h2>The CCPM mixer code has not been used to fly a helicopter!</h2><p><font color=red>Use it at your own risk!</font><p>Do you wish to continue?"); msgBox.setInformativeText("<h2>The CCPM mixer code needs more testing!</h2><p><font color=red>Use it at your own risk!</font><p>Do you wish to continue?");
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Cancel); msgBox.setDefaultButton(QMessageBox::Cancel);
msgBox.setIcon(QMessageBox::Warning); msgBox.setIcon(QMessageBox::Warning);

View File

@ -85,6 +85,7 @@ private:
int MixerChannelData[6]; int MixerChannelData[6];
int ShowDisclaimer(int messageID); int ShowDisclaimer(int messageID);
virtual void enableControls(bool enable) { Q_UNUSED(enable)}; // Not used by this widget
private slots: private slots:
void ccpmSwashplateUpdate(); void ccpmSwashplateUpdate();
@ -107,10 +108,14 @@ private:
void setSwashplateLevel(int percent); void setSwashplateLevel(int percent);
void SwashLvlSpinBoxChanged(int value); void SwashLvlSpinBoxChanged(int value);
void FocusChanged(QWidget *oldFocus, QWidget *newFocus); void FocusChanged(QWidget *oldFocus, QWidget *newFocus);
virtual void refreshValues() {}; // Not used
public slots: public slots:
void requestccpmUpdate(); void requestccpmUpdate();
void sendccpmUpdate(); void sendccpmUpdate();
void saveccpmUpdate(); void saveccpmUpdate();
protected: protected:
void showEvent(QShowEvent *event); void showEvent(QShowEvent *event);
void resizeEvent(QResizeEvent *event); void resizeEvent(QResizeEvent *event);

View File

@ -90,6 +90,7 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
TelemetryManager* telMngr = pm->getObject<TelemetryManager>(); TelemetryManager* telMngr = pm->getObject<TelemetryManager>();
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect())); connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
// And check whether by any chance we are not already connected // And check whether by any chance we are not already connected
if (telMngr->isConnected()) if (telMngr->isConnected())
@ -111,6 +112,10 @@ void ConfigGadgetWidget::resizeEvent(QResizeEvent *event)
QWidget::resizeEvent(event); QWidget::resizeEvent(event);
} }
void ConfigGadgetWidget::onAutopilotDisconnect() {
emit autopilotDisconnected();
}
void ConfigGadgetWidget::onAutopilotConnect() { void ConfigGadgetWidget::onAutopilotConnect() {
// First of all, check what Board type we are talking to, and // First of all, check what Board type we are talking to, and
@ -135,8 +140,6 @@ void ConfigGadgetWidget::onAutopilotConnect() {
ftw->insertTab(3, qwd, QIcon(":/configgadget/images/AHRS-v1.3.png"), QString("INS")); ftw->insertTab(3, qwd, QIcon(":/configgadget/images/AHRS-v1.3.png"), QString("INS"));
} }
} }
emit autopilotConnected(); emit autopilotConnected();
} }

View File

@ -52,9 +52,11 @@ public:
public slots: public slots:
void onAutopilotConnect(); void onAutopilotConnect();
void onAutopilotDisconnect();
signals: signals:
void autopilotConnected(); void autopilotConnected();
void autopilotDisconnected();
protected: protected:
void resizeEvent(QResizeEvent * event); void resizeEvent(QResizeEvent * event);

View File

@ -38,6 +38,8 @@
#include <QDesktopServices> #include <QDesktopServices>
#include <QUrl> #include <QUrl>
#include "manualcontrolsettings.h"
ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent) ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent)
{ {
m_config = new Ui_InputWidget(); m_config = new Ui_InputWidget();
@ -68,15 +70,6 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent)
<< m_config->ch6Min << m_config->ch6Min
<< m_config->ch7Min; << m_config->ch7Min;
inNeuLabels << m_config->ch0Cur
<< m_config->ch1Cur
<< m_config->ch2Cur
<< m_config->ch3Cur
<< m_config->ch4Cur
<< m_config->ch5Cur
<< m_config->ch6Cur
<< m_config->ch7Cur;
inSliders << m_config->inSlider0 inSliders << m_config->inSlider0
<< m_config->inSlider1 << m_config->inSlider1
<< m_config->inSlider2 << m_config->inSlider2
@ -95,12 +88,24 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent)
<< m_config->ch6Rev << m_config->ch6Rev
<< m_config->ch7Rev; << m_config->ch7Rev;
inChannelAssign << m_config->ch0Assign
<< m_config->ch1Assign
<< m_config->ch2Assign
<< m_config->ch3Assign
<< m_config->ch4Assign
<< m_config->ch5Assign
<< m_config->ch6Assign
<< m_config->ch7Assign;
// Now connect the widget to the ManualControlCommand / Channel UAVObject // Now connect the widget to the ManualControlCommand / Channel UAVObject
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlCommand"))); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlCommand")));
connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateChannels(UAVObject*))); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(updateChannels(UAVObject*)));
// Register for ManualControlSettings changes:
obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings")));
connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
// Get the receiver types supported by OpenPilot and fill the corresponding // Get the receiver types supported by OpenPilot and fill the corresponding
// dropdown menu: // dropdown menu:
obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings"))); obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings")));
@ -151,22 +156,14 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent)
m_config->armControl->clear(); m_config->armControl->clear();
m_config->armControl->addItems(field->getOptions()); m_config->armControl->addItems(field->getOptions());
requestRCInputUpdate();
connect(m_config->saveRCInputToSD, SIGNAL(clicked()), this, SLOT(saveRCInputObject())); connect(m_config->saveRCInputToSD, SIGNAL(clicked()), this, SLOT(saveRCInputObject()));
connect(m_config->saveRCInputToRAM, SIGNAL(clicked()), this, SLOT(sendRCInputUpdate())); connect(m_config->saveRCInputToRAM, SIGNAL(clicked()), this, SLOT(sendRCInputUpdate()));
connect(m_config->getRCInputCurrent, SIGNAL(clicked()), this, SLOT(requestRCInputUpdate()));
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestRCInputUpdate())); enableControls(false);
refreshValues();
connect(m_config->inSlider0, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged0(int))); connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
connect(m_config->inSlider1, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged1(int))); connect(parent, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()));
connect(m_config->inSlider2, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged2(int)));
connect(m_config->inSlider3, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged3(int)));
connect(m_config->inSlider4, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged4(int)));
connect(m_config->inSlider5, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged5(int)));
connect(m_config->inSlider6, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged6(int)));
connect(m_config->inSlider7, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged7(int)));
connect(m_config->ch0Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool))); connect(m_config->ch0Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool)));
connect(m_config->ch1Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool))); connect(m_config->ch1Rev, SIGNAL(toggled(bool)), this, SLOT(reverseCheckboxClicked(bool)));
@ -179,19 +176,6 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent)
firstUpdate = true; firstUpdate = true;
enableControls(false);
// Listen to telemetry connection events
if (pm) {
TelemetryManager *tm = pm->getObject<TelemetryManager>();
if (tm) {
connect(tm, SIGNAL(myStart()), this, SLOT(onTelemetryStart()));
connect(tm, SIGNAL(myStop()), this, SLOT(onTelemetryStop()));
connect(tm, SIGNAL(connected()), this, SLOT(onTelemetryConnect()));
connect(tm, SIGNAL(disconnected()), this, SLOT(onTelemetryDisconnect()));
}
}
// Connect the help button // Connect the help button
connect(m_config->inputHelp, SIGNAL(clicked()), this, SLOT(openHelp())); connect(m_config->inputHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
} }
@ -219,89 +203,19 @@ void ConfigInputWidget::reverseCheckboxClicked(bool state)
} }
} }
// ************************************
// slider value changed signals
void ConfigInputWidget::onInSliderValueChanged0(int value)
{
inNeuLabels[0]->setText(QString::number(value));
}
void ConfigInputWidget::onInSliderValueChanged1(int value)
{
inNeuLabels[1]->setText(QString::number(value));
}
void ConfigInputWidget::onInSliderValueChanged2(int value)
{
inNeuLabels[2]->setText(QString::number(value));
}
void ConfigInputWidget::onInSliderValueChanged3(int value)
{
inNeuLabels[3]->setText(QString::number(value));
}
void ConfigInputWidget::onInSliderValueChanged4(int value)
{
inNeuLabels[4]->setText(QString::number(value));
}
void ConfigInputWidget::onInSliderValueChanged5(int value)
{
inNeuLabels[5]->setText(QString::number(value));
}
void ConfigInputWidget::onInSliderValueChanged6(int value)
{
inNeuLabels[6]->setText(QString::number(value));
}
void ConfigInputWidget::onInSliderValueChanged7(int value)
{
inNeuLabels[7]->setText(QString::number(value));
}
// ************************************
// telemetry start/stop connect/disconnect signals
void ConfigInputWidget::onTelemetryStart()
{
}
void ConfigInputWidget::onTelemetryStop()
{
}
void ConfigInputWidget::onTelemetryConnect()
{
enableControls(true);
}
void ConfigInputWidget::onTelemetryDisconnect()
{
enableControls(false);
m_config->doRCInputCalibration->setChecked(false);
}
// ************************************ // ************************************
/*
Enable or disable some controls depending on whether we are connected
or not to the board. Actually, this i mostly useless IMHO, I don't
know who added this into the code (Ed's note)
*/
void ConfigInputWidget::enableControls(bool enable) void ConfigInputWidget::enableControls(bool enable)
{ {
m_config->getRCInputCurrent->setEnabled(enable); //m_config->saveRCInputToRAM->setEnabled(enable);
m_config->saveRCInputToRAM->setEnabled(enable);
m_config->saveRCInputToSD->setEnabled(enable); m_config->saveRCInputToSD->setEnabled(enable);
m_config->doRCInputCalibration->setEnabled(enable); m_config->doRCInputCalibration->setEnabled(enable);
m_config->ch0Assign->setEnabled(enable);
m_config->ch1Assign->setEnabled(enable);
m_config->ch2Assign->setEnabled(enable);
m_config->ch3Assign->setEnabled(enable);
m_config->ch4Assign->setEnabled(enable);
m_config->ch5Assign->setEnabled(enable);
m_config->ch6Assign->setEnabled(enable);
m_config->ch7Assign->setEnabled(enable);
} }
@ -312,11 +226,11 @@ void ConfigInputWidget::enableControls(bool enable)
/** /**
Request the current config from the board Request the current config from the board
*/ */
void ConfigInputWidget::requestRCInputUpdate() void ConfigInputWidget::refreshValues()
{ {
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ManualControlSettings"))); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ManualControlSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
obj->requestUpdate(); //obj->requestUpdate();
UAVObjectField *field; UAVObjectField *field;
// Now update all the slider values: // Now update all the slider values:
@ -350,14 +264,9 @@ void ConfigInputWidget::requestRCInputUpdate()
m_config->receiverType->setCurrentIndex(m_config->receiverType->findText(field->getValue().toString())); m_config->receiverType->setCurrentIndex(m_config->receiverType->findText(field->getValue().toString()));
// Reset all channel assignement dropdowns: // Reset all channel assignement dropdowns:
m_config->ch0Assign->setCurrentIndex(0); foreach (QComboBox *combo, inChannelAssign) {
m_config->ch1Assign->setCurrentIndex(0); combo->setCurrentIndex(0);
m_config->ch2Assign->setCurrentIndex(0); }
m_config->ch3Assign->setCurrentIndex(0);
m_config->ch4Assign->setCurrentIndex(0);
m_config->ch5Assign->setCurrentIndex(0);
m_config->ch6Assign->setCurrentIndex(0);
m_config->ch7Assign->setCurrentIndex(0);
// Update all channels assignements // Update all channels assignements
QList<UAVObjectField *> fieldList = obj->getFields(); QList<UAVObjectField *> fieldList = obj->getFields();
@ -508,11 +417,9 @@ void ConfigInputWidget::saveRCInputObject()
{ {
// Send update so that the latest value is saved // Send update so that the latest value is saved
sendRCInputUpdate(); sendRCInputUpdate();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ManualControlSettings")));
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj); saveObjectToSD(obj);
} }
@ -582,11 +489,14 @@ void ConfigInputWidget::updateChannels(UAVObject* controlCommand)
mdata.flightAccess = UAVObject::ACCESS_READONLY; mdata.flightAccess = UAVObject::ACCESS_READONLY;
obj->setMetadata(mdata); obj->setMetadata(mdata);
UAVObjectField *field = obj->getField("Channel"); UAVObjectField *field = obj->getField("Channel");
for (int i=0; i< field->getNumElements(); i++) { for (uint i=0; i< field->getNumElements(); i++) {
field->setValue(0,i); field->setValue(0,i);
} }
obj->updated(); obj->updated();
// Last, make sure the user won't apply/save during calibration
m_config->saveRCInputToRAM->setEnabled(false);
m_config->saveRCInputToSD->setEnabled(false);
} }
field = controlCommand->getField(QString("Channel")); field = controlCommand->getField(QString("Channel"));
@ -606,20 +516,58 @@ void ConfigInputWidget::updateChannels(UAVObject* controlCommand)
mdata = obj->getMetadata(); mdata = obj->getMetadata();
mdata.flightAccess = UAVObject::ACCESS_READWRITE; mdata.flightAccess = UAVObject::ACCESS_READWRITE;
obj->setMetadata(mdata); obj->setMetadata(mdata);
// Set some slider values to better defaults
// Find what channel we used for throttle, set it 5% about min:
int throttleChannel = -1;
int fmChannel = -1;
for (int i=0; i < inChannelAssign.length(); i++) {
if (inChannelAssign.at(i)->currentText() == "Throttle") {
// TODO: this is very ugly, because this relies on the name of the
// channel input, everywhere else in the gadget we don't rely on the
// naming...
throttleChannel = i;
}
if (inChannelAssign.at(i)->currentText() == "FlightMode") {
// TODO: this is very ugly, because this relies on the name of the
// channel input, everywhere else in the gadget we don't rely on the
// naming...
fmChannel = i;
}
}
// Throttle neutral defaults to 2% of range
if (throttleChannel > -1) {
inSliders.at(throttleChannel)->setValue(
inSliders.at(throttleChannel)->minimum() +
(inSliders.at(throttleChannel)->maximum()-
inSliders.at(throttleChannel)->minimum())*0.02);
}
// Flight mode at 50% of range:
if (fmChannel > -1) {
inSliders.at(fmChannel)->setValue(
inSliders.at(fmChannel)->minimum()+
(inSliders.at(fmChannel)->maximum()-
inSliders.at(fmChannel)->minimum())*0.5);
}
m_config->saveRCInputToRAM->setEnabled(true);
m_config->saveRCInputToSD->setEnabled(true);
} }
firstUpdate = true; firstUpdate = true;
} }
//Update the Flight mode channel slider //Update the Flight mode channel slider
UAVObject* obj = getObjectManager()->getObject("ManualControlSettings"); ManualControlSettings * manualSettings = ManualControlSettings::GetInstance(getObjectManager());
// Find the channel currently assigned to flightmode ManualControlSettings::DataFields manualSettingsData = manualSettings->getData();
field = obj->getField("FlightMode"); uint chIndex = manualSettingsData.FlightMode;
int chIndex = field->getOptions().indexOf(field->getValue().toString()); if (chIndex < manualSettings->FLIGHTMODE_NONE) {
if (chIndex < field->getOptions().length() - 1) {
float valueScaled; float valueScaled;
int chMin = inSliders[chIndex]->minimum(); int chMin = manualSettingsData.ChannelMin[chIndex];
int chMax = inSliders[chIndex]->maximum(); int chMax = manualSettingsData.ChannelMax[chIndex];
int chNeutral = inSliders[chIndex]->value(); int chNeutral = manualSettingsData.ChannelNeutral[chIndex];
int value = controlCommand->getField("Channel")->getValue(chIndex).toInt(); int value = controlCommand->getField("Channel")->getValue(chIndex).toInt();
if ((chMax > chMin && value >= chNeutral) || (chMin > chMax && value <= chNeutral)) if ((chMax > chMin && value >= chNeutral) || (chMin > chMax && value <= chNeutral))
@ -637,12 +585,13 @@ void ConfigInputWidget::updateChannels(UAVObject* controlCommand)
valueScaled = 0; valueScaled = 0;
} }
// Bound if(valueScaled < -(1.0 / 3.0))
if (valueScaled > 1.0) valueScaled = 1.0; m_config->fmsSlider->setValue(-100);
else if (valueScaled > (1.0/3.0))
m_config->fmsSlider->setValue(100);
else else
if (valueScaled < -1.0) valueScaled = -1.0; m_config->fmsSlider->setValue(0);
m_config->fmsSlider->setValue(valueScaled * 100);
} }
} }

View File

@ -46,19 +46,6 @@ public:
~ConfigInputWidget(); ~ConfigInputWidget();
public slots: public slots:
void onTelemetryStart();
void onTelemetryStop();
void onTelemetryConnect();
void onTelemetryDisconnect();
void onInSliderValueChanged0(int value);
void onInSliderValueChanged1(int value);
void onInSliderValueChanged2(int value);
void onInSliderValueChanged3(int value);
void onInSliderValueChanged4(int value);
void onInSliderValueChanged5(int value);
void onInSliderValueChanged6(int value);
void onInSliderValueChanged7(int value);
private: private:
Ui_InputWidget *m_config; Ui_InputWidget *m_config;
@ -79,14 +66,15 @@ private:
QList<QLabel*> inMinLabels; QList<QLabel*> inMinLabels;
QList<QLabel*> inNeuLabels; QList<QLabel*> inNeuLabels;
QList<QCheckBox*> inRevCheckboxes; QList<QCheckBox*> inRevCheckboxes;
QList<QComboBox*> inChannelAssign;
bool firstUpdate; bool firstUpdate;
void enableControls(bool enable); virtual void enableControls(bool enable);
private slots: private slots:
void updateChannels(UAVObject* obj); void updateChannels(UAVObject* obj);
void requestRCInputUpdate(); virtual void refreshValues();
void sendRCInputUpdate(); void sendRCInputUpdate();
void saveRCInputObject(); void saveRCInputObject();
void reverseCheckboxClicked(bool state); void reverseCheckboxClicked(bool state);

View File

@ -107,8 +107,7 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
// Register for ActuatorSettings changes: // Register for ActuatorSettings changes:
UAVDataObject * obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings"))); UAVDataObject * obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings")));
connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(requestRCOutputUpdate())); connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
connect(outMin[i], SIGNAL(editingFinished()), this, SLOT(setChOutRange())); connect(outMin[i], SIGNAL(editingFinished()), this, SLOT(setChOutRange()));
@ -125,36 +124,18 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
for (int i = 0; i < links.count(); i++) for (int i = 0; i < links.count(); i++)
connect(links[i], SIGNAL(toggled(bool)), this, SLOT(linkToggled(bool))); connect(links[i], SIGNAL(toggled(bool)), this, SLOT(linkToggled(bool)));
requestRCOutputUpdate();
connect(m_config->saveRCOutputToSD, SIGNAL(clicked()), this, SLOT(saveRCOutputObject())); connect(m_config->saveRCOutputToSD, SIGNAL(clicked()), this, SLOT(saveRCOutputObject()));
connect(m_config->saveRCOutputToRAM, SIGNAL(clicked()), this, SLOT(sendRCOutputUpdate())); connect(m_config->saveRCOutputToRAM, SIGNAL(clicked()), this, SLOT(sendRCOutputUpdate()));
// Actually, this is not really needed since we are subscribing to the object updates already enableControls(false);
// TODO: remove those buttons on all config gadget panels. refreshValues();
connect(m_config->getRCOutputCurrent, SIGNAL(clicked()), this, SLOT(requestRCOutputUpdate())); connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
connect(parent, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()));
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestRCOutputUpdate()));
firstUpdate = true; firstUpdate = true;
connect(m_config->spinningArmed, SIGNAL(toggled(bool)), this, SLOT(setSpinningArmed(bool))); connect(m_config->spinningArmed, SIGNAL(toggled(bool)), this, SLOT(setSpinningArmed(bool)));
enableControls(false);
// Listen to telemetry connection events
if (pm)
{
TelemetryManager *tm = pm->getObject<TelemetryManager>();
if (tm)
{
connect(tm, SIGNAL(myStart()), this, SLOT(onTelemetryStart()));
connect(tm, SIGNAL(myStop()), this, SLOT(onTelemetryStop()));
connect(tm, SIGNAL(connected()), this, SLOT(onTelemetryConnect()));
connect(tm, SIGNAL(disconnected()), this, SLOT(onTelemetryDisconnect()));
}
}
// Connect the help button // Connect the help button
connect(m_config->outputHelp, SIGNAL(clicked()), this, SLOT(openHelp())); connect(m_config->outputHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
} }
@ -165,35 +146,12 @@ ConfigOutputWidget::~ConfigOutputWidget()
} }
// ************************************
// telemetry start/stop connect/disconnect signals
void ConfigOutputWidget::onTelemetryStart()
{
}
void ConfigOutputWidget::onTelemetryStop()
{
}
void ConfigOutputWidget::onTelemetryConnect()
{
enableControls(true);
}
void ConfigOutputWidget::onTelemetryDisconnect()
{
enableControls(false);
}
// ************************************ // ************************************
void ConfigOutputWidget::enableControls(bool enable) void ConfigOutputWidget::enableControls(bool enable)
{ {
m_config->saveRCOutputToSD->setEnabled(enable); m_config->saveRCOutputToSD->setEnabled(enable);
m_config->saveRCOutputToRAM->setEnabled(enable); //m_config->saveRCOutputToRAM->setEnabled(enable);
m_config->getRCOutputCurrent->setEnabled(enable);
} }
// ************************************ // ************************************
@ -203,6 +161,7 @@ void ConfigOutputWidget::enableControls(bool enable)
*/ */
void ConfigOutputWidget::linkToggled(bool state) void ConfigOutputWidget::linkToggled(bool state)
{ {
Q_UNUSED(state)
// find the minimum slider value for the linked ones // find the minimum slider value for the linked ones
int min = 10000; int min = 10000;
int linked_count = 0; int linked_count = 0;
@ -237,7 +196,7 @@ void ConfigOutputWidget::runChannelTests(bool state)
// Confirm this is definitely what they want // Confirm this is definitely what they want
if(state) { if(state) {
QMessageBox mbox; QMessageBox mbox;
mbox.setText(QString(tr("This option will requires you to be in the armed state and will start your motors by the amount selected on the sliders. It is recommended to remove any blades from motors. Are you sure you want to do this?"))); mbox.setText(QString(tr("This option will start your motors by the amount selected on the sliders regardless of transmitter. It is recommended to remove any blades from motors. Are you sure you want to do this?")));
mbox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); mbox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
int retval = mbox.exec(); int retval = mbox.exec();
if(retval != QMessageBox::Yes) { if(retval != QMessageBox::Yes) {
@ -396,7 +355,7 @@ void ConfigOutputWidget::sendChannelTest(int value)
/** /**
Request the current config from the board (RC Output) Request the current config from the board (RC Output)
*/ */
void ConfigOutputWidget::requestRCOutputUpdate() void ConfigOutputWidget::refreshValues()
{ {
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
@ -534,11 +493,9 @@ void ConfigOutputWidget::saveRCOutputObject()
{ {
// Send update so that the latest value is saved // Send update so that the latest value is saved
sendRCOutputUpdate(); sendRCOutputUpdate();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj); saveObjectToSD(obj);
} }
@ -547,8 +504,8 @@ void ConfigOutputWidget::saveRCOutputObject()
Sets the minimum/maximum value of the channel 0 to seven output sliders. Sets the minimum/maximum value of the channel 0 to seven output sliders.
Have to do it here because setMinimum is not a slot. Have to do it here because setMinimum is not a slot.
One added trick: if the slider is at either its max or its min when the value One added trick: if the slider is at its min when the value
is changed, then keep it on the max/min. is changed, then keep it on the min.
*/ */
void ConfigOutputWidget::setChOutRange() void ConfigOutputWidget::setChOutRange()
{ {
@ -561,7 +518,7 @@ void ConfigOutputWidget::setChOutRange()
QSlider *slider = outSliders[index]; QSlider *slider = outSliders[index];
int oldMini = slider->minimum(); int oldMini = slider->minimum();
int oldMaxi = slider->maximum(); // int oldMaxi = slider->maximum();
if (outMin[index]->value()<outMax[index]->value()) if (outMin[index]->value()<outMax[index]->value())
{ {

View File

@ -46,12 +46,6 @@ public:
ConfigOutputWidget(QWidget *parent = 0); ConfigOutputWidget(QWidget *parent = 0);
~ConfigOutputWidget(); ~ConfigOutputWidget();
public slots:
void onTelemetryStart();
void onTelemetryStop();
void onTelemetryConnect();
void onTelemetryDisconnect();
private: private:
Ui_OutputWidget *m_config; Ui_OutputWidget *m_config;
@ -75,10 +69,10 @@ private:
bool firstUpdate; bool firstUpdate;
void enableControls(bool enable); virtual void enableControls(bool enable);
private slots: private slots:
void requestRCOutputUpdate(); virtual void refreshValues();
void sendRCOutputUpdate(); void sendRCOutputUpdate();
void saveRCOutputObject(); void saveRCOutputObject();
void runChannelTests(bool state); void runChannelTests(bool state);

View File

@ -42,15 +42,18 @@ ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTa
m_stabilization = new Ui_StabilizationWidget(); m_stabilization = new Ui_StabilizationWidget();
m_stabilization->setupUi(this); m_stabilization->setupUi(this);
// Now connect the widget to the ManualControlCommand / Channel UAVObject
//UAVObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("StabilizationSettings")));
requestStabilizationUpdate();
connect(m_stabilization->saveStabilizationToSD, SIGNAL(clicked()), this, SLOT(saveStabilizationUpdate())); connect(m_stabilization->saveStabilizationToSD, SIGNAL(clicked()), this, SLOT(saveStabilizationUpdate()));
connect(m_stabilization->saveStabilizationToRAM, SIGNAL(clicked()), this, SLOT(sendStabilizationUpdate())); connect(m_stabilization->saveStabilizationToRAM, SIGNAL(clicked()), this, SLOT(sendStabilizationUpdate()));
connect(m_stabilization->getStabilizationCurrent, SIGNAL(clicked()), this, SLOT(requestStabilizationUpdate()));
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestStabilizationUpdate())); enableControls(false);
refreshValues();
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
connect(parent, SIGNAL(autopilotDisconnected()),this, SLOT(onAutopilotDisconnect()));
// Now connect the widget to the StabilizationSettings object
UAVObject *obj = getObjectManager()->getObject(QString("StabilizationSettings"));
connect(obj,SIGNAL(objectUpdated(UAVObject*)),this,SLOT(refreshValues()));
// Create a timer to regularly send the object update in case // Create a timer to regularly send the object update in case
// we want realtime updates. // we want realtime updates.
@ -84,6 +87,12 @@ ConfigStabilizationWidget::~ConfigStabilizationWidget()
} }
void ConfigStabilizationWidget::enableControls(bool enable)
{
//m_stabilization->saveStabilizationToRAM->setEnabled(enable);
m_stabilization->saveStabilizationToSD->setEnabled(enable);
}
void ConfigStabilizationWidget::updateRateRollKP(double val) void ConfigStabilizationWidget::updateRateRollKP(double val)
{ {
if (m_stabilization->linkRateRP->isChecked()) { if (m_stabilization->linkRateRP->isChecked()) {
@ -178,9 +187,11 @@ void ConfigStabilizationWidget::updatePitchILimit(double val)
/** /**
Request stabilization settings from the board Request stabilization settings from the board
*/ */
void ConfigStabilizationWidget::requestStabilizationUpdate() void ConfigStabilizationWidget::refreshValues()
{ {
stabSettings->requestUpdate(); // Not needed anymore as this slot is only called whenever we get
// a signal that the object was just updated
// stabSettings->requestUpdate();
StabilizationSettings::DataFields stabData = stabSettings->getData(); StabilizationSettings::DataFields stabData = stabSettings->getData();
// Now fill in all the fields, this is fairly tedious: // Now fill in all the fields, this is fairly tedious:
m_stabilization->rateRollKp->setValue(stabData.RollRatePI[StabilizationSettings::ROLLRATEPI_KP]); m_stabilization->rateRollKp->setValue(stabData.RollRatePI[StabilizationSettings::ROLLRATEPI_KP]);
@ -262,20 +273,19 @@ void ConfigStabilizationWidget::saveStabilizationUpdate()
{ {
// Send update so that the latest value is saved // Send update so that the latest value is saved
sendStabilizationUpdate(); sendStabilizationUpdate();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("StabilizationSettings")));
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("StabilizationSettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj); saveObjectToSD(obj);
} }
void ConfigStabilizationWidget::realtimeUpdateToggle(bool state) void ConfigStabilizationWidget::realtimeUpdateToggle(bool state)
{ {
if (state) if (state) {
updateTimer.start(300); updateTimer.start(300);
else } else {
updateTimer.stop(); updateTimer.stop();
}
} }
void ConfigStabilizationWidget::openHelp() void ConfigStabilizationWidget::openHelp()

View File

@ -49,9 +49,10 @@ private:
Ui_StabilizationWidget *m_stabilization; Ui_StabilizationWidget *m_stabilization;
StabilizationSettings* stabSettings; StabilizationSettings* stabSettings;
QTimer updateTimer; QTimer updateTimer;
virtual void enableControls(bool enable);
private slots: private slots:
void requestStabilizationUpdate(); virtual void refreshValues();
void sendStabilizationUpdate(); void sendStabilizationUpdate();
void saveStabilizationUpdate(); void saveStabilizationUpdate();
void realtimeUpdateToggle(bool); void realtimeUpdateToggle(bool);

View File

@ -30,8 +30,6 @@
ConfigTaskWidget::ConfigTaskWidget(QWidget *parent) : QWidget(parent) ConfigTaskWidget::ConfigTaskWidget(QWidget *parent) : QWidget(parent)
{ {
saveState = IDLE;
queue.clear();
} }
ConfigTaskWidget::~ConfigTaskWidget() ConfigTaskWidget::~ConfigTaskWidget()
@ -41,100 +39,13 @@ ConfigTaskWidget::~ConfigTaskWidget()
void ConfigTaskWidget::saveObjectToSD(UAVObject *obj) void ConfigTaskWidget::saveObjectToSD(UAVObject *obj)
{ {
// Add to queue // saveObjectToSD is now handled by the UAVUtils plugin in one
queue.enqueue(obj); // central place (and one central queue)
// If queue length is one, then start sending (call sendNextObject) ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
// Otherwise, do nothing, it's sending anyway UAVObjectUtilManager* utilMngr = pm->getObject<UAVObjectUtilManager>();
if (queue.length()==1) utilMngr->saveObjectToSD(obj);
saveNextObject();
} }
void ConfigTaskWidget::saveNextObject()
{
if ( queue.isEmpty() )
{
return;
}
Q_ASSERT(saveState == IDLE);
// Get next object from the queue
UAVObject* obj = queue.head();
ObjectPersistence* objper = dynamic_cast<ObjectPersistence*>( getObjectManager()->getObject(ObjectPersistence::NAME) );
connect(objper, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectPersistenceTransactionCompleted(UAVObject*,bool)));
connect(objper, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(objectPersistenceUpdated(UAVObject *)));
saveState = AWAITING_ACK;
if (obj != NULL)
{
ObjectPersistence::DataFields data;
data.Operation = ObjectPersistence::OPERATION_SAVE;
data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT;
data.ObjectID = obj->getObjID();
data.InstanceID = obj->getInstID();
objper->setData(data);
objper->updated();
}
}
/**
* @brief Process the transactionCompleted message from Telemetry indicating request sent successfully
* @param[in] The object just transsacted. Must be ObjectPersistance
* @param[in] success Indicates that the transaction did not time out
*
* After a failed transaction (usually timeout) resends the save request. After a succesful
* transaction will then wait for a save completed update from the autopilot.
*/
void ConfigTaskWidget::objectPersistenceTransactionCompleted(UAVObject* obj, bool success)
{
if(success) {
Q_ASSERT(obj->getName().compare("ObjectPersistence") == 0);
Q_ASSERT(saveState == AWAITING_ACK);
saveState = AWAITING_COMPLETED;
disconnect(obj, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectPersistenceTransactionCompleted(UAVObject*,bool)));
} else if (!success) {
// Can be caused by timeout errors on sending. Send again.
saveNextObject();
}
}
/**
* @brief Process the ObjectPersistence updated message to confirm the right object saved
* then requests next object be saved.
* @param[in] The object just received. Must be ObjectPersistance
*/
void ConfigTaskWidget::objectPersistenceUpdated(UAVObject * obj)
{
Q_ASSERT(obj->getName().compare("ObjectPersistence") == 0);
if(saveState == AWAITING_COMPLETED) {
// Check flight is saying it completed. This is the only thing flight should do to trigger an update.
Q_ASSERT( obj->getField("Operation")->getValue().toString().compare(QString("Completed")) == 0 );
// Check right object saved
UAVObject* savingObj = queue.head();
Q_ASSERT( obj->getField("ObjectID")->getValue() == savingObj->getObjID() );
obj->disconnect(this);
queue.dequeue(); // We can now remove the object, it's done.
saveState = IDLE;
saveNextObject();
}
}
void ConfigTaskWidget::updateObjectPersistance(ObjectPersistence::OperationOptions op, UAVObject *obj)
{
ObjectPersistence* objper = dynamic_cast<ObjectPersistence*>( getObjectManager()->getObject(ObjectPersistence::NAME) );
if (obj != NULL)
{
ObjectPersistence::DataFields data;
data.Operation = op;
data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT;
data.ObjectID = obj->getObjID();
data.InstanceID = obj->getInstID();
objper->setData(data);
objper->updated();
}
}
UAVObjectManager* ConfigTaskWidget::getObjectManager() { UAVObjectManager* ConfigTaskWidget::getObjectManager() {
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
@ -151,6 +62,21 @@ double ConfigTaskWidget::listMean(QList<double> list)
return accum / list.size(); return accum / list.size();
} }
// ************************************
// telemetry start/stop connect/disconnect signals
void ConfigTaskWidget::onAutopilotDisconnect()
{
enableControls(false);
}
void ConfigTaskWidget::onAutopilotConnect()
{
enableControls(true);
refreshValues();
}
/** /**
@} @}

View File

@ -31,7 +31,7 @@
#include "extensionsystem/pluginmanager.h" #include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h" #include "uavobjectmanager.h"
#include "uavobject.h" #include "uavobject.h"
#include "objectpersistence.h" #include "uavobjectutilmanager.h"
#include <QQueue> #include <QQueue>
#include <QtGui/QWidget> #include <QtGui/QWidget>
#include <QList> #include <QList>
@ -45,20 +45,18 @@ public:
ConfigTaskWidget(QWidget *parent = 0); ConfigTaskWidget(QWidget *parent = 0);
~ConfigTaskWidget(); ~ConfigTaskWidget();
void saveObjectToSD(UAVObject *obj); void saveObjectToSD(UAVObject *obj);
void updateObjectPersistance(ObjectPersistence::OperationOptions op, UAVObject *obj);
UAVObjectManager* getObjectManager(); UAVObjectManager* getObjectManager();
static double listMean(QList<double> list); static double listMean(QList<double> list);
public slots:
void onAutopilotDisconnect();
void onAutopilotConnect();
private slots: private slots:
void objectPersistenceTransactionCompleted(UAVObject* obj, bool success); virtual void refreshValues() = 0;
void objectPersistenceUpdated(UAVObject * obj);
private: private:
QQueue<UAVObject*> queue; virtual void enableControls(bool enable) = 0;
void saveNextObject();
enum {IDLE, AWAITING_ACK, AWAITING_COMPLETED} saveState;
}; };

View File

@ -43,16 +43,18 @@ ConfigTelemetryWidget::ConfigTelemetryWidget(QWidget *parent) : ConfigTaskWidget
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVObject *obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("TelemetrySettings"))); UAVObject *obj = objManager->getObject(QString("TelemetrySettings"));
UAVObjectField *field = obj->getField(QString("Speed")); UAVObjectField *field = obj->getField(QString("Speed"));
m_telemetry->telemetrySpeed->addItems(field->getOptions()); m_telemetry->telemetrySpeed->addItems(field->getOptions());
requestTelemetryUpdate();
connect(m_telemetry->saveTelemetryToSD, SIGNAL(clicked()), this, SLOT(saveTelemetryUpdate())); connect(m_telemetry->saveTelemetryToSD, SIGNAL(clicked()), this, SLOT(saveTelemetryUpdate()));
connect(m_telemetry->saveTelemetryToRAM, SIGNAL(clicked()), this, SLOT(sendTelemetryUpdate())); connect(m_telemetry->saveTelemetryToRAM, SIGNAL(clicked()), this, SLOT(sendTelemetryUpdate()));
connect(m_telemetry->getTelemetryCurrent, SIGNAL(clicked()), this, SLOT(requestTelemetryUpdate())); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(refreshValues()));
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestTelemetryUpdate())); enableControls(false);
refreshValues();
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
connect(parent, SIGNAL(autopilotDisconnected()),this, SLOT(onAutopilotDisconnect()));
} }
ConfigTelemetryWidget::~ConfigTelemetryWidget() ConfigTelemetryWidget::~ConfigTelemetryWidget()
@ -65,16 +67,21 @@ ConfigTelemetryWidget::~ConfigTelemetryWidget()
* Telemetry Settings * Telemetry Settings
*****************************/ *****************************/
void ConfigTelemetryWidget::enableControls(bool enable)
{
m_telemetry->saveTelemetryToSD->setEnabled(enable);
//m_telemetry->saveTelemetryToRAM->setEnabled(enable);
}
/** /**
Request telemetry settings from the board Request telemetry settings from the board
*/ */
void ConfigTelemetryWidget::requestTelemetryUpdate() void ConfigTelemetryWidget::refreshValues()
{ {
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>(); UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("TelemetrySettings"))); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("TelemetrySettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
obj->requestUpdate();
UAVObjectField *field = obj->getField(QString("Speed")); UAVObjectField *field = obj->getField(QString("Speed"));
m_telemetry->telemetrySpeed->setCurrentIndex(m_telemetry->telemetrySpeed->findText(field->getValue().toString())); m_telemetry->telemetrySpeed->setCurrentIndex(m_telemetry->telemetrySpeed->findText(field->getValue().toString()));
} }
@ -84,9 +91,7 @@ void ConfigTelemetryWidget::requestTelemetryUpdate()
*/ */
void ConfigTelemetryWidget::sendTelemetryUpdate() void ConfigTelemetryWidget::sendTelemetryUpdate()
{ {
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("TelemetrySettings")));
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("TelemetrySettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
UAVObjectField* field = obj->getField(QString("Speed")); UAVObjectField* field = obj->getField(QString("Speed"));
field->setValue(m_telemetry->telemetrySpeed->currentText()); field->setValue(m_telemetry->telemetrySpeed->currentText());
@ -100,11 +105,7 @@ void ConfigTelemetryWidget::saveTelemetryUpdate()
{ {
// Send update so that the latest value is saved // Send update so that the latest value is saved
sendTelemetryUpdate(); sendTelemetryUpdate();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("TelemetrySettings")));
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("TelemetrySettings")));
Q_ASSERT(obj); Q_ASSERT(obj);
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj); saveObjectToSD(obj);
} }

View File

@ -46,9 +46,10 @@ public:
private: private:
Ui_TelemetryWidget *m_telemetry; Ui_TelemetryWidget *m_telemetry;
void enableControls(bool enable);
private slots: private slots:
void requestTelemetryUpdate(); virtual void refreshValues();
void sendTelemetryUpdate(); void sendTelemetryUpdate();
void saveTelemetryUpdate(); void saveTelemetryUpdate();

View File

@ -31,7 +31,7 @@
#include <QDebug> #include <QDebug>
DefaultAttitudeWidget::DefaultAttitudeWidget(QWidget *parent) : DefaultAttitudeWidget::DefaultAttitudeWidget(QWidget *parent) :
ConfigTaskWidget(parent), QWidget(parent),
ui(new Ui_defaultattitude) ui(new Ui_defaultattitude)
{ {
ui->setupUi(this); ui->setupUi(this);

View File

@ -38,7 +38,7 @@
class Ui_Widget; class Ui_Widget;
class DefaultAttitudeWidget : public ConfigTaskWidget class DefaultAttitudeWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>557</width> <width>557</width>
<height>462</height> <height>467</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -52,7 +52,7 @@ p, li { white-space: pre-wrap; }
&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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>1000</string> <string>1500</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -160,7 +160,7 @@ p, li { white-space: pre-wrap; }
&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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>1000</string> <string>1500</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -268,7 +268,7 @@ p, li { white-space: pre-wrap; }
&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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>1000</string> <string>1500</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -376,7 +376,7 @@ p, li { white-space: pre-wrap; }
&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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>1000</string> <string>1500</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -484,7 +484,7 @@ p, li { white-space: pre-wrap; }
&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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>1000</string> <string>1500</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -592,7 +592,7 @@ p, li { white-space: pre-wrap; }
&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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>1000</string> <string>1500</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -700,7 +700,7 @@ p, li { white-space: pre-wrap; }
&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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>1000</string> <string>1500</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -912,7 +912,7 @@ p, li { white-space: pre-wrap; }
&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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &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:9pt;&quot;&gt;Current channel value.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>1000</string> <string>1500</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -1406,16 +1406,6 @@ if you have not done so already.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="getRCInputCurrent">
<property name="toolTip">
<string>Retrieve settings from OpenPilot</string>
</property>
<property name="text">
<string>Get Current</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="saveRCInputToRAM"> <widget class="QPushButton" name="saveRCInputToRAM">
<property name="toolTip"> <property name="toolTip">
@ -1470,5 +1460,134 @@ Applies and Saves all settings to SD</string>
<resources> <resources>
<include location="../coreplugin/core.qrc"/> <include location="../coreplugin/core.qrc"/>
</resources> </resources>
<connections/> <connections>
<connection>
<sender>inSlider0</sender>
<signal>valueChanged(int)</signal>
<receiver>ch0Cur</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>291</x>
<y>93</y>
</hint>
<hint type="destinationlabel">
<x>150</x>
<y>104</y>
</hint>
</hints>
</connection>
<connection>
<sender>inSlider1</sender>
<signal>valueChanged(int)</signal>
<receiver>ch1Cur</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>283</x>
<y>137</y>
</hint>
<hint type="destinationlabel">
<x>160</x>
<y>138</y>
</hint>
</hints>
</connection>
<connection>
<sender>inSlider2</sender>
<signal>valueChanged(int)</signal>
<receiver>ch2Cur</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>341</x>
<y>163</y>
</hint>
<hint type="destinationlabel">
<x>156</x>
<y>167</y>
</hint>
</hints>
</connection>
<connection>
<sender>inSlider3</sender>
<signal>valueChanged(int)</signal>
<receiver>ch3Cur</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>283</x>
<y>211</y>
</hint>
<hint type="destinationlabel">
<x>159</x>
<y>210</y>
</hint>
</hints>
</connection>
<connection>
<sender>inSlider4</sender>
<signal>valueChanged(int)</signal>
<receiver>ch4Cur</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>287</x>
<y>239</y>
</hint>
<hint type="destinationlabel">
<x>156</x>
<y>242</y>
</hint>
</hints>
</connection>
<connection>
<sender>inSlider5</sender>
<signal>valueChanged(int)</signal>
<receiver>ch5Cur</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>309</x>
<y>272</y>
</hint>
<hint type="destinationlabel">
<x>164</x>
<y>276</y>
</hint>
</hints>
</connection>
<connection>
<sender>inSlider6</sender>
<signal>valueChanged(int)</signal>
<receiver>ch6Cur</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>282</x>
<y>300</y>
</hint>
<hint type="destinationlabel">
<x>144</x>
<y>311</y>
</hint>
</hints>
</connection>
<connection>
<sender>inSlider7</sender>
<signal>valueChanged(int)</signal>
<receiver>ch7Cur</receiver>
<slot>setNum(int)</slot>
<hints>
<hint type="sourcelabel">
<x>278</x>
<y>339</y>
</hint>
<hint type="destinationlabel">
<x>168</x>
<y>340</y>
</hint>
</hints>
</connection>
</connections>
</ui> </ui>

View File

@ -1143,16 +1143,6 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="getRCOutputCurrent">
<property name="toolTip">
<string>Retrieve settings from OpenPilot</string>
</property>
<property name="text">
<string>Get Current</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="saveRCOutputToRAM"> <widget class="QPushButton" name="saveRCOutputToRAM">
<property name="toolTip"> <property name="toolTip">
@ -1225,7 +1215,6 @@ Applies and Saves all settings to SD</string>
<tabstop>ch7Rev</tabstop> <tabstop>ch7Rev</tabstop>
<tabstop>ch7Link</tabstop> <tabstop>ch7Link</tabstop>
<tabstop>channelOutTest</tabstop> <tabstop>channelOutTest</tabstop>
<tabstop>getRCOutputCurrent</tabstop>
<tabstop>saveRCOutputToRAM</tabstop> <tabstop>saveRCOutputToRAM</tabstop>
<tabstop>saveRCOutputToSD</tabstop> <tabstop>saveRCOutputToSD</tabstop>
</tabstops> </tabstops>

View File

@ -638,13 +638,6 @@ automatically every 300ms, which will help for fast tuning.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="getStabilizationCurrent">
<property name="text">
<string>Get Current</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="saveStabilizationToRAM"> <widget class="QPushButton" name="saveStabilizationToRAM">
<property name="text"> <property name="text">

View File

@ -22,15 +22,9 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTextBrowser" name="textBrowser"> <widget class="QTextBrowser" name="textBrowser">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>361</width>
<height>151</height>
</rect>
</property>
<property name="html"> <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; <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; &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;
@ -41,15 +35,11 @@ p, li { white-space: pre-wrap; }
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;Beware of not locking yourself out! You should only modify this setting when the OpenPilot board is connected through the USB port.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;Beware of not locking yourself out! You should only modify this setting when the OpenPilot board is connected through the USB port.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>70</x>
<y>200</y>
<width>131</width>
<height>17</height>
</rect>
</property>
<property name="font"> <property name="font">
<font> <font>
<pointsize>11</pointsize> <pointsize>11</pointsize>
@ -61,28 +51,46 @@ p, li { white-space: pre-wrap; }
<string>Telemetry speed:</string> <string>Telemetry speed:</string>
</property> </property>
</widget> </widget>
</item>
<item>
<widget class="QComboBox" name="telemetrySpeed"> <widget class="QComboBox" name="telemetrySpeed">
<property name="geometry">
<rect>
<x>200</x>
<y>190</y>
<width>141</width>
<height>31</height>
</rect>
</property>
<property name="toolTip"> <property name="toolTip">
<string>Select the speed here.</string> <string>Select the speed here.</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="saveTelemetryToRAM"> </item>
<property name="geometry"> </layout>
<rect> </item>
<x>190</x> <item>
<y>280</y> <spacer name="verticalSpacer">
<width>93</width> <property name="orientation">
<height>27</height> <enum>Qt::Vertical</enum>
</rect>
</property> </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>
<item>
<widget class="QPushButton" name="saveTelemetryToRAM">
<property name="toolTip"> <property name="toolTip">
<string>Send to OpenPilot but don't write in SD. <string>Send to OpenPilot but don't write in SD.
Beware of not locking yourself out!</string> Beware of not locking yourself out!</string>
@ -91,31 +99,9 @@ Beware of not locking yourself out!</string>
<string>Apply</string> <string>Apply</string>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="getTelemetryCurrent"> </item>
<property name="geometry"> <item>
<rect>
<x>80</x>
<y>280</y>
<width>93</width>
<height>27</height>
</rect>
</property>
<property name="toolTip">
<string>Retrieve settings from OpenPilot</string>
</property>
<property name="text">
<string>Get Current</string>
</property>
</widget>
<widget class="QPushButton" name="saveTelemetryToSD"> <widget class="QPushButton" name="saveTelemetryToSD">
<property name="geometry">
<rect>
<x>300</x>
<y>280</y>
<width>93</width>
<height>27</height>
</rect>
</property>
<property name="toolTip"> <property name="toolTip">
<string>Applies and Saves all settings to SD. <string>Applies and Saves all settings to SD.
Beware of not locking yourself out!</string> Beware of not locking yourself out!</string>
@ -124,6 +110,10 @@ Beware of not locking yourself out!</string>
<string>Save</string> <string>Save</string>
</property> </property>
</widget> </widget>
</item>
</layout>
</item>
</layout>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -219,6 +219,7 @@ void ConnectionManager::aboutToRemoveObject(QObject *obj)
void ConnectionManager::onConnectionDestroyed(QObject *obj) // Pip void ConnectionManager::onConnectionDestroyed(QObject *obj) // Pip
{ {
Q_UNUSED(obj)
//onConnectionClosed(obj); //onConnectionClosed(obj);
disconnectDevice(); disconnectDevice();
} }

View File

@ -183,6 +183,7 @@ void CoreImpl::updateContext()
void CoreImpl::openFiles(const QStringList &arguments) void CoreImpl::openFiles(const QStringList &arguments)
{ {
Q_UNUSED(arguments)
//m_mainwindow->openFiles(arguments); //m_mainwindow->openFiles(arguments);
} }

View File

@ -290,14 +290,12 @@ void MainWindow::extensionsInitialized()
if ( ! qs->allKeys().count() ){ if ( ! qs->allKeys().count() ){
QMessageBox msgBox; QMessageBox msgBox;
msgBox.setText(tr("No configuration file could be found.")); msgBox.setText(tr("No configuration file could be found."));
msgBox.setInformativeText(tr("Do you want to load the default configuration?")); msgBox.setInformativeText(tr("The default configuration will be loaded."));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Yes); msgBox.exec();
if ( msgBox.exec() == QMessageBox::Yes ){
qDebug() << "Load default config from resource /core/OpenPilotGCS.xml"; qDebug() << "Load default config from resource /core/OpenPilotGCS.xml";
qs = &defaultSettings; qs = &defaultSettings;
} }
}
m_uavGadgetInstanceManager = new UAVGadgetInstanceManager(this); m_uavGadgetInstanceManager = new UAVGadgetInstanceManager(this);
m_uavGadgetInstanceManager->readSettings(qs); m_uavGadgetInstanceManager->readSettings(qs);

View File

@ -177,8 +177,8 @@ private:
QList<int> m_additionalContexts; QList<int> m_additionalContexts;
QSettings *m_settings; QSettings *m_settings;
QSettings *m_globalSettings; QSettings *m_globalSettings;
bool m_dontSaveSettings; // In case of an Error or if we reset the settings, never save them.
SettingsDatabase *m_settingsDatabase; SettingsDatabase *m_settingsDatabase;
bool m_dontSaveSettings; // In case of an Error or if we reset the settings, never save them.
ActionManagerPrivate *m_actionManager; ActionManagerPrivate *m_actionManager;
MessageManager *m_messageManager; MessageManager *m_messageManager;
VariableManager *m_variableManager; VariableManager *m_variableManager;

View File

@ -7,18 +7,9 @@ include(importexport_dependencies.pri)
HEADERS += importexportplugin.h \ HEADERS += importexportplugin.h \
importexportgadgetwidget.h \ importexportgadgetwidget.h \
importexportdialog.h importexportdialog.h
HEADERS += importexportgadget.h
HEADERS += importexportgadgetfactory.h
HEADERS += importexportgadgetconfiguration.h
HEADERS += importexportgadgetoptionspage.h
SOURCES += importexportplugin.cpp \ SOURCES += importexportplugin.cpp \
importexportgadgetwidget.cpp \ importexportgadgetwidget.cpp \
importexportdialog.cpp importexportdialog.cpp
SOURCES += importexportgadget.cpp
SOURCES += importexportgadgetfactory.cpp
SOURCES += importexportgadgetconfiguration.cpp
SOURCES += importexportgadgetoptionspage.cpp
OTHER_FILES += ImportExportGadget.pluginspec OTHER_FILES += ImportExportGadget.pluginspec
FORMS += importexportgadgetoptionspage.ui \ FORMS += importexportgadgetwidget.ui \
importexportgadgetwidget.ui \
importexportdialog.ui importexportdialog.ui

View File

@ -1,12 +1,11 @@
#include "importexportdialog.h" #include "importexportdialog.h"
#include "ui_importexportdialog.h" #include "ui_importexportdialog.h"
ImportExportDialog::ImportExportDialog( ImportExportGadgetConfiguration *config, QWidget *parent) : ImportExportDialog::ImportExportDialog(QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::ImportExportDialog) ui(new Ui::ImportExportDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
ui->widget->loadConfiguration(config);
setWindowTitle(tr("Import Export Settings")); setWindowTitle(tr("Import Export Settings"));
connect( ui->widget, SIGNAL(done()), this, SLOT(close())); connect( ui->widget, SIGNAL(done()), this, SLOT(close()));

View File

@ -27,7 +27,6 @@
#define IMPORTEXPORTDIALOG_H #define IMPORTEXPORTDIALOG_H
#include <QDialog> #include <QDialog>
#include "importexportgadgetconfiguration.h"
namespace Ui { namespace Ui {
class ImportExportDialog; class ImportExportDialog;
@ -38,7 +37,7 @@ class ImportExportDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit ImportExportDialog( ImportExportGadgetConfiguration *config, QWidget *parent = 0); explicit ImportExportDialog(QWidget *parent = 0);
~ImportExportDialog(); ~ImportExportDialog();
protected: protected:

View File

@ -23,7 +23,7 @@
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="standardButtons"> <property name="standardButtons">
<set>QDialogButtonBox::Cancel</set> <set>QDialogButtonBox::Close</set>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -1,76 +0,0 @@
/**
******************************************************************************
*
* @file importexportgadgetconfiguration.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3
* @brief Configuration for Import/Export Plugin
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup importexportplugin
* @{
*
*****************************************************************************/
/*
* 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 "importexportgadgetconfiguration.h"
static const QString VERSION = "1.0.1";
/**
* Loads a saved configuration or defaults if non exist.
*
*/
ImportExportGadgetConfiguration::ImportExportGadgetConfiguration(QString classId, QSettings* qSettings, UAVConfigInfo *configInfo, QObject *parent) :
IUAVGadgetConfiguration(classId, parent)
{
if ( ! qSettings )
return;
if ( configInfo->version() == UAVConfigVersion() )
configInfo->setVersion("1.0.0");
if ( !configInfo->standardVersionHandlingOK(VERSION))
return;
iniFile = qSettings->value("iniFile", "gcs.xml").toString();
}
/**
* Clones a configuration.
*
*/
IUAVGadgetConfiguration *ImportExportGadgetConfiguration::clone()
{
ImportExportGadgetConfiguration *m = new ImportExportGadgetConfiguration(this->classId());
m->iniFile = iniFile;
return m;
}
/**
* Saves a configuration.
*
*/
void ImportExportGadgetConfiguration::saveConfig(QSettings* qSettings, Core::UAVConfigInfo *configInfo) const {
configInfo->setVersion(VERSION);
qSettings->setValue("iniFile", iniFile);
}
/**
* @}
* @}
*/

View File

@ -1,65 +0,0 @@
/**
******************************************************************************
* @file
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup importexportplugin
* @{
*****************************************************************************/
/*
* 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 IMPORTEXPORTGADGETCONFIGURATION_H
#define IMPORTEXPORTGADGETCONFIGURATION_H
#include <coreplugin/iuavgadgetconfiguration.h>
#include "importexport_global.h"
using namespace Core;
/* This is a generic bargraph dial
supporting one indicator.
*/
class IMPORTEXPORT_EXPORT ImportExportGadgetConfiguration : public IUAVGadgetConfiguration
{
Q_OBJECT
public:
ImportExportGadgetConfiguration(QString classId, QSettings* qSettings = 0, UAVConfigInfo *configInfo = 0, QObject *parent = 0);
//set dial configuration functions
void setIniFile(QString filename) {
iniFile = filename;
}
//get dial configuration functions
QString getIniFile() const{
return iniFile;
}
void saveConfig(QSettings* settings, Core::UAVConfigInfo *configInfo) const;
IUAVGadgetConfiguration *clone();
private:
QString iniFile;
};
#endif // IMPORTEXPORTGADGETCONFIGURATION_H
/**
* @}
* @}
*/

View File

@ -1,67 +0,0 @@
/**
******************************************************************************
*
* @file importexportgadgetfactory.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3
* @brief Factory for Import/Export Plugin
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup importexportplugin
* @{
*
*****************************************************************************/
/*
* 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 "importexportgadgetfactory.h"
#include "importexportgadgetwidget.h"
#include "importexportgadget.h"
#include "importexportgadgetconfiguration.h"
#include "importexportgadgetoptionspage.h"
#include <coreplugin/iuavgadget.h>
ImportExportGadgetFactory::ImportExportGadgetFactory(QObject *parent) :
IUAVGadgetFactory(QString("ImportExportGadget"),
tr("Import/Export GCS Config"),
parent)
{
}
ImportExportGadgetFactory::~ImportExportGadgetFactory()
{
}
Core::IUAVGadget* ImportExportGadgetFactory::createGadget(QWidget *parent)
{
ImportExportGadgetWidget* gadgetWidget = new ImportExportGadgetWidget(parent);
return new ImportExportGadget(QString("ImportExportGadget"), gadgetWidget, parent);
}
IUAVGadgetConfiguration *ImportExportGadgetFactory::createConfiguration(QSettings* qSettings, UAVConfigInfo *configInfo)
{
lastConfig = new ImportExportGadgetConfiguration(QString("ImportExportGadget"), qSettings, configInfo);
return lastConfig;
}
IOptionsPage *ImportExportGadgetFactory::createOptionsPage(IUAVGadgetConfiguration *config)
{
return new ImportExportGadgetOptionsPage(qobject_cast<ImportExportGadgetConfiguration*>(config));
}
/**
* @}
* @}
*/

View File

@ -1,61 +0,0 @@
/**
******************************************************************************
* @file
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup importexportplugin
* @{
*****************************************************************************/
/*
* 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 IMPORTEXPORTGADGETFACTORY_H_
#define IMPORTEXPORTGADGETFACTORY_H_
#include <coreplugin/iuavgadgetfactory.h>
#include "importexportgadgetconfiguration.h"
namespace Core
{
class IUAVGadget;
class IUAVGadgetFactory;
}
using namespace Core;
class IMPORTEXPORT_EXPORT ImportExportGadgetFactory : public IUAVGadgetFactory
{
Q_OBJECT
public:
ImportExportGadgetFactory(QObject *parent = 0);
~ImportExportGadgetFactory();
ImportExportGadgetConfiguration *getLastConfig(){ return lastConfig;}
Core::IUAVGadget *createGadget(QWidget *parent);
IUAVGadgetConfiguration *createConfiguration(QSettings *qSettings, UAVConfigInfo *configInfo);
IOptionsPage *createOptionsPage(IUAVGadgetConfiguration *config);
private:
ImportExportGadgetConfiguration *lastConfig;
};
#endif // IMPORTEXPORTGADGETFACTORY_H_
/**
* @}
* @}
*/

View File

@ -1,81 +0,0 @@
/**
******************************************************************************
*
* @file importexportgadgetoptionspage.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3
* @brief Option page for Import/Export Plugin
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup importexportplugin
* @{
*
*****************************************************************************/
/*
* 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 "importexportgadgetoptionspage.h"
#include "importexportgadgetconfiguration.h"
#include "ui_importexportgadgetoptionspage.h"
#include <QFileDialog>
#include <QtDebug>
ImportExportGadgetOptionsPage::ImportExportGadgetOptionsPage(ImportExportGadgetConfiguration *config, QObject *parent) :
IOptionsPage(parent),
m_config(config)
{
}
//creates options page widget (uses the UI file)
QWidget *ImportExportGadgetOptionsPage::createPage(QWidget *parent)
{
options_page = new Ui::ImportExportGadgetOptionsPage();
//main widget
QWidget *optionsPageWidget = new QWidget;
//main layout
options_page->setupUi(optionsPageWidget);
// Restore the contents from the settings:
options_page->iniFile->setExpectedKind(Utils::PathChooser::File);
options_page->iniFile->setPromptDialogFilter(tr("INI file (*.ini);; XML file (*.xml)"));
options_page->iniFile->setPromptDialogTitle(tr("Choose configuration file"));
options_page->iniFile->setPath(m_config->getIniFile());
return optionsPageWidget;
}
/**
* Called when the user presses apply or OK.
*
* Saves the current values
*
*/
void ImportExportGadgetOptionsPage::apply()
{
m_config->setIniFile(options_page->iniFile->path());
}
void ImportExportGadgetOptionsPage::finish()
{
}
/**
* @}
* @}
*/

View File

@ -1,74 +0,0 @@
/**
******************************************************************************
* @file
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup importexportplugin
* @{
*****************************************************************************/
/*
* 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 IMPORTEXPORTGADGETOPTIONSPAGE_H
#define IMPORTEXPORTGADGETOPTIONSPAGE_H
#include "importexport_global.h"
#include "coreplugin/dialogs/ioptionspage.h"
#include <QString>
#include <QFont>
#include <QStringList>
#include <QDebug>
namespace Core
{
class IUAVGadgetConfiguration;
}
class ImportExportGadgetConfiguration;
namespace Ui
{
class ImportExportGadgetOptionsPage;
}
using namespace Core;
class IMPORTEXPORT_EXPORT ImportExportGadgetOptionsPage : public IOptionsPage
{
Q_OBJECT
public:
explicit ImportExportGadgetOptionsPage(ImportExportGadgetConfiguration *config, QObject *parent = 0);
QWidget *createPage(QWidget *parent);
void apply();
void finish();
private:
Ui::ImportExportGadgetOptionsPage *options_page;
ImportExportGadgetConfiguration *m_config;
QFont font;
private slots:
};
#endif // IMPORTEXPORTGADGETOPTIONSPAGE_H
/**
* @}
* @}
*/

View File

@ -1,103 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ImportExportGadgetOptionsPage</class>
<widget class="QWidget" name="ImportExportGadgetOptionsPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>486</width>
<height>300</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>-1</x>
<y>-1</y>
<width>485</width>
<height>339</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
<property name="spacing">
<number>10</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<property name="bottomMargin">
<number>10</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Default Config File </string>
</property>
</widget>
</item>
<item>
<widget class="Utils::PathChooser" name="iniFile" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>Utils::PathChooser</class>
<extends>QWidget</extends>
<header>utils/pathchooser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -48,10 +48,9 @@ ImportExportGadgetWidget::ImportExportGadgetWidget(QWidget *parent) :
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
ui->setupUi(this); ui->setupUi(this);
ui->configFile->setExpectedKind(Utils::PathChooser::File); ui->configFile->setExpectedKind(Utils::PathChooser::File);
ui->configFile->setPromptDialogFilter(tr("INI file (*.ini);; XML file (*.xml)")); ui->configFile->setPromptDialogFilter(tr("XML file (*.xml)"));
ui->configFile->setPromptDialogTitle(tr("Choose configuration file")); ui->configFile->setPromptDialogTitle(tr("Choose configuration file"));
} }
ImportExportGadgetWidget::~ImportExportGadgetWidget() ImportExportGadgetWidget::~ImportExportGadgetWidget()
@ -70,17 +69,22 @@ void ImportExportGadgetWidget::changeEvent(QEvent *e)
break; break;
} }
} }
void ImportExportGadgetWidget::loadConfiguration(const ImportExportGadgetConfiguration* config)
{
if ( !config )
return;
ui->configFile->setPath(config->getIniFile());
}
void ImportExportGadgetWidget::on_exportButton_clicked() void ImportExportGadgetWidget::on_exportButton_clicked()
{ {
QString file = ui->configFile->path(); QString file = ui->configFile->path();
if (file.isEmpty()) {
QMessageBox msgBox;
msgBox.setText(tr("Empty File name."));
msgBox.setInformativeText(tr("Please choose an export file name."));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.exec();
return;
}
// Add a "XML" extension to the file in case it does not exist:
if (!file.endsWith(".xml"))
file.append(".xml");
qDebug() << "Export pressed! Write to file " << QFileInfo(file).absoluteFilePath(); qDebug() << "Export pressed! Write to file " << QFileInfo(file).absoluteFilePath();
if ( QFileInfo(file).exists() ){ if ( QFileInfo(file).exists() ){
@ -133,18 +137,7 @@ void ImportExportGadgetWidget::exportConfiguration(const QString& fileName)
bool doAllGadgets = ui->checkBoxAllGadgets->isChecked(); bool doAllGadgets = ui->checkBoxAllGadgets->isChecked();
bool doPlugins = ui->checkBoxPlugins->isChecked(); bool doPlugins = ui->checkBoxPlugins->isChecked();
QSettings::Format format; QSettings::Format format = XmlConfig::XmlSettingsFormat;
if ( ui->radioButtonIniFormat->isChecked() ){
format = QSettings::IniFormat;
}
else if ( ui->radioButtonXmlFormat->isChecked() ){
format = XmlConfig::XmlSettingsFormat;
}
else {
qWarning() << "Program Error in ImportExportGadgetWidget::exportConfiguration: unknown format. Assume XML!";
format = XmlConfig::XmlSettingsFormat;
}
QSettings qs(fileName, format); QSettings qs(fileName, format);
if (doGeneral) { if (doGeneral) {
@ -193,19 +186,7 @@ void ImportExportGadgetWidget::importConfiguration(const QString& fileName)
bool doAllGadgets = ui->checkBoxAllGadgets->isChecked(); bool doAllGadgets = ui->checkBoxAllGadgets->isChecked();
bool doPlugins = ui->checkBoxPlugins->isChecked(); bool doPlugins = ui->checkBoxPlugins->isChecked();
QSettings::Format format; QSettings qs(fileName, XmlConfig::XmlSettingsFormat);
if ( ui->radioButtonIniFormat->isChecked() ){
format = QSettings::IniFormat;
}
else if ( ui->radioButtonXmlFormat->isChecked() ){
format = XmlConfig::XmlSettingsFormat;
}
else {
qWarning() << "Program Error in ImportExportGadgetWidget::exportConfiguration: unknown format. Assume XML!";
format = XmlConfig::XmlSettingsFormat;
}
QSettings qs(fileName, format);
if ( doAllGadgets ) { if ( doAllGadgets ) {
Core::ICore::instance()->uavGadgetInstanceManager()->readSettings(&qs); Core::ICore::instance()->uavGadgetInstanceManager()->readSettings(&qs);

View File

@ -13,8 +13,8 @@
#include <QWidget> #include <QWidget>
#include <QString> #include <QString>
#include "importexport_global.h"
#include <coreplugin/iconfigurableplugin.h> #include <coreplugin/iconfigurableplugin.h>
#include "importexportgadgetconfiguration.h"
namespace Ui namespace Ui
{ {
@ -28,8 +28,6 @@ public:
ImportExportGadgetWidget(QWidget *parent = 0); ImportExportGadgetWidget(QWidget *parent = 0);
~ImportExportGadgetWidget(); ~ImportExportGadgetWidget();
void loadConfiguration(const ImportExportGadgetConfiguration* config);
signals: signals:
void done(); void done();

View File

@ -82,8 +82,50 @@
</item> </item>
<item row="2" column="0" colspan="2"> <item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="helpButton">
<property name="maximumSize">
<size>
<width>32</width>
<height>32</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>32</width>
<height>32</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="exportButton"> <widget class="QPushButton" name="exportButton">
<property name="toolTip">
<string>Export the GCS settings selected in the checkboxes above.</string>
</property>
<property name="text"> <property name="text">
<string>Export</string> <string>Export</string>
</property> </property>
@ -91,6 +133,9 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="importButton"> <widget class="QPushButton" name="importButton">
<property name="toolTip">
<string>Import settings from the config file, only for the items checked above.</string>
</property>
<property name="text"> <property name="text">
<string>Import</string> <string>Import</string>
</property> </property>
@ -98,46 +143,16 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="resetButton"> <widget class="QPushButton" name="resetButton">
<property name="toolTip">
<string>Resets your GCS configuration to its default configuration.</string>
</property>
<property name="text"> <property name="text">
<string>Reset Config</string> <string>Reset Config</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="helpButton">
<property name="text">
<string>Help</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item row="1" column="1">
<widget class="QGroupBox" name="groupBoxFormat">
<property name="title">
<string>Format</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QRadioButton" name="radioButtonXmlFormat">
<property name="text">
<string>XML Format</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonIniFormat">
<property name="text">
<string>INI Format</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>
@ -148,6 +163,8 @@
<container>1</container> <container>1</container>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources/> <resources>
<include location="../coreplugin/core.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>

View File

@ -4,7 +4,7 @@
* @file importexportplugin.cpp * @file importexportplugin.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3 * @see The GNU Public License (GPL) Version 3
* @brief Import/Export Plugin * @brief Import/Export Plugin for GCS Settings
* @addtogroup GCSPlugins GCS Plugins * @addtogroup GCSPlugins GCS Plugins
* @{ * @{
* @defgroup importexportplugin * @defgroup importexportplugin
@ -28,7 +28,6 @@
*/ */
#include "importexportplugin.h" #include "importexportplugin.h"
#include "importexportgadgetfactory.h"
#include "importexportdialog.h" #include "importexportdialog.h"
#include <QDebug> #include <QDebug>
#include <QtPlugin> #include <QtPlugin>
@ -55,8 +54,6 @@ bool ImportExportPlugin::initialize(const QStringList& args, QString *errMsg)
{ {
Q_UNUSED(args); Q_UNUSED(args);
Q_UNUSED(errMsg); Q_UNUSED(errMsg);
mf = new ImportExportGadgetFactory(this);
addAutoReleasedObject(mf);
// Add Menu entry // Add Menu entry
Core::ActionManager* am = Core::ICore::instance()->actionManager(); Core::ActionManager* am = Core::ICore::instance()->actionManager();
@ -66,7 +63,7 @@ bool ImportExportPlugin::initialize(const QStringList& args, QString *errMsg)
"ImportExportPlugin.ImportExport", "ImportExportPlugin.ImportExport",
QList<int>() << QList<int>() <<
Core::Constants::C_GLOBAL_ID); Core::Constants::C_GLOBAL_ID);
cmd->setDefaultKeySequence(QKeySequence("Ctrl+I")); cmd->setDefaultKeySequence(QKeySequence("Ctrl+S"));
cmd->action()->setText(tr("GCS Settings Import/Export...")); cmd->action()->setText(tr("GCS Settings Import/Export..."));
// ac->menu()->addSeparator(); // ac->menu()->addSeparator();
@ -82,7 +79,7 @@ bool ImportExportPlugin::initialize(const QStringList& args, QString *errMsg)
void ImportExportPlugin::importExport() void ImportExportPlugin::importExport()
{ {
ImportExportDialog(mf->getLastConfig()).exec(); ImportExportDialog().exec();
} }
void ImportExportPlugin::extensionsInitialized() void ImportExportPlugin::extensionsInitialized()

View File

@ -30,8 +30,6 @@
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
#include "importexport_global.h" #include "importexport_global.h"
class ImportExportGadgetFactory;
class IMPORTEXPORT_EXPORT ImportExportPlugin : public ExtensionSystem::IPlugin class IMPORTEXPORT_EXPORT ImportExportPlugin : public ExtensionSystem::IPlugin
{ {
Q_OBJECT Q_OBJECT
@ -44,7 +42,6 @@ public:
bool initialize(const QStringList & arguments, QString * errorString); bool initialize(const QStringList & arguments, QString * errorString);
void shutdown(); void shutdown();
private: private:
ImportExportGadgetFactory *mf;
private slots: private slots:
void importExport(); void importExport();

View File

@ -41,6 +41,11 @@
UAVObjectUtilManager::UAVObjectUtilManager() UAVObjectUtilManager::UAVObjectUtilManager()
{ {
mutex = new QMutex(QMutex::Recursive); mutex = new QMutex(QMutex::Recursive);
saveState = IDLE;
failureTimer.stop();
failureTimer.setSingleShot(true);
failureTimer.setInterval(1000);
connect(&failureTimer, SIGNAL(timeout()),this,SLOT(objectPersistenceOperationFailed()));
} }
UAVObjectUtilManager::~UAVObjectUtilManager() UAVObjectUtilManager::~UAVObjectUtilManager()
@ -58,41 +63,56 @@ UAVObjectUtilManager::~UAVObjectUtilManager()
} }
} }
UAVObjectManager* UAVObjectUtilManager::getObjectManager() {
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager * objMngr = pm->getObject<UAVObjectManager>();
Q_ASSERT(objMngr);
return objMngr;
}
// ****************************** // ******************************
// SD card saving // SD card saving
//
/*
Add a new object to save in the queue
*/
void UAVObjectUtilManager::saveObjectToSD(UAVObject *obj) void UAVObjectUtilManager::saveObjectToSD(UAVObject *obj)
{ {
QMutexLocker locker(mutex);
if (!obj) return;
// Add to queue // Add to queue
queue.enqueue(obj); queue.enqueue(obj);
qDebug() << "Enqueue object: " << obj->getName();
// If queue length is one, then start sending (call sendNextObject) // If queue length is one, then start sending (call sendNextObject)
// Otherwise, do nothing, it's sending anyway // Otherwise, do nothing, it's sending anyway
if (queue.length() <= 1) if (queue.length()==1)
saveNextObject(); saveNextObject();
} }
void UAVObjectUtilManager::saveNextObject() void UAVObjectUtilManager::saveNextObject()
{ {
if (queue.isEmpty()) return; if ( queue.isEmpty() )
{
return;
}
Q_ASSERT(saveState == IDLE);
// Get next object from the queue // Get next object from the queue
UAVObject *obj = queue.head(); UAVObject* obj = queue.head();
if (!obj) return; qDebug() << "Request board to save object " << obj->getName();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
if (!pm) return;
UAVObjectManager *om = pm->getObject<UAVObjectManager>();
if (!om) return;
ObjectPersistence *objper = dynamic_cast<ObjectPersistence *>(om->getObject(ObjectPersistence::NAME));
connect(objper, SIGNAL(transactionCompleted(UAVObject *, bool)), this, SLOT(transactionCompleted(UAVObject *, bool)));
ObjectPersistence* objper = dynamic_cast<ObjectPersistence*>( getObjectManager()->getObject(ObjectPersistence::NAME) );
connect(objper, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectPersistenceTransactionCompleted(UAVObject*,bool)));
connect(objper, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(objectPersistenceUpdated(UAVObject *)));
saveState = AWAITING_ACK;
if (obj != NULL)
{
ObjectPersistence::DataFields data; ObjectPersistence::DataFields data;
data.Operation = ObjectPersistence::OPERATION_SAVE; data.Operation = ObjectPersistence::OPERATION_SAVE;
data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT; data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT;
@ -100,22 +120,97 @@ void UAVObjectUtilManager::saveNextObject()
data.InstanceID = obj->getInstID(); data.InstanceID = obj->getInstID();
objper->setData(data); objper->setData(data);
objper->updated(); objper->updated();
}
// Now: we are going to get two "objectUpdated" messages (one coming from GCS, one coming from Flight, which
// will confirm the object was properly received by both sides) and then one "transactionCompleted" indicating
// that the Flight side did not only receive the object but it did receive it without error. Last we will get
// a last "objectUpdated" message coming from flight side, where we'll get the results of the objectPersistence
// operation we asked for (saved, other).
} }
void UAVObjectUtilManager::transactionCompleted(UAVObject *obj, bool success) /**
* @brief Process the transactionCompleted message from Telemetry indicating request sent successfully
* @param[in] The object just transsacted. Must be ObjectPersistance
* @param[in] success Indicates that the transaction did not time out
*
* After a failed transaction (usually timeout) resends the save request. After a succesful
* transaction will then wait for a save completed update from the autopilot.
*/
void UAVObjectUtilManager::objectPersistenceTransactionCompleted(UAVObject* obj, bool success)
{ {
Q_UNUSED(success); if(success) {
Q_ASSERT(obj->getName().compare("ObjectPersistence") == 0);
Q_ASSERT(saveState == AWAITING_ACK);
// Two things can happen:
// Either the Object Save Request did actually go through, and then we should get in
// "AWAITING_COMPLETED" mode, or the Object Save Request did _not_ go through, for example
// because the object does not exist and then we will never get a subsequent update.
// For this reason, we will arm a 1 second timer to make provision for this and not block
// the queue:
saveState = AWAITING_COMPLETED;
disconnect(obj, SIGNAL(transactionCompleted(UAVObject*,bool)), this, SLOT(objectPersistenceTransactionCompleted(UAVObject*,bool)));
failureTimer.start(1000); // Create a timeout
} else {
// Can be caused by timeout errors on sending. Forget it and send next.
qDebug() << "objectPersistenceTranscationCompleted (error)";
UAVObject *obj = getObjectManager()->getObject(ObjectPersistence::NAME);
obj->disconnect(this);
queue.dequeue(); // We can now remove the object, it failed anyway.
saveState = IDLE;
emit saveCompleted(obj->getField("ObjectID")->getValue().toInt(), false);
saveNextObject();
}
}
QMutexLocker locker(mutex); /**
* @brief Object persistence operation failed, i.e. we never got an update
* from the board saying "completed".
*/
void UAVObjectUtilManager::objectPersistenceOperationFailed()
{
qDebug() << "objectPersistenceOperationFailed";
if(saveState == AWAITING_COMPLETED) {
//TODO: some warning that this operation failed somehow
// We have to disconnect the object persistence 'updated' signal
// and ask to save the next object:
UAVObject *obj = getObjectManager()->getObject(ObjectPersistence::NAME);
obj->disconnect(this);
queue.dequeue(); // We can now remove the object, it failed anyway.
saveState = IDLE;
emit saveCompleted(obj->getField("ObjectID")->getValue().toInt(), false);
saveNextObject();
}
}
if (!obj) return;
// Disconnect from sending object
/**
* @brief Process the ObjectPersistence updated message to confirm the right object saved
* then requests next object be saved.
* @param[in] The object just received. Must be ObjectPersistance
*/
void UAVObjectUtilManager::objectPersistenceUpdated(UAVObject * obj)
{
qDebug() << "objectPersistenceUpdated: " << obj->getField("Operation")->getValue().toString();
Q_ASSERT(obj->getName().compare("ObjectPersistence") == 0);
if(saveState == AWAITING_COMPLETED) {
failureTimer.stop();
// Check flight is saying it completed. This is the only thing flight should do to trigger an update.
Q_ASSERT( obj->getField("Operation")->getValue().toString().compare(QString("Completed")) == 0 );
// Check right object saved
UAVObject* savingObj = queue.head();
Q_ASSERT( obj->getField("ObjectID")->getValue() == savingObj->getObjID() );
obj->disconnect(this); obj->disconnect(this);
queue.dequeue(); // We can now remove the object, it's done. queue.dequeue(); // We can now remove the object, it's done.
saveState = IDLE;
emit saveCompleted(obj->getField("ObjectID")->getValue().toInt(), true);
saveNextObject(); saveNextObject();
}
} }
/** /**
* Get the UAV Board model, for anyone interested. Return format is: * Get the UAV Board model, for anyone interested. Return format is:
* (Board Type << 8) + BoardRevision. * (Board Type << 8) + BoardRevision.

View File

@ -38,6 +38,7 @@
#include <QtGlobal> #include <QtGlobal>
#include <QObject> #include <QObject>
#include <QTimer>
#include <QMutex> #include <QMutex>
#include <QQueue> #include <QQueue>
#include <QComboBox> #include <QComboBox>
@ -63,17 +64,25 @@ public:
int getBoardModel(); int getBoardModel();
QByteArray getBoardCPUSerial(); QByteArray getBoardCPUSerial();
QString getBoardDescription(); QString getBoardDescription();
UAVObjectManager* getObjectManager();
void saveObjectToSD(UAVObject *obj);
signals:
void saveCompleted(int objectID, bool status);
private: private:
QMutex *mutex; QMutex *mutex;
QQueue<UAVObject *> queue; QQueue<UAVObject *> queue;
enum {IDLE, AWAITING_ACK, AWAITING_COMPLETED} saveState;
void saveNextObject(); void saveNextObject();
void saveObjectToSD(UAVObject *obj); QTimer failureTimer;
private slots: private slots:
void transactionCompleted(UAVObject *obj, bool success); //void transactionCompleted(UAVObject *obj, bool success);
void objectPersistenceTransactionCompleted(UAVObject* obj, bool success);
void objectPersistenceUpdated(UAVObject * obj);
void objectPersistenceOperationFailed();
}; };

View File

@ -0,0 +1,137 @@
/**
******************************************************************************
*
* @file importsummary.cpp
* @author (C) 2011 The OpenPilot Team, http://www.openpilot.org
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVSettingsImportExport UAVSettings Import/Export Plugin
* @{
* @brief UAVSettings Import/Export 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 "importsummary.h"
ImportSummaryDialog::ImportSummaryDialog( QWidget *parent) :
QDialog(parent),
ui(new Ui::ImportSummaryDialog)
{
ui->setupUi(this);
setWindowTitle(tr("Import Summary"));
ui->importSummaryList->setColumnCount(3);
ui->importSummaryList->setRowCount(0);
QStringList header;
header.append("Save");
header.append("Name");
header.append("Status");
ui->importSummaryList->setHorizontalHeaderLabels(header);
ui->progressBar->setValue(0);
connect( ui->closeButton, SIGNAL(clicked()), this, SLOT(close()));
connect(ui->saveToFlash, SIGNAL(clicked()), this, SLOT(doTheSaving()));
// Connect the help button
connect(ui->helpButton, SIGNAL(clicked()), this, SLOT(openHelp()));
}
ImportSummaryDialog::~ImportSummaryDialog()
{
delete ui;
}
/*
Open the right page on the wiki
*/
void ImportSummaryDialog::openHelp()
{
QDesktopServices::openUrl( QUrl("http://wiki.openpilot.org/display/Doc/UAV+Settings+import-export", QUrl::StrictMode) );
}
/*
Adds a new line about a UAVObject along with its status
(whether it got saved OK or not)
*/
void ImportSummaryDialog::addLine(QString uavObjectName, QString text, bool status)
{
ui->importSummaryList->setRowCount(ui->importSummaryList->rowCount()+1);
int row = ui->importSummaryList->rowCount()-1;
ui->progressBar->setMaximum(row);
ui->importSummaryList->setCellWidget(row,0,new QCheckBox(ui->importSummaryList));
QTableWidgetItem *objName = new QTableWidgetItem(uavObjectName);
ui->importSummaryList->setItem(row, 1, objName);
QCheckBox *box = dynamic_cast<QCheckBox*>(ui->importSummaryList->cellWidget(row,0));
ui->importSummaryList->setItem(row,2,new QTableWidgetItem(text));
if (status) {
box->setChecked(true);
} else {
box->setChecked(false);
box->setEnabled(false);
}
this->repaint();
this->showEvent(NULL);
}
/*
Saves every checked UAVObjet in the list to Flash
*/
void ImportSummaryDialog::doTheSaving()
{
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVObjectUtilManager *utilManager = pm->getObject<UAVObjectUtilManager>();
connect(utilManager, SIGNAL(saveCompleted(int,bool)), this, SLOT(updateSaveCompletion()));
for(int i=0; i < ui->importSummaryList->rowCount(); i++) {
QString uavObjectName = ui->importSummaryList->item(i,1)->text();
QCheckBox *box = dynamic_cast<QCheckBox*>(ui->importSummaryList->cellWidget(i,0));
if (box->isChecked()) {
UAVObject* obj = objManager->getObject(uavObjectName);
utilManager->saveObjectToSD(obj);
this->repaint();
}
}
}
void ImportSummaryDialog::updateSaveCompletion()
{
ui->progressBar->setValue(ui->progressBar->value()+1);
}
void ImportSummaryDialog::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void ImportSummaryDialog::showEvent(QShowEvent *event)
{
Q_UNUSED(event)
ui->importSummaryList->resizeColumnsToContents();
int width = ui->importSummaryList->width()-(ui->importSummaryList->columnWidth(0)+
ui->importSummaryList->columnWidth(2));
ui->importSummaryList->setColumnWidth(1,width-15);
}

View File

@ -0,0 +1,71 @@
/**
******************************************************************************
*
* @file importsummary.h
* @author (C) 2011 The OpenPilot Team, http://www.openpilot.org
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVSettingsImportExport UAVSettings Import/Export Plugin
* @{
* @brief UAVSettings Import/Export 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
*/
#ifndef IMPORTSUMMARY_H
#define IMPORTSUMMARY_H
#include <QDialog>
#include <QCheckBox>
#include <QDesktopServices>
#include <QUrl>
#include "ui_importsummarydialog.h"
#include "uavdataobject.h"
#include "uavobjectmanager.h"
#include "extensionsystem/pluginmanager.h"
#include "uavobjectutil/uavobjectutilmanager.h"
namespace Ui {
class ImportSummaryDialog;
}
class ImportSummaryDialog : public QDialog
{
Q_OBJECT
public:
ImportSummaryDialog(QWidget *parent=0);
~ImportSummaryDialog();
void addLine(QString objectName, QString text, bool status);
protected:
void showEvent(QShowEvent *event);
void changeEvent(QEvent *e);
private:
Ui::ImportSummaryDialog *ui;
public slots:
void updateSaveCompletion();
private slots:
void doTheSaving();
void openHelp();
};
#endif // IMPORTSUMMARY_H

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ImportSummaryDialog</class>
<widget class="QDialog" name="ImportSummaryDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>377</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>UAV Settings import summary</string>
</property>
</widget>
</item>
<item>
<widget class="QTableWidget" name="importSummaryList">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>10</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>24</number>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="helpButton">
<property name="maximumSize">
<size>
<width>32</width>
<height>32</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>32</width>
<height>32</height>
</size>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveToFlash">
<property name="toolTip">
<string>Save all settings checked above to persistent board storage,
then close the dialog.</string>
</property>
<property name="text">
<string>Save to Board Flash/SD</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="closeButton">
<property name="toolTip">
<string>Close this dialog without saving to persistent storage</string>
</property>
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../coreplugin/core.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -25,17 +25,12 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/*
* TODO:
* - write import functions
* - split formats into different files/classes
* - better error handling (not a lot of QMessageBoxes)
*/
#include "uavsettingsimportexport.h" #include "uavsettingsimportexport.h"
#include <QtPlugin> #include <QtPlugin>
#include <QStringList> #include <QStringList>
#include <QDebug>
#include <QCheckBox>
// for menu item // for menu item
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
@ -74,20 +69,22 @@ bool UAVSettingsImportExportPlugin::initialize(const QStringList& args, QString
Core::ActionManager* am = Core::ICore::instance()->actionManager(); Core::ActionManager* am = Core::ICore::instance()->actionManager();
Core::ActionContainer* ac = am->actionContainer(Core::Constants::M_FILE); Core::ActionContainer* ac = am->actionContainer(Core::Constants::M_FILE);
Core::Command* cmd = am->registerAction(new QAction(this), Core::Command* cmd = am->registerAction(new QAction(this),
"UAVSettingsImportExportPlugin.UAVSettingsImportExport", "UAVSettingsImportExportPlugin.UAVSettingsExport",
QList<int>() << QList<int>() <<
Core::Constants::C_GLOBAL_ID); Core::Constants::C_GLOBAL_ID);
cmd->setDefaultKeySequence(QKeySequence("Ctrl+E")); cmd->setDefaultKeySequence(QKeySequence("Ctrl+E"));
cmd->action()->setText(tr("Export UAV Settings..."));
// cmd->action()->setText(tr("UAV Settings Import/Export..."));
cmd->action()->setText(tr("UAV Settings Export..."));
// ac->menu()->addSeparator();
// ac->appendGroup("ImportExport");
// ac->addAction(cmd, "ImportExport");
ac->addAction(cmd, Core::Constants::G_FILE_SAVE); ac->addAction(cmd, Core::Constants::G_FILE_SAVE);
connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(exportUAVSettings()));
connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(importExport())); cmd = am->registerAction(new QAction(this),
"UAVSettingsImportExportPlugin.UAVSettingsImport",
QList<int>() <<
Core::Constants::C_GLOBAL_ID);
cmd->setDefaultKeySequence(QKeySequence("Ctrl+I"));
cmd->action()->setText(tr("Import UAV Settings..."));
ac->addAction(cmd, Core::Constants::G_FILE_SAVE);
connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(importUAVSettings()));
return true; return true;
} }
@ -97,40 +94,129 @@ void UAVSettingsImportExportPlugin::extensionsInitialized()
// Do nothing // Do nothing
} }
// Slot called by the menu manager on user action
// TODO: import function is not implemented yet
void UAVSettingsImportExportPlugin::importExport()
{
// available formats
enum { UNDEF, UAV, XML, INI } fileFormat = UNDEF;
// ask for file name and export format // Slot called by the menu manager on user action
void UAVSettingsImportExportPlugin::importUAVSettings()
{
// ask for file name
QString fileName; QString fileName;
QString filters = tr("UAV Settings files (*.uav)") QString filters = tr("UAVSettings XML files (*.uav);; XML files (*.xml)");
+ ";;" + tr("Simple XML files (*.xml)") fileName = QFileDialog::getOpenFileName(0, tr("Import UAV Settings"), "", filters);
+ ";;" + tr("INI files (*.ini)"); if (fileName.isEmpty()) {
return;
}
// Now open the file
QFile file(fileName);
QDomDocument doc("UAVSettings");
file.open(QFile::ReadOnly|QFile::Text);
if (!doc.setContent(file.readAll())) {
QMessageBox msgBox;
msgBox.setText(tr("File Parsing Failed."));
msgBox.setInformativeText(tr("This file is not a correct XML file"));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.exec();
return;
}
file.close();
QDomElement root = doc.documentElement();
if (root.tagName() != "settings") {
QMessageBox msgBox;
msgBox.setText(tr("Wrong file contents."));
msgBox.setInformativeText(tr("This file is not a correct UAVSettings file"));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.exec();
return;
}
// We are now ok: setup the import summary dialog & update it as we
// go along.
ImportSummaryDialog swui;
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
swui.show();
QDomNode node = root.firstChild();
while (!node.isNull()) {
QDomElement e = node.toElement();
if (e.tagName() == "object") {
// - Read each object
QString uavObjectName = e.attribute("name");
uint uavObjectID = e.attribute("id").toUInt(NULL,16);
// Sanity Check:
UAVObject* obj = objManager->getObject(uavObjectName);
if (obj == NULL) {
// This object is unknown!
qDebug() << "Object unknown:" << uavObjectName << uavObjectID;
swui.addLine(uavObjectName, "Error (Object unknown)", false);
} else {
// - Update each field
// - Issue and "updated" command
bool error=false;
QDomNode field = node.firstChild();
while(!field.isNull()) {
QDomElement f = field.toElement();
if (f.tagName() == "field") {
UAVObjectField *uavfield = obj->getField(f.attribute("name"));
if (uavfield) {
QStringList list = f.attribute("values").split(",");
if (list.length() == 1) {
uavfield->setValue(f.attribute("values"));
} else {
// This is an enum:
int i=0;
QStringList list = f.attribute("values").split(",");
foreach (QString element, list) {
uavfield->setValue(element,i++);
}
}
error = false;
} else {
error = true;
}
}
field = field.nextSibling();
}
obj->updated();
if (error) {
swui.addLine(uavObjectName, "Warning (Object field unknown)", true);
} else if (uavObjectID != obj->getObjID()) {
qDebug() << "Mismatch for Object " << uavObjectName << uavObjectID << " - " << obj->getObjID();
swui.addLine(uavObjectName, "Warning (ObjectID mismatch)", true);
} else
swui.addLine(uavObjectName, "OK", true);
}
}
node = node.nextSibling();
}
swui.exec();
}
// Slot called by the menu manager on user action
void UAVSettingsImportExportPlugin::exportUAVSettings()
{
// ask for file name
QString fileName;
QString filters = tr("UAVSettings XML files (*.uav)");
fileName = QFileDialog::getSaveFileName(0, tr("Save UAV Settings File As"), "", filters); fileName = QFileDialog::getSaveFileName(0, tr("Save UAV Settings File As"), "", filters);
if (fileName.isEmpty()) { if (fileName.isEmpty()) {
return; return;
} }
// check export file format bool fullExport = false;
QFileInfo fileInfo(fileName); // If the filename ends with .xml, we will do a full export, otherwise, a simple export
QString fileType = fileInfo.suffix().toLower(); if (fileName.endsWith(".xml")) {
fullExport = true;
if (fileType == "uav") { } else if (!fileName.endsWith(".uav")) {
fileFormat = UAV; fileName.append(".uav");
} else if (fileType == "xml") {
fileFormat = XML;
} else if (fileType == "ini") {
fileFormat = INI;
} else {
QMessageBox::critical(0,
tr("UAV Settings Export"),
tr("Unsupported export file format: ") + fileType,
QMessageBox::Ok);
return;
} }
// generate an XML first (used for all export formats as a formatted data source) // generate an XML first (used for all export formats as a formatted data source)
@ -152,7 +238,7 @@ void UAVSettingsImportExportPlugin::importExport()
QDomElement o = doc.createElement("object"); QDomElement o = doc.createElement("object");
o.setAttribute("name", obj->getName()); o.setAttribute("name", obj->getName());
o.setAttribute("id", QString("0x")+ QString().setNum(obj->getObjID(),16).toUpper()); o.setAttribute("id", QString("0x")+ QString().setNum(obj->getObjID(),16).toUpper());
if (fileFormat == UAV) { if (fullExport) {
QDomElement d = doc.createElement("description"); QDomElement d = doc.createElement("description");
QDomText t = doc.createTextNode(obj->getDescription().remove("@Ref ", Qt::CaseInsensitive)); QDomText t = doc.createTextNode(obj->getDescription().remove("@Ref ", Qt::CaseInsensitive));
d.appendChild(t); d.appendChild(t);
@ -175,7 +261,7 @@ void UAVSettingsImportExportPlugin::importExport()
f.setAttribute("name", field->getName()); f.setAttribute("name", field->getName());
f.setAttribute("values", vals); f.setAttribute("values", vals);
if (fileFormat == UAV) { if (fullExport) {
f.setAttribute("type", field->getTypeAsString()); f.setAttribute("type", field->getTypeAsString());
f.setAttribute("units", field->getUnits()); f.setAttribute("units", field->getUnits());
f.setAttribute("elements", nelem); f.setAttribute("elements", nelem);
@ -189,9 +275,7 @@ void UAVSettingsImportExportPlugin::importExport()
} }
} }
} }
// save file // save file
if ((fileFormat == UAV) || (fileFormat == XML)) {
QFile file(fileName); QFile file(fileName);
if (file.open(QIODevice::WriteOnly) && if (file.open(QIODevice::WriteOnly) &&
(file.write(doc.toString(4).toAscii()) != -1)) { (file.write(doc.toString(4).toAscii()) != -1)) {
@ -203,34 +287,11 @@ void UAVSettingsImportExportPlugin::importExport()
QMessageBox::Ok); QMessageBox::Ok);
return; return;
} }
} else if (fileFormat == INI) {
if (QFile::exists(fileName) && !QFile::remove(fileName)) {
QMessageBox::critical(0,
tr("UAV Settings Export"),
tr("Unable to remove existing file: ") + fileName,
QMessageBox::Ok);
return;
}
QSettings ini(fileName, QSettings::IniFormat); QMessageBox msgBox;
QDomElement docElem = doc.documentElement(); msgBox.setText(tr("Settings saved."));
QDomNodeList nodeList = docElem.elementsByTagName("object"); msgBox.setStandardButtons(QMessageBox::Ok);
for (int i = 0; i < nodeList.count(); i++) { msgBox.exec();
QDomElement e = nodeList.at(i).toElement();
if (!e.isNull()) {
ini.beginGroup(e.attribute("name", "undefined"));
ini.setValue("id", e.attribute("id"));
QDomNodeList n = e.elementsByTagName("field");
for (int j = 0; j < n.count(); j++) {
QDomElement f = n.at(j).toElement();
if (!f.isNull()) {
ini.setValue(f.attribute("name", "unknown"), f.attribute("values"));
}
}
ini.endGroup();
}
}
}
} }
void UAVSettingsImportExportPlugin::shutdown() void UAVSettingsImportExportPlugin::shutdown()

View File

@ -28,6 +28,8 @@
#define UAVSETTINGSIMPORTEXPORT_H #define UAVSETTINGSIMPORTEXPORT_H
#include <extensionsystem/iplugin.h> #include <extensionsystem/iplugin.h>
#include "uavobjectutil/uavobjectutilmanager.h"
#include "importsummary.h"
class UAVSettingsImportExportPlugin : public ExtensionSystem::IPlugin class UAVSettingsImportExportPlugin : public ExtensionSystem::IPlugin
{ {
@ -42,7 +44,8 @@ public:
void shutdown(); void shutdown();
private slots: private slots:
void importExport(); void importUAVSettings();
void exportUAVSettings();
}; };

View File

@ -7,5 +7,6 @@
<dependencyList> <dependencyList>
<dependency name="Core" version="1.0.0"/> <dependency name="Core" version="1.0.0"/>
<dependency name="UAVObjects" version="1.0.0"/> <dependency name="UAVObjects" version="1.0.0"/>
<dependency name="UAVObjectUtil" version="1.0.0"/>
</dependencyList> </dependencyList>
</plugin> </plugin>

View File

@ -7,7 +7,12 @@ TARGET = UAVSettingsImportExport
include(../../openpilotgcsplugin.pri) include(../../openpilotgcsplugin.pri)
include(uavsettingsimportexport_dependencies.pri) include(uavsettingsimportexport_dependencies.pri)
HEADERS += uavsettingsimportexport.h HEADERS += uavsettingsimportexport.h \
SOURCES += uavsettingsimportexport.cpp importsummary.h
SOURCES += uavsettingsimportexport.cpp \
importsummary.cpp
OTHER_FILES += uavsettingsimportexport.pluginspec OTHER_FILES += uavsettingsimportexport.pluginspec
FORMS += \
importsummarydialog.ui

View File

@ -1,2 +1,3 @@
include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/coreplugin/coreplugin.pri)
include(../../plugins/uavobjects/uavobjects.pri) include(../../plugins/uavobjects/uavobjects.pri)
include(../../plugins/uavobjectutil/uavobjectutil.pri)

View File

@ -4,7 +4,7 @@
<field name="AccelBias" units="lsb" type="int16" elementnames="X,Y,Z" defaultvalue="0"/> <field name="AccelBias" units="lsb" type="int16" elementnames="X,Y,Z" defaultvalue="0"/>
<field name="BoardRotation" units="deg" type="int16" elementnames="Roll,Pitch,Yaw" defaultvalue="0,0,0"/> <field name="BoardRotation" units="deg" type="int16" elementnames="Roll,Pitch,Yaw" defaultvalue="0,0,0"/>
<field name="GyroGain" units="(rad/s)/lsb" type="float" elements="1" defaultvalue="0.42"/> <field name="GyroGain" units="(rad/s)/lsb" type="float" elements="1" defaultvalue="0.42"/>
<field name="AccelKp" units="channel" type="float" elements="1" defaultvalue="0.05"/> <field name="AccelKp" units="channel" type="float" elements="1" defaultvalue="0.03"/>
<field name="AccelKi" units="channel" type="float" elements="1" defaultvalue="0.0001"/> <field name="AccelKi" units="channel" type="float" elements="1" defaultvalue="0.0001"/>
<field name="YawBiasRate" units="channel" type="float" elements="1" defaultvalue="0.000001"/> <field name="YawBiasRate" units="channel" type="float" elements="1" defaultvalue="0.000001"/>
<field name="ZeroDuringArming" units="channel" type="enum" elements="1" options="FALSE,TRUE" defaultvalue="FALSE"/> <field name="ZeroDuringArming" units="channel" type="enum" elements="1" options="FALSE,TRUE" defaultvalue="FALSE"/>

View File

@ -2,11 +2,11 @@
<object name="ManualControlSettings" singleinstance="true" settings="true"> <object name="ManualControlSettings" singleinstance="true" settings="true">
<description>Settings to indicate how to decode receiver input by @ref ManualControlModule.</description> <description>Settings to indicate how to decode receiver input by @ref ManualControlModule.</description>
<field name="InputMode" units="" type="enum" elements="1" options="PWM,PPM,Spektrum" defaultvalue="PWM"/> <field name="InputMode" units="" type="enum" elements="1" options="PWM,PPM,Spektrum" defaultvalue="PWM"/>
<field name="Roll" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="Channel1"/> <field name="Roll" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/>
<field name="Pitch" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="Channel2"/> <field name="Pitch" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/>
<field name="Yaw" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="Channel3"/> <field name="Yaw" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/>
<field name="Throttle" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="Channel4"/> <field name="Throttle" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/>
<field name="FlightMode" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="Channel5"/> <field name="FlightMode" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/>
<field name="Accessory0" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/> <field name="Accessory0" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/>
<field name="Accessory1" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/> <field name="Accessory1" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/>
<field name="Accessory2" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/> <field name="Accessory2" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="None"/>