1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-29 14:52:12 +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"
id="svg10068"
version="1.1"
inkscape:version="0.47 r22583"
inkscape:version="0.48.1 r9760"
sodipodi:docname="flightmode-status.svg"
inkscape:export-filename="H:\Documents\Hobbies\W433\My Gauges\vbat-001.png"
inkscape:export-xdpi="103.61"
@ -949,6 +949,94 @@
fx="29.77438"
fy="7.0922189"
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>
<sodipodi:namedview
id="base"
@ -958,13 +1046,13 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="56.191298"
inkscape:cx="-7.1957738"
inkscape:cy="90.710362"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="725"
inkscape:window-width="1366"
inkscape:window-height="691"
inkscape:window-x="0"
inkscape:window-y="24"
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"
id="value"
width="132.66878"
height="20.899738"
height="13.323594"
x="15.425945"
y="29.964067"
ry="5.4077783"
y="33.75214"
ry="3.4474616"
inkscape:label="#rect2989" />
<g
id="symbol-Stabilized"
id="symbol-Stabilized1"
inkscape:label="#g3832"
transform="matrix(1.2181818,0,0,1.2181818,-416.7342,39.213763)">
<g
@ -1297,7 +1385,7 @@
</g>
</g>
<g
id="symbol-Auto"
id="symbol-VelocityControl"
inkscape:label="#g4229"
transform="matrix(1.2181818,0,0,1.2181818,-132.92733,94.550987)">
<g
@ -1354,5 +1442,245 @@
inkscape:export-xdpi="103.61"
inkscape:export-ydpi="103.61" />
</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>
</svg>

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -14,7 +14,7 @@
height="80.827866"
id="svg10068"
version="1.1"
inkscape:version="0.47 r22583"
inkscape:version="0.48.1 r9760"
sodipodi:docname="flightmode-status.svg"
inkscape:export-filename="H:\Documents\Hobbies\W433\My Gauges\vbat-001.png"
inkscape:export-xdpi="103.61"
@ -949,6 +949,94 @@
fx="29.77438"
fy="7.0922189"
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>
<sodipodi:namedview
id="base"
@ -958,13 +1046,13 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="56.191298"
inkscape:cx="-7.1957738"
inkscape:cy="90.710362"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="725"
inkscape:window-width="1366"
inkscape:window-height="691"
inkscape:window-x="0"
inkscape:window-y="24"
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"
id="value"
width="132.66878"
height="20.899738"
height="13.323594"
x="15.425945"
y="29.964067"
ry="5.4077783"
y="33.75214"
ry="3.4474616"
inkscape:label="#rect2989" />
<g
id="symbol-Stabilized"
id="symbol-Stabilized1"
inkscape:label="#g3832"
transform="matrix(1.2181818,0,0,1.2181818,-416.7342,39.213763)">
<g
@ -1297,7 +1385,7 @@
</g>
</g>
<g
id="symbol-Auto"
id="symbol-VelocityControl"
inkscape:label="#g4229"
transform="matrix(1.2181818,0,0,1.2181818,-132.92733,94.550987)">
<g
@ -1354,5 +1442,245 @@
inkscape:export-xdpi="103.61"
inkscape:export-ydpi="103.61" />
</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>
</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>
</widget>
</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>
<widget class="QPushButton" name="ahrsSettingsSaveRAM">
<property name="toolTip">

View File

@ -1962,16 +1962,6 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</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>
<widget class="QPushButton" name="saveAircraftToRAM">
<property name="toolTip">
@ -2316,16 +2306,6 @@ p, li { white-space: pre-wrap; }
</property>
</spacer>
</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>
<widget class="QPushButton" name="ffApply">
<property name="toolTip">

View File

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

View File

@ -216,18 +216,25 @@ ConfigAHRSWidget::ConfigAHRSWidget(QWidget *parent) : ConfigTaskWidget(parent)
// Connect the signals
connect(m_ahrs->ahrsCalibStart, SIGNAL(clicked()), this, SLOT(launchAHRSCalibration()));
connect(m_ahrs->accelBiasStart, SIGNAL(clicked()), this, SLOT(launchAccelBiasCalibration()));
connect(m_ahrs->ahrsSettingsRequest, SIGNAL(clicked()), this, SLOT(ahrsSettingsRequest()));
/*
connect(m_ahrs->algorithm, SIGNAL(currentIndexChanged(int)), this, SLOT(ahrsSettingsSave()));
connect(m_ahrs->indoorFlight, SIGNAL(stateChanged(int)), this, SLOT(homeLocationSave()));
connect(m_ahrs->homeLocation, SIGNAL(clicked()), this, SLOT(homeLocationSaveSD()));
*/
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSSettings")));
connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(refreshValues()));
obj = getObjectManager()->getObject(QString("HomeLocation"));
connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(refreshValues()));
connect(m_ahrs->ahrsSettingsSaveRAM, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveRAM()));
connect(m_ahrs->ahrsSettingsSaveSD, SIGNAL(clicked()), this, SLOT(ahrsSettingsSaveSD()));
connect(m_ahrs->sixPointsStart, SIGNAL(clicked()), this, SLOT(multiPointCalibrationMode()));
connect(m_ahrs->sixPointsSave, SIGNAL(clicked()), this, SLOT(savePositionData()));
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(m_ahrs->ahrsHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
@ -256,6 +263,13 @@ void ConfigAHRSWidget::resizeEvent(QResizeEvent *event)
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.
*/
@ -274,7 +288,7 @@ void ConfigAHRSWidget::launchAccelBiasCalibration()
accel_accum_y.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,1);
// ahrsCalib->getField("accel_bias")->setDouble(0,2);
@ -409,6 +423,7 @@ void ConfigAHRSWidget::launchGyroDriftCalibration()
*/
void ConfigAHRSWidget::driftCalibrationAttitudeRawUpdated(UAVObject* obj) {
Q_UNUSED(obj)
// This is necessary to prevent a race condition on disconnect signal and another update
if (collectingData == true) {
/**
@ -568,8 +583,7 @@ void ConfigAHRSWidget::saveAHRSCalibration()
UAVObjectField *field = obj->getField(QString("measure_var"));
field->setValue("SET");
obj->updated();
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj);
saveObjectToSD(obj);
}
FORCE_ALIGN_FUNC
@ -1136,17 +1150,16 @@ void ConfigAHRSWidget::drawVariancesGraph()
/**
Request current settings from the AHRS
*/
void ConfigAHRSWidget::ahrsSettingsRequest()
void ConfigAHRSWidget::refreshValues()
{
UAVObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("AHRSSettings")));
obj->requestUpdate();
UAVObject *obj = getObjectManager()->getObject(QString("AHRSSettings"));
UAVObjectField *field = obj->getField(QString("Algorithm"));
if (field)
m_ahrs->algorithm->setCurrentIndex(m_ahrs->algorithm->findText(field->getValue().toString()));
drawVariancesGraph();
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("HomeLocation")));
obj = getObjectManager()->getObject(QString("HomeLocation"));
field = obj->getField(QString("Set"));
if (field)
m_ahrs->homeLocationSet->setEnabled(field->getValue().toBool());

View File

@ -55,6 +55,7 @@ public:
private:
void drawVariancesGraph();
void displayPlane(QString elementID);
virtual void enableControls(bool enable);
Ui_AHRSWidget *m_ahrs;
QGraphicsSvgItem *paperplane;
@ -130,7 +131,9 @@ private slots:
void launchAccelBiasCalibration();
void calibPhase2();
void incrementProgress();
void ahrsSettingsRequest();
virtual void refreshValues();
//void ahrsSettingsRequest();
void ahrsSettingsSaveRAM();
void ahrsSettingsSaveSD();
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->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->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->multirotorFrameType, SIGNAL(currentIndexChanged(QString)), this, SLOT(setupAirframeUI(QString)));
connect(m_aircraft->aircraftType, SIGNAL(currentIndexChanged(int)), this, SLOT(switchAirframeType(int)));
requestAircraftUpdate();
connect(m_aircraft->fwThrottleReset, SIGNAL(clicked()), this, SLOT(resetFwMixer()));
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->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(m_aircraft->airframeHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
}
ConfigAirframeWidget::~ConfigAirframeWidget()
@ -203,6 +213,18 @@ ConfigAirframeWidget::~ConfigAirframeWidget()
// 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
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
**************************/
/**
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:
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("SystemSettings")));
Q_ASSERT(obj);
obj->requestUpdate();
UAVObjectField *field = obj->getField(QString("AirframeType"));
Q_ASSERT(field);
// 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")));
Q_ASSERT(obj);
obj->requestUpdate();
field = obj->getField(QString("ThrottleCurve1"));
Q_ASSERT(field);
QList<double> curveValues;
@ -1524,7 +1544,7 @@ bool ConfigAirframeWidget::setupMixer(double mixerFactors[8][3])
setupQuadMotor(channel, mixerFactors[i][0]*pFactor,
rFactor*mixerFactors[i][1], yFactor*mixerFactors[i][2]);
}
obj->updated();
// obj->updated();
return true;
}
@ -1568,7 +1588,7 @@ void ConfigAirframeWidget::setupMotors(QList<QString> motorList)
field = obj->getField(motor);
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");
return;
}
motorList << "VTOLMotorNW" << "VTOLMotorNE" << "VTOLMotorS";
setupMotors(motorList);
obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
field = obj->getField("FixedWingYaw1");
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:
// pitch roll yaw
@ -2112,10 +2130,13 @@ void ConfigAirframeWidget::sendAircraftUpdate()
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"));
field->setValue(airframeType);
obj->updated();

View File

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

View File

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

View File

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

View File

@ -1195,11 +1195,9 @@ void ConfigccpmWidget::saveccpmUpdate()
ShowDisclaimer(0);
// Send update so that the latest value is saved
sendccpmUpdate();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("MixerSettings")));
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("MixerSettings")));
Q_ASSERT(obj);
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj);
saveObjectToSD(obj);
}
void ConfigccpmWidget::resizeEvent(QResizeEvent* event)
@ -1276,7 +1274,7 @@ void ConfigccpmWidget::SwashLvlStartButtonPressed()
// Get the channel assignements:
obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
obj->requestUpdate();
// obj->requestUpdate();
MinField = obj->getField(QString("ChannelMin"));
NeutralField = obj->getField(QString("ChannelNeutral"));
MaxField = obj->getField(QString("ChannelMax"));
@ -1506,8 +1504,7 @@ void ConfigccpmWidget::SwashLvlFinishButtonPressed()
}
obj->updated();
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj);
saveObjectToSD(obj);
//restore Flight control of ActuatorCommand
enableSwashplateLevellingControl(false);
@ -1536,7 +1533,7 @@ int ConfigccpmWidget::ShowDisclaimer(int messageID)
break;
case 1:
// 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.setDefaultButton(QMessageBox::Cancel);
msgBox.setIcon(QMessageBox::Warning);

View File

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

View File

@ -90,10 +90,11 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
TelemetryManager* telMngr = pm->getObject<TelemetryManager>();
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
// And check whether by any chance we are not already connected
if (telMngr->isConnected())
onAutopilotConnect();
onAutopilotConnect();
help = 0;
}
@ -111,6 +112,10 @@ void ConfigGadgetWidget::resizeEvent(QResizeEvent *event)
QWidget::resizeEvent(event);
}
void ConfigGadgetWidget::onAutopilotDisconnect() {
emit autopilotDisconnected();
}
void ConfigGadgetWidget::onAutopilotConnect() {
// 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"));
}
}
emit autopilotConnected();
}

View File

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

View File

@ -38,13 +38,15 @@
#include <QDesktopServices>
#include <QUrl>
#include "manualcontrolsettings.h"
ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent)
{
m_config = new Ui_InputWidget();
m_config->setupUi(this);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
// First of all, put all the channel widgets into lists, so that we can
// manipulate those:
@ -68,15 +70,6 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent)
<< m_config->ch6Min
<< 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
<< m_config->inSlider1
<< m_config->inSlider2
@ -95,12 +88,24 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) : ConfigTaskWidget(parent)
<< m_config->ch6Rev
<< 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
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlCommand")));
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
// dropdown menu:
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->addItems(field->getOptions());
requestRCInputUpdate();
connect(m_config->saveRCInputToSD, SIGNAL(clicked()), this, SLOT(saveRCInputObject()));
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()));
connect(m_config->inSlider0, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged0(int)));
connect(m_config->inSlider1, SIGNAL(valueChanged(int)),this, SLOT(onInSliderValueChanged1(int)));
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)));
enableControls(false);
refreshValues();
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
connect(parent, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()));
connect(m_config->ch0Rev, 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;
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(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)
{
m_config->getRCInputCurrent->setEnabled(enable);
m_config->saveRCInputToRAM->setEnabled(enable);
//m_config->saveRCInputToRAM->setEnabled(enable);
m_config->saveRCInputToSD->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
*/
void ConfigInputWidget::requestRCInputUpdate()
void ConfigInputWidget::refreshValues()
{
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ManualControlSettings")));
Q_ASSERT(obj);
obj->requestUpdate();
//obj->requestUpdate();
UAVObjectField *field;
// Now update all the slider values:
@ -350,14 +264,9 @@ void ConfigInputWidget::requestRCInputUpdate()
m_config->receiverType->setCurrentIndex(m_config->receiverType->findText(field->getValue().toString()));
// Reset all channel assignement dropdowns:
m_config->ch0Assign->setCurrentIndex(0);
m_config->ch1Assign->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);
foreach (QComboBox *combo, inChannelAssign) {
combo->setCurrentIndex(0);
}
// Update all channels assignements
QList<UAVObjectField *> fieldList = obj->getFields();
@ -508,11 +417,9 @@ void ConfigInputWidget::saveRCInputObject()
{
// Send update so that the latest value is saved
sendRCInputUpdate();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ManualControlSettings")));
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ManualControlSettings")));
Q_ASSERT(obj);
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj);
saveObjectToSD(obj);
}
@ -567,35 +474,38 @@ void ConfigInputWidget::updateChannels(UAVObject* controlCommand)
if (m_config->doRCInputCalibration->isChecked()) {
if (firstUpdate) {
// Increase the data rate from the board so that the sliders
// move faster
UAVObject::Metadata mdata = controlCommand->getMetadata();
mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
mccDataRate = mdata.flightTelemetryUpdatePeriod;
mdata.flightTelemetryUpdatePeriod = 150;
controlCommand->setMetadata(mdata);
// Also protect the user by setting all values to zero
// and making the ActuatorCommand object readonly
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorCommand")));
mdata = obj->getMetadata();
mdata.flightAccess = UAVObject::ACCESS_READONLY;
obj->setMetadata(mdata);
UAVObjectField *field = obj->getField("Channel");
for (int i=0; i< field->getNumElements(); i++) {
field->setValue(0,i);
}
obj->updated();
// Increase the data rate from the board so that the sliders
// move faster
UAVObject::Metadata mdata = controlCommand->getMetadata();
mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
mccDataRate = mdata.flightTelemetryUpdatePeriod;
mdata.flightTelemetryUpdatePeriod = 150;
controlCommand->setMetadata(mdata);
// Also protect the user by setting all values to zero
// and making the ActuatorCommand object readonly
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorCommand")));
mdata = obj->getMetadata();
mdata.flightAccess = UAVObject::ACCESS_READONLY;
obj->setMetadata(mdata);
UAVObjectField *field = obj->getField("Channel");
for (uint i=0; i< field->getNumElements(); i++) {
field->setValue(0,i);
}
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"));
for (int i = 0; i < 8; i++)
updateChannelInSlider(inSliders[i], inMinLabels[i], inMaxLabels[i], field->getValue(i).toInt(),inRevCheckboxes[i]->isChecked());
firstUpdate = false;
}
else {
if (!firstUpdate) {
}
else {
if (!firstUpdate) {
// Restore original data rate from the board:
UAVObject::Metadata mdata = controlCommand->getMetadata();
mdata.flightTelemetryUpdateMode = UAVObject::UPDATEMODE_PERIODIC;
@ -606,44 +516,83 @@ void ConfigInputWidget::updateChannels(UAVObject* controlCommand)
mdata = obj->getMetadata();
mdata.flightAccess = UAVObject::ACCESS_READWRITE;
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;
}
//Update the Flight mode channel slider
UAVObject* obj = getObjectManager()->getObject("ManualControlSettings");
// Find the channel currently assigned to flightmode
field = obj->getField("FlightMode");
int chIndex = field->getOptions().indexOf(field->getValue().toString());
if (chIndex < field->getOptions().length() - 1) {
ManualControlSettings * manualSettings = ManualControlSettings::GetInstance(getObjectManager());
ManualControlSettings::DataFields manualSettingsData = manualSettings->getData();
uint chIndex = manualSettingsData.FlightMode;
if (chIndex < manualSettings->FLIGHTMODE_NONE) {
float valueScaled;
int chMin = inSliders[chIndex]->minimum();
int chMax = inSliders[chIndex]->maximum();
int chNeutral = inSliders[chIndex]->value();
int chMin = manualSettingsData.ChannelMin[chIndex];
int chMax = manualSettingsData.ChannelMax[chIndex];
int chNeutral = manualSettingsData.ChannelNeutral[chIndex];
int value = controlCommand->getField("Channel")->getValue(chIndex).toInt();
if ((chMax > chMin && value >= chNeutral) || (chMin > chMax && value <= chNeutral))
{
if (chMax != chNeutral)
valueScaled = (float)(value - chNeutral) / (float)(chMax - chNeutral);
else
valueScaled = 0;
if (chMax != chNeutral)
valueScaled = (float)(value - chNeutral) / (float)(chMax - chNeutral);
else
valueScaled = 0;
}
else
{
if (chMin != chNeutral)
valueScaled = (float)(value - chNeutral) / (float)(chNeutral - chMin);
else
valueScaled = 0;
if (chMin != chNeutral)
valueScaled = (float)(value - chNeutral) / (float)(chNeutral - chMin);
else
valueScaled = 0;
}
// Bound
if (valueScaled > 1.0) valueScaled = 1.0;
else
if (valueScaled < -1.0) valueScaled = -1.0;
if(valueScaled < -(1.0 / 3.0))
m_config->fmsSlider->setValue(-100);
else if (valueScaled > (1.0/3.0))
m_config->fmsSlider->setValue(100);
else
m_config->fmsSlider->setValue(0);
m_config->fmsSlider->setValue(valueScaled * 100);
}
}
}
void ConfigInputWidget::updateChannelInSlider(QSlider *slider, QLabel *min, QLabel *max, int value, bool reversed)

View File

@ -46,19 +46,6 @@ public:
~ConfigInputWidget();
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:
Ui_InputWidget *m_config;
@ -79,14 +66,15 @@ private:
QList<QLabel*> inMinLabels;
QList<QLabel*> inNeuLabels;
QList<QCheckBox*> inRevCheckboxes;
QList<QComboBox*> inChannelAssign;
bool firstUpdate;
void enableControls(bool enable);
virtual void enableControls(bool enable);
private slots:
void updateChannels(UAVObject* obj);
void requestRCInputUpdate();
virtual void refreshValues();
void sendRCInputUpdate();
void saveRCInputObject();
void reverseCheckboxClicked(bool state);

View File

@ -97,18 +97,17 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
<< m_config->ch7Rev;
links << m_config->ch0Link
<< m_config->ch1Link
<< m_config->ch2Link
<< m_config->ch3Link
<< m_config->ch4Link
<< m_config->ch5Link
<< m_config->ch6Link
<< m_config->ch7Link;
<< m_config->ch1Link
<< m_config->ch2Link
<< m_config->ch3Link
<< m_config->ch4Link
<< m_config->ch5Link
<< m_config->ch6Link
<< m_config->ch7Link;
// Register for ActuatorSettings changes:
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++) {
connect(outMin[i], SIGNAL(editingFinished()), this, SLOT(setChOutRange()));
@ -120,41 +119,23 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
connect(m_config->channelOutTest, SIGNAL(toggled(bool)), this, SLOT(runChannelTests(bool)));
for (int i = 0; i < links.count(); i++)
links[i]->setChecked(false);
for (int i = 0; i < links.count(); i++)
connect(links[i], SIGNAL(toggled(bool)), this, SLOT(linkToggled(bool)));
requestRCOutputUpdate();
for (int i = 0; i < links.count(); i++)
links[i]->setChecked(false);
for (int i = 0; i < links.count(); i++)
connect(links[i], SIGNAL(toggled(bool)), this, SLOT(linkToggled(bool)));
connect(m_config->saveRCOutputToSD, SIGNAL(clicked()), this, SLOT(saveRCOutputObject()));
connect(m_config->saveRCOutputToRAM, SIGNAL(clicked()), this, SLOT(sendRCOutputUpdate()));
// Actually, this is not really needed since we are subscribing to the object updates already
// TODO: remove those buttons on all config gadget panels.
connect(m_config->getRCOutputCurrent, SIGNAL(clicked()), this, SLOT(requestRCOutputUpdate()));
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(requestRCOutputUpdate()));
enableControls(false);
refreshValues();
connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect()));
connect(parent, SIGNAL(autopilotDisconnected()), this, SLOT(onAutopilotDisconnect()));
firstUpdate = true;
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(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)
{
m_config->saveRCOutputToSD->setEnabled(enable);
m_config->saveRCOutputToRAM->setEnabled(enable);
m_config->getRCOutputCurrent->setEnabled(enable);
//m_config->saveRCOutputToRAM->setEnabled(enable);
}
// ************************************
@ -203,29 +161,30 @@ void ConfigOutputWidget::enableControls(bool enable)
*/
void ConfigOutputWidget::linkToggled(bool state)
{
// find the minimum slider value for the linked ones
int min = 10000;
int linked_count = 0;
for (int i = 0; i < outSliders.count(); i++)
{
if (!links[i]->checkState()) continue;
int value = outSliders[i]->value();
if (min > value) min = value;
linked_count++;
}
Q_UNUSED(state)
// find the minimum slider value for the linked ones
int min = 10000;
int linked_count = 0;
for (int i = 0; i < outSliders.count(); i++)
{
if (!links[i]->checkState()) continue;
int value = outSliders[i]->value();
if (min > value) min = value;
linked_count++;
}
if (linked_count <= 0)
return; // no linked channels
if (linked_count <= 0)
return; // no linked channels
if (!m_config->channelOutTest->checkState())
return; // we are not in Test Output mode
if (!m_config->channelOutTest->checkState())
return; // we are not in Test Output mode
// set the linked channels to the same value
for (int i = 0; i < outSliders.count(); i++)
{
if (!links[i]->checkState()) continue;
outSliders[i]->setValue(min);
}
// set the linked channels to the same value
for (int i = 0; i < outSliders.count(); i++)
{
if (!links[i]->checkState()) continue;
outSliders[i]->setValue(min);
}
}
/**
@ -237,7 +196,7 @@ void ConfigOutputWidget::runChannelTests(bool state)
// Confirm this is definitely what they want
if(state) {
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);
int retval = mbox.exec();
if(retval != QMessageBox::Yes) {
@ -396,7 +355,7 @@ void ConfigOutputWidget::sendChannelTest(int value)
/**
Request the current config from the board (RC Output)
*/
void ConfigOutputWidget::requestRCOutputUpdate()
void ConfigOutputWidget::refreshValues()
{
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
@ -534,11 +493,9 @@ void ConfigOutputWidget::saveRCOutputObject()
{
// Send update so that the latest value is saved
sendRCOutputUpdate();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings")));
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
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.
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
is changed, then keep it on the max/min.
One added trick: if the slider is at its min when the value
is changed, then keep it on the min.
*/
void ConfigOutputWidget::setChOutRange()
{
@ -561,7 +518,7 @@ void ConfigOutputWidget::setChOutRange()
QSlider *slider = outSliders[index];
int oldMini = slider->minimum();
int oldMaxi = slider->maximum();
// int oldMaxi = slider->maximum();
if (outMin[index]->value()<outMax[index]->value())
{

View File

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

View File

@ -42,15 +42,18 @@ ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTa
m_stabilization = new Ui_StabilizationWidget();
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->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
// 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)
{
if (m_stabilization->linkRateRP->isChecked()) {
@ -178,9 +187,11 @@ void ConfigStabilizationWidget::updatePitchILimit(double val)
/**
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();
// Now fill in all the fields, this is fairly tedious:
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
sendStabilizationUpdate();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("StabilizationSettings")));
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("StabilizationSettings")));
Q_ASSERT(obj);
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj);
saveObjectToSD(obj);
}
void ConfigStabilizationWidget::realtimeUpdateToggle(bool state)
{
if (state)
if (state) {
updateTimer.start(300);
else
} else {
updateTimer.stop();
}
}
void ConfigStabilizationWidget::openHelp()

View File

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

View File

@ -30,8 +30,6 @@
ConfigTaskWidget::ConfigTaskWidget(QWidget *parent) : QWidget(parent)
{
saveState = IDLE;
queue.clear();
}
ConfigTaskWidget::~ConfigTaskWidget()
@ -41,100 +39,13 @@ ConfigTaskWidget::~ConfigTaskWidget()
void ConfigTaskWidget::saveObjectToSD(UAVObject *obj)
{
// Add to queue
queue.enqueue(obj);
// If queue length is one, then start sending (call sendNextObject)
// Otherwise, do nothing, it's sending anyway
if (queue.length()==1)
saveNextObject();
// saveObjectToSD is now handled by the UAVUtils plugin in one
// central place (and one central queue)
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectUtilManager* utilMngr = pm->getObject<UAVObjectUtilManager>();
utilMngr->saveObjectToSD(obj);
}
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() {
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
@ -151,6 +62,21 @@ double ConfigTaskWidget::listMean(QList<double> list)
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 "uavobjectmanager.h"
#include "uavobject.h"
#include "objectpersistence.h"
#include "uavobjectutilmanager.h"
#include <QQueue>
#include <QtGui/QWidget>
#include <QList>
@ -45,20 +45,18 @@ public:
ConfigTaskWidget(QWidget *parent = 0);
~ConfigTaskWidget();
void saveObjectToSD(UAVObject *obj);
void updateObjectPersistance(ObjectPersistence::OperationOptions op, UAVObject *obj);
UAVObjectManager* getObjectManager();
static double listMean(QList<double> list);
public slots:
void onAutopilotDisconnect();
void onAutopilotConnect();
private slots:
void objectPersistenceTransactionCompleted(UAVObject* obj, bool success);
void objectPersistenceUpdated(UAVObject * obj);
virtual void refreshValues() = 0;
private:
QQueue<UAVObject*> queue;
void saveNextObject();
enum {IDLE, AWAITING_ACK, AWAITING_COMPLETED} saveState;
virtual void enableControls(bool enable) = 0;
};

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>557</width>
<height>462</height>
<height>467</height>
</rect>
</property>
<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>
</property>
<property name="text">
<string>1000</string>
<string>1500</string>
</property>
</widget>
</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>
</property>
<property name="text">
<string>1000</string>
<string>1500</string>
</property>
</widget>
</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>
</property>
<property name="text">
<string>1000</string>
<string>1500</string>
</property>
</widget>
</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>
</property>
<property name="text">
<string>1000</string>
<string>1500</string>
</property>
</widget>
</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>
</property>
<property name="text">
<string>1000</string>
<string>1500</string>
</property>
</widget>
</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>
</property>
<property name="text">
<string>1000</string>
<string>1500</string>
</property>
</widget>
</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>
</property>
<property name="text">
<string>1000</string>
<string>1500</string>
</property>
</widget>
</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>
</property>
<property name="text">
<string>1000</string>
<string>1500</string>
</property>
</widget>
</item>
@ -1406,16 +1406,6 @@ if you have not done so already.</string>
</property>
</widget>
</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>
<widget class="QPushButton" name="saveRCInputToRAM">
<property name="toolTip">
@ -1470,5 +1460,134 @@ Applies and Saves all settings to SD</string>
<resources>
<include location="../coreplugin/core.qrc"/>
</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>

View File

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

View File

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

View File

@ -22,108 +22,98 @@
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<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">
<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;
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QTextBrowser" name="textBrowser">
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;Set the serial speed of your onboard telemetry modem here. It is the speed between the OpenPilot board and the onboard modem, and could be different from the radio link speed.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans'; font-size:10pt;&quot;&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;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>
</widget>
<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">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Telemetry speed:</string>
</property>
</widget>
<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">
<string>Select the speed here.</string>
</property>
</widget>
<widget class="QPushButton" name="saveTelemetryToRAM">
<property name="geometry">
<rect>
<x>190</x>
<y>280</y>
<width>93</width>
<height>27</height>
</rect>
</property>
<property name="toolTip">
<string>Send to OpenPilot but don't write in SD.
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Telemetry speed:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="telemetrySpeed">
<property name="toolTip">
<string>Select the speed here.</string>
</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>
<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">
<string>Send to OpenPilot but don't write in SD.
Beware of not locking yourself out!</string>
</property>
<property name="text">
<string>Apply</string>
</property>
</widget>
<widget class="QPushButton" name="getTelemetryCurrent">
<property name="geometry">
<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">
<property name="geometry">
<rect>
<x>300</x>
<y>280</y>
<width>93</width>
<height>27</height>
</rect>
</property>
<property name="toolTip">
<string>Applies and Saves all settings to SD.
</property>
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="saveTelemetryToSD">
<property name="toolTip">
<string>Applies and Saves all settings to SD.
Beware of not locking yourself out!</string>
</property>
<property name="text">
<string>Save</string>
</property>
</widget>
</property>
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,7 +23,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel</set>
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</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);
ui->setupUi(this);
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"));
}
ImportExportGadgetWidget::~ImportExportGadgetWidget()
@ -70,17 +69,22 @@ void ImportExportGadgetWidget::changeEvent(QEvent *e)
break;
}
}
void ImportExportGadgetWidget::loadConfiguration(const ImportExportGadgetConfiguration* config)
{
if ( !config )
return;
ui->configFile->setPath(config->getIniFile());
}
void ImportExportGadgetWidget::on_exportButton_clicked()
{
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();
if ( QFileInfo(file).exists() ){
@ -133,18 +137,7 @@ void ImportExportGadgetWidget::exportConfiguration(const QString& fileName)
bool doAllGadgets = ui->checkBoxAllGadgets->isChecked();
bool doPlugins = ui->checkBoxPlugins->isChecked();
QSettings::Format format;
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::Format format = XmlConfig::XmlSettingsFormat;
QSettings qs(fileName, format);
if (doGeneral) {
@ -193,19 +186,7 @@ void ImportExportGadgetWidget::importConfiguration(const QString& fileName)
bool doAllGadgets = ui->checkBoxAllGadgets->isChecked();
bool doPlugins = ui->checkBoxPlugins->isChecked();
QSettings::Format format;
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, XmlConfig::XmlSettingsFormat);
if ( doAllGadgets ) {
Core::ICore::instance()->uavGadgetInstanceManager()->readSettings(&qs);

View File

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

View File

@ -82,8 +82,50 @@
</item>
<item row="2" column="0" colspan="2">
<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="exportButton">
<property name="toolTip">
<string>Export the GCS settings selected in the checkboxes above.</string>
</property>
<property name="text">
<string>Export</string>
</property>
@ -91,6 +133,9 @@
</item>
<item>
<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">
<string>Import</string>
</property>
@ -98,46 +143,16 @@
</item>
<item>
<widget class="QPushButton" name="resetButton">
<property name="toolTip">
<string>Resets your GCS configuration to its default configuration.</string>
</property>
<property name="text">
<string>Reset Config</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="helpButton">
<property name="text">
<string>Help</string>
</property>
</widget>
</item>
</layout>
</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>
</widget>
<customwidgets>
@ -148,6 +163,8 @@
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<resources>
<include location="../coreplugin/core.qrc"/>
</resources>
<connections/>
</ui>

View File

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

View File

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

View File

@ -41,6 +41,11 @@
UAVObjectUtilManager::UAVObjectUtilManager()
{
mutex = new QMutex(QMutex::Recursive);
saveState = IDLE;
failureTimer.stop();
failureTimer.setSingleShot(true);
failureTimer.setInterval(1000);
connect(&failureTimer, SIGNAL(timeout()),this,SLOT(objectPersistenceOperationFailed()));
}
UAVObjectUtilManager::~UAVObjectUtilManager()
@ -58,64 +63,154 @@ UAVObjectUtilManager::~UAVObjectUtilManager()
}
}
UAVObjectManager* UAVObjectUtilManager::getObjectManager() {
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager * objMngr = pm->getObject<UAVObjectManager>();
Q_ASSERT(objMngr);
return objMngr;
}
// ******************************
// SD card saving
//
/*
Add a new object to save in the queue
*/
void UAVObjectUtilManager::saveObjectToSD(UAVObject *obj)
{
QMutexLocker locker(mutex);
// Add to queue
queue.enqueue(obj);
qDebug() << "Enqueue object: " << obj->getName();
if (!obj) return;
// Add to queue
queue.enqueue(obj);
// If queue length is one, then start sending (call sendNextObject)
// Otherwise, do nothing, it's sending anyway
if (queue.length()==1)
saveNextObject();
// If queue length is one, then start sending (call sendNextObject)
// Otherwise, do nothing, it's sending anyway
if (queue.length() <= 1)
saveNextObject();
}
void UAVObjectUtilManager::saveNextObject()
{
if (queue.isEmpty()) return;
if ( queue.isEmpty() )
{
return;
}
// Get next object from the queue
UAVObject *obj = queue.head();
if (!obj) return;
Q_ASSERT(saveState == IDLE);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
if (!pm) return;
// Get next object from the queue
UAVObject* obj = queue.head();
qDebug() << "Request board to save object " << obj->getName();
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::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();
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();
}
// 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);
QMutexLocker locker(mutex);
if (!obj) return;
// Disconnect from sending object
obj->disconnect(this);
queue.dequeue(); // We can now remove the object, it's done.
saveNextObject();
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();
}
}
/**
* @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();
}
}
/**
* @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);
queue.dequeue(); // We can now remove the object, it's done.
saveState = IDLE;
emit saveCompleted(obj->getField("ObjectID")->getValue().toInt(), true);
saveNextObject();
}
}
/**
* Get the UAV Board model, for anyone interested. Return format is:
* (Board Type << 8) + BoardRevision.

View File

@ -38,6 +38,7 @@
#include <QtGlobal>
#include <QObject>
#include <QTimer>
#include <QMutex>
#include <QQueue>
#include <QComboBox>
@ -63,17 +64,25 @@ public:
int getBoardModel();
QByteArray getBoardCPUSerial();
QString getBoardDescription();
UAVObjectManager* getObjectManager();
void saveObjectToSD(UAVObject *obj);
signals:
void saveCompleted(int objectID, bool status);
private:
QMutex *mutex;
QQueue<UAVObject *> queue;
enum {IDLE, AWAITING_ACK, AWAITING_COMPLETED} saveState;
void saveNextObject();
void saveObjectToSD(UAVObject *obj);
QTimer failureTimer;
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
*/
/*
* TODO:
* - write import functions
* - split formats into different files/classes
* - better error handling (not a lot of QMessageBoxes)
*/
#include "uavsettingsimportexport.h"
#include <QtPlugin>
#include <QStringList>
#include <QDebug>
#include <QCheckBox>
// for menu item
#include <coreplugin/coreconstants.h>
@ -74,20 +69,22 @@ bool UAVSettingsImportExportPlugin::initialize(const QStringList& args, QString
Core::ActionManager* am = Core::ICore::instance()->actionManager();
Core::ActionContainer* ac = am->actionContainer(Core::Constants::M_FILE);
Core::Command* cmd = am->registerAction(new QAction(this),
"UAVSettingsImportExportPlugin.UAVSettingsImportExport",
"UAVSettingsImportExportPlugin.UAVSettingsExport",
QList<int>() <<
Core::Constants::C_GLOBAL_ID);
cmd->setDefaultKeySequence(QKeySequence("Ctrl+E"));
cmd->setDefaultKeySequence(QKeySequence("Ctrl+E"));
cmd->action()->setText(tr("Export UAV Settings..."));
ac->addAction(cmd, Core::Constants::G_FILE_SAVE);
connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(exportUAVSettings()));
// 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);
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;
}
@ -97,40 +94,129 @@ void UAVSettingsImportExportPlugin::extensionsInitialized()
// 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 filters = tr("UAV Settings files (*.uav)")
+ ";;" + tr("Simple XML files (*.xml)")
+ ";;" + tr("INI files (*.ini)");
QString filters = tr("UAVSettings XML files (*.uav);; XML files (*.xml)");
fileName = QFileDialog::getOpenFileName(0, tr("Import UAV Settings"), "", filters);
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);
if (fileName.isEmpty()) {
return;
}
// check export file format
QFileInfo fileInfo(fileName);
QString fileType = fileInfo.suffix().toLower();
if (fileType == "uav") {
fileFormat = 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;
bool fullExport = false;
// If the filename ends with .xml, we will do a full export, otherwise, a simple export
if (fileName.endsWith(".xml")) {
fullExport = true;
} else if (!fileName.endsWith(".uav")) {
fileName.append(".uav");
}
// 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");
o.setAttribute("name", obj->getName());
o.setAttribute("id", QString("0x")+ QString().setNum(obj->getObjID(),16).toUpper());
if (fileFormat == UAV) {
if (fullExport) {
QDomElement d = doc.createElement("description");
QDomText t = doc.createTextNode(obj->getDescription().remove("@Ref ", Qt::CaseInsensitive));
d.appendChild(t);
@ -175,7 +261,7 @@ void UAVSettingsImportExportPlugin::importExport()
f.setAttribute("name", field->getName());
f.setAttribute("values", vals);
if (fileFormat == UAV) {
if (fullExport) {
f.setAttribute("type", field->getTypeAsString());
f.setAttribute("units", field->getUnits());
f.setAttribute("elements", nelem);
@ -189,48 +275,23 @@ void UAVSettingsImportExportPlugin::importExport()
}
}
}
// save file
if ((fileFormat == UAV) || (fileFormat == XML)) {
QFile file(fileName);
if (file.open(QIODevice::WriteOnly) &&
(file.write(doc.toString(4).toAscii()) != -1)) {
file.close();
} else {
QMessageBox::critical(0,
tr("UAV Settings Export"),
tr("Unable to save settings: ") + fileName,
QMessageBox::Ok);
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);
QDomElement docElem = doc.documentElement();
QDomNodeList nodeList = docElem.elementsByTagName("object");
for (int i = 0; i < nodeList.count(); i++) {
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();
}
}
QFile file(fileName);
if (file.open(QIODevice::WriteOnly) &&
(file.write(doc.toString(4).toAscii()) != -1)) {
file.close();
} else {
QMessageBox::critical(0,
tr("UAV Settings Export"),
tr("Unable to save settings: ") + fileName,
QMessageBox::Ok);
return;
}
QMessageBox msgBox;
msgBox.setText(tr("Settings saved."));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.exec();
}
void UAVSettingsImportExportPlugin::shutdown()

View File

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

View File

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

View File

@ -1,13 +1,18 @@
TEMPLATE = lib
QT += xml
TARGET = UAVSettingsImportExport
include(../../openpilotgcsplugin.pri)
include(uavsettingsimportexport_dependencies.pri)
HEADERS += uavsettingsimportexport.h
SOURCES += uavsettingsimportexport.cpp
OTHER_FILES += uavsettingsimportexport.pluginspec
TEMPLATE = lib
QT += xml
TARGET = UAVSettingsImportExport
include(../../openpilotgcsplugin.pri)
include(uavsettingsimportexport_dependencies.pri)
HEADERS += uavsettingsimportexport.h \
importsummary.h
SOURCES += uavsettingsimportexport.cpp \
importsummary.cpp
OTHER_FILES += uavsettingsimportexport.pluginspec
FORMS += \
importsummarydialog.ui

View File

@ -1,2 +1,3 @@
include(../../plugins/coreplugin/coreplugin.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="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="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="YawBiasRate" units="channel" type="float" elements="1" defaultvalue="0.000001"/>
<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">
<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="Roll" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="Channel1"/>
<field name="Pitch" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="Channel2"/>
<field name="Yaw" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="Channel3"/>
<field name="Throttle" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="Channel4"/>
<field name="FlightMode" units="channel" type="enum" elements="1" options="Channel1,Channel2,Channel3,Channel4,Channel5,Channel6,Channel7,Channel8,None" defaultvalue="Channel5"/>
<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="None"/>
<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="None"/>
<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="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"/>