diff options
author | Jakob Odersky <jodersky@gmail.com> | 2014-12-16 18:24:55 +0100 |
---|---|---|
committer | Jakob Odersky <jodersky@gmail.com> | 2014-12-16 18:24:55 +0100 |
commit | 937bec66df1a3edfe819fb68e3ad85f60f92c1bb (patch) | |
tree | 031d9ee53834adb03afad8992c846a31d7619d04 | |
parent | 458971f834a3af0dbf2fffe527352fa11e7d8168 (diff) | |
download | mavigator-937bec66df1a3edfe819fb68e3ad85f60f92c1bb.tar.gz mavigator-937bec66df1a3edfe819fb68e3ad85f60f92c1bb.tar.bz2 mavigator-937bec66df1a3edfe819fb68e3ad85f60f92c1bb.zip |
add animations and reenable showing messages
-rw-r--r-- | concise.xml | 13 | ||||
-rw-r--r-- | vfd-backend/public/images/instruments/altimeter.svg (renamed from vfd-backend/public/images/instruments/altitude.svg) | 0 | ||||
-rw-r--r-- | vfd-backend/public/images/instruments/basic.svg | 313 | ||||
-rw-r--r-- | vfd-backend/public/images/instruments/compass.svg (renamed from vfd-backend/public/images/instruments/heading.svg) | 0 | ||||
-rw-r--r-- | vfd-backend/public/images/instruments/horizon.svg (renamed from vfd-backend/public/images/instruments/attitude.svg) | 28 | ||||
-rw-r--r-- | vfd-frontend/src/main/scala/vfd/frontend/Main.scala | 3 | ||||
-rw-r--r-- | vfd-frontend/src/main/scala/vfd/frontend/ui/Components.scala | 62 | ||||
-rw-r--r-- | vfd-frontend/src/main/scala/vfd/frontend/ui/panels/Communication.scala | 27 | ||||
-rw-r--r-- | vfd-frontend/src/main/scala/vfd/frontend/ui/panels/Primary.scala | 12 | ||||
-rw-r--r-- | vfd-uav/src/main/scala/vfd/uav/MockConnection.scala | 20 |
10 files changed, 430 insertions, 48 deletions
diff --git a/concise.xml b/concise.xml index 9be16f7..4d8d174 100644 --- a/concise.xml +++ b/concise.xml @@ -66,6 +66,19 @@ <field type="uint8_t" name="target_system">System ID</field> <field type="uint8_t" name="target_component">Component ID</field> </message> + <message name="MOTOR" id="6"> + <description>Status of motors</description> + <field type="uint8_t" name="m0">m0</field> + <field type="uint8_t" name="m1">m1</field> + <field type="uint8_t" name="m2">m2</field> + <field type="uint8_t" name="m3">m3</field> + </message> + <message id="30" name="ATTITUDE"> + <description>The attitude in the aeronautical frame (right-handed, Z-down, X-front, Y-right).</description> + <field type="int16_t" name="roll">Roll angle</field> + <field type="int16_t" name="pitch">Pitch angle</field> + <field type="uint16_t" name="yaw">Yaw angle</field> + </message> <message id="70" name="RC_CHANNELS_OVERRIDE"> <description>The RAW values of the RC channels sent to the MAV to override info received from the RC radio. A value of UINT16_MAX means no change to that channel. A value of 0 means control of that channel should be released back to the RC radio. The standard PPM modulation is as follows: 1000 microseconds: 0%, 2000 microseconds: 100%. Individual receivers/transmitters might violate this specification.</description> <field type="uint8_t" name="target_system">System ID</field> diff --git a/vfd-backend/public/images/instruments/altitude.svg b/vfd-backend/public/images/instruments/altimeter.svg index 2bfb306..2bfb306 100644 --- a/vfd-backend/public/images/instruments/altitude.svg +++ b/vfd-backend/public/images/instruments/altimeter.svg diff --git a/vfd-backend/public/images/instruments/basic.svg b/vfd-backend/public/images/instruments/basic.svg new file mode 100644 index 0000000..7712ece --- /dev/null +++ b/vfd-backend/public/images/instruments/basic.svg @@ -0,0 +1,313 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg:svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="100" + height="100" + id="svg4387" + version="1.1" + inkscape:version="0.48.5 r10040" + viewBox="-50 -50 100 100" + sodipodi:docname="thin.svg"> + <svg:defs + id="defs4389"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 50 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="100 : 50 : 1" + inkscape:persp3d-origin="50 : 33.333333 : 1" + id="perspective5114" /> + </svg:defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="5.6568542" + inkscape:cx="64.85138" + inkscape:cy="31.918663" + inkscape:document-units="px" + inkscape:current-layer="svg4387" + showgrid="true" + showguides="false" + inkscape:snap-bbox="true" + inkscape:window-width="1920" + inkscape:window-height="1029" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:snap-grids="false"> + <inkscape:grid + type="xygrid" + id="grid4395" + units="px" + empspacing="5" + visible="true" + enabled="true" + snapvisiblegridlinesonly="true" + spacingx="1px" + spacingy="1px" /> + </sodipodi:namedview> + <svg:metadata + id="metadata4392"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </svg:metadata> + <svg:g + id="lower"> + <svg:path + inkscape:transform-center-y="44.418149" + inkscape:transform-center-x="11.044759" + inkscape:connector-curvature="0" + id="path5010" + d="m -0.52403983,48.510133 0.0154511,-3.487667 C -7.2448512,44.942356 -13.911142,43.340039 -19.989534,40.326163 l -1.591395,3.126201 c 6.563792,3.254436 13.7823459,4.974145 21.05688917,5.057769 z" + style="fill:#00d400;fill-opacity:1;stroke:none" /> + <svg:path + inkscape:transform-center-y="-24.174304" + inkscape:transform-center-x="39.074649" + inkscape:connector-curvature="0" + id="path5002" + d="m -45.973942,-15.488849 3.312195,1.092444 c 2.157808,-6.381812 5.741699,-12.226687 10.486391,-17.076243 l -2.481425,-2.479556 c -5.123476,5.236862 -8.989672,11.570695 -11.317161,18.463355 z" + style="fill:#00d400;fill-opacity:1;stroke:none" /> + <svg:path + style="fill:#00d400;fill-opacity:1;stroke:none" + d="m -47.994872,7.0710673 3.447146,-0.5303303 c -0.974661,-6.66586045 -0.434908,-13.5007347 1.590991,-19.975766 l -3.336661,-1.082757 c -2.187565,6.9920876 -2.756871,14.39079041 -1.701476,21.5888533 z" + id="path5004" + inkscape:connector-curvature="0" + inkscape:transform-center-x="45.733006" + inkscape:transform-center-y="-3.7233588" /> + <svg:path + inkscape:transform-center-y="17.810418" + inkscape:transform-center-x="42.280768" + inkscape:connector-curvature="0" + id="path5006" + d="m -39.553546,28.089583 2.830664,-2.037499 c -3.894666,-5.496838 -6.516711,-11.831799 -7.651224,-18.5208328 l -3.464548,0.5500689 c 1.225206,7.2231289 4.076892,14.0738809 8.285108,20.0082629 z" + style="fill:#00d400;fill-opacity:1;stroke:none" /> + <svg:path + style="fill:#00d400;fill-opacity:1;stroke:none" + d="m -22.490063,42.984936 1.597135,-3.10052 c -5.965685,-3.129577 -11.177957,-7.583685 -15.225573,-13.0286 l -2.837209,2.062987 c 4.370899,5.879623 10.021946,10.68905 16.465647,14.066133 z" + id="path5008" + inkscape:connector-curvature="0" + inkscape:transform-center-x="29.924319" + inkscape:transform-center-y="34.920377" /> + </svg:g> + <svg:g + id="dial"> + <svg:path + transform="translate(-50,-50)" + id="path4401" + d="M 50,0 C 22.385763,0 0,22.385763 0,50 c 0,27.614237 22.385763,50 50,50 l 0,-1.5 C 23.21419,98.5 1.5,76.78581 1.5,50 1.5,23.21419 23.21419,1.5 50,1.5 76.78581,1.5 98.5,23.21419 98.5,50 l 1.5,0 C 100,22.385763 77.614237,0 50,0 z" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + inkscape:connector-curvature="0" /> + <svg:rect + inkscape:transform-center-y="51.283333" + y="40.5" + x="-1" + height="8.5" + width="2" + id="rect4409" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" /> + <svg:rect + inkscape:transform-center-x="31.996582" + transform="matrix(-0.70710678,0.70710678,-0.70710678,-0.70710678,0,0)" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + id="rect4411" + width="2" + height="7.5" + x="-1" + y="41.5" + inkscape:transform-center-y="-31.996582" /> + <svg:rect + y="41.5" + x="-1.0000002" + height="7.5" + width="2" + id="rect4413" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + transform="matrix(0,-1,1,0,0,0)" + inkscape:transform-center-x="-45.25" /> + <svg:rect + inkscape:transform-center-x="21.110558" + transform="matrix(0.89100652,0.4539905,-0.4539905,0.89100652,0,0)" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + id="rect4961" + width="1" + height="5" + x="-0.5" + y="44" + inkscape:transform-center-y="41.431803" /> + <svg:rect + inkscape:transform-center-y="27.332014" + y="44" + x="-0.49999985" + height="5" + width="1" + id="rect4963" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + transform="matrix(0.58778525,0.809017,-0.809017,0.58778525,0,0)" + inkscape:transform-center-x="37.61929" /> + <svg:rect + inkscape:transform-center-x="45.927507" + transform="matrix(0.15643446,0.98768834,-0.98768834,0.15643446,0,0)" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + id="rect4965" + width="1" + height="5" + x="-0.49999964" + y="44" + inkscape:transform-center-y="7.2742025" /> + <svg:rect + inkscape:transform-center-y="-14.36929" + y="44" + x="-0.49999928" + height="5" + width="1" + id="rect4967" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + transform="matrix(-0.309017,0.95105651,-0.95105651,-0.309017,0,0)" + inkscape:transform-center-x="44.224127" /> + <svg:rect + inkscape:transform-center-x="14.36929" + transform="matrix(-0.95105652,0.30901699,-0.30901699,-0.95105652,0,0)" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + id="rect4969" + width="1" + height="5" + x="-0.49999872" + y="44" + inkscape:transform-center-y="-44.224128" /> + <svg:rect + inkscape:transform-center-y="-45.927508" + y="44" + x="-0.49999878" + height="5" + width="1" + id="rect4971" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + transform="matrix(-0.98768834,-0.15643447,0.15643447,-0.98768834,0,0)" + inkscape:transform-center-x="-7.2742029" /> + <svg:rect + inkscape:transform-center-x="-27.332015" + transform="matrix(-0.80901699,-0.58778526,0.58778526,-0.80901699,0,0)" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + id="rect4973" + width="1" + height="5" + x="-0.49999899" + y="44" + inkscape:transform-center-y="-37.619291" /> + <svg:rect + inkscape:transform-center-y="-21.110559" + y="44" + x="-0.49999952" + height="5" + width="1" + id="rect4975" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + transform="matrix(-0.45399049,-0.89100653,0.89100653,-0.45399049,0,0)" + inkscape:transform-center-x="-41.431805" /> + </svg:g> + <svg:g + id="upper"> + <svg:path + inkscape:transform-center-y="-11.026553" + inkscape:transform-center-x="-44.430044" + inkscape:connector-curvature="0" + id="path4979" + d="m 43.460756,-21.556216 -3.114549,1.5696 c 2.986821,6.038424 4.585579,12.7055669 4.65973,19.48972598 l 3.507943,-0.001321 C 48.433702,-7.8240776 46.68882,-15.036587 43.460756,-21.556216 z" + style="fill:#ff0000;fill-opacity:1;stroke:none" /> + <svg:path + style="fill:#ff0000;fill-opacity:1;stroke:none" + d="m 28.9375,-38.9375 -2.0625,2.8125 c 5.402664,4.024287 9.853987,9.238934 13,15.25 L 43,-22.46875 C 39.602688,-28.959745 34.773576,-34.593978 28.9375,-38.9375 z" + id="path5000" + inkscape:connector-curvature="0" + inkscape:transform-center-x="-34.9375" + inkscape:transform-center-y="-29.90625" /> + </svg:g> + <svg:g + id="labels"> + <svg:text + xml:space="preserve" + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:end;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#4d4d4d;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial" + x="40.52644" + y="3.5468256" + id="text5100" + sodipodi:linespacing="125%"><svg:tspan + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Sans;-inkscape-font-specification:Sans" + sodipodi:role="line" + id="max" + x="40.52644" + y="3.5468256">100</svg:tspan></svg:text> + <svg:text + sodipodi:linespacing="125%" + id="text5102" + y="39.272289" + x="0.0016270902" + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#4d4d4d;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" + xml:space="preserve"><svg:tspan + y="39.272289" + x="0.0016270902" + id="min" + sodipodi:role="line">0</svg:tspan></svg:text> + <svg:text + sodipodi:linespacing="125%" + id="text5104" + y="27.28607" + x="25.962608" + style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#1a1a1a;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" + xml:space="preserve"><svg:tspan + y="27.28607" + x="25.962608" + id="value" + sodipodi:role="line">0</svg:tspan></svg:text> + <svg:text + sodipodi:linespacing="125%" + id="text5106" + y="38.902164" + x="25.957726" + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#4d4d4d;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" + xml:space="preserve"><svg:tspan + y="38.902164" + x="25.957726" + id="unit" + sodipodi:role="line">%</svg:tspan></svg:text> + <svg:text + sodipodi:linespacing="125%" + id="text5108" + y="-20.848358" + x="-28.750261" + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#4d4d4d;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial" + xml:space="preserve"><svg:tspan + y="-20.848358" + x="-28.750261" + id="med" + sodipodi:role="line" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;font-family:Sans;-inkscape-font-specification:Sans">50</svg:tspan></svg:text> + </svg:g> + <svg:g + id="hand"> + <svg:path + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + d="m 48,50 c 0,13.34999 2,42 2,42 0,0 2,-28.65001 2,-42 0,-3 -4,-3 -4,0 z" + id="path5012" + inkscape:connector-curvature="0" + transform="translate(-50,-50)" + sodipodi:nodetypes="scss"/> + </svg:g> +</svg:svg> diff --git a/vfd-backend/public/images/instruments/heading.svg b/vfd-backend/public/images/instruments/compass.svg index 83cf17b..83cf17b 100644 --- a/vfd-backend/public/images/instruments/heading.svg +++ b/vfd-backend/public/images/instruments/compass.svg diff --git a/vfd-backend/public/images/instruments/attitude.svg b/vfd-backend/public/images/instruments/horizon.svg index 09464d1..363b962 100644 --- a/vfd-backend/public/images/instruments/attitude.svg +++ b/vfd-backend/public/images/instruments/horizon.svg @@ -20,17 +20,17 @@ id="defs4"> <clipPath clipPathUnits="userSpaceOnUse" - id="clipPath3999"> + id="clipPath3055"> <path - transform="translate(-55,-55)" - d="M 105,55 A 50,50 0 1 1 5,55 50,50 0 1 1 105,55 z" - sodipodi:ry="50" - sodipodi:rx="50" - sodipodi:cy="55" - sodipodi:cx="55" - id="path4002" + sodipodi:type="arc" style="fill:#00ff00;fill-opacity:1;stroke:none" - sodipodi:type="arc" /> + id="path3057" + sodipodi:cx="55" + sodipodi:cy="55" + sodipodi:rx="50" + sodipodi:ry="50" + d="M 105,55 A 50,50 0 1 1 5,55 50,50 0 1 1 105,55 z" + transform="translate(-55,-55)" /> </clipPath> </defs> <sodipodi:namedview @@ -41,7 +41,7 @@ inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="2.8284271" - inkscape:cx="-34.071266" + inkscape:cx="-19.222023" inkscape:cy="22.322089" inkscape:document-units="px" inkscape:current-layer="layer1" @@ -87,21 +87,21 @@ id="layer1"> <g id="roll" - clip-path="url(#clipPath3999)"> + clip-path="url(#clipPath3055)"> <g id="pitch"> <rect style="fill:#2eccfa;fill-opacity:1;stroke:none" id="rect3861" width="100" - height="100" + height="150" x="-50" - y="-100" /> + y="-150" /> <rect style="fill:#61380b;fill-opacity:1;stroke:none" id="rect3863" width="100" - height="100" + height="150" x="-50" y="0" /> <rect diff --git a/vfd-frontend/src/main/scala/vfd/frontend/Main.scala b/vfd-frontend/src/main/scala/vfd/frontend/Main.scala index 5c22a4b..446d56d 100644 --- a/vfd-frontend/src/main/scala/vfd/frontend/Main.scala +++ b/vfd-frontend/src/main/scala/vfd/frontend/Main.scala @@ -64,7 +64,8 @@ object Main { socket.stats.packets, socket.stats.crcErrors, socket.stats.overflows, - socket.stats.wrongIds)))))) + socket.stats.wrongIds, + message)))))) env.root.appendChild(element.render) } diff --git a/vfd-frontend/src/main/scala/vfd/frontend/ui/Components.scala b/vfd-frontend/src/main/scala/vfd/frontend/ui/Components.scala index a340c15..4c17ecf 100644 --- a/vfd-frontend/src/main/scala/vfd/frontend/ui/Components.scala +++ b/vfd-frontend/src/main/scala/vfd/frontend/ui/Components.scala @@ -1,7 +1,6 @@ package vfd.frontend.ui import org.scalajs.dom.HTMLElement - import rx.Obs import rx.Rx import rx.Rx @@ -19,17 +18,6 @@ import vfd.frontend.util.Environment object Components { - def led(color: Rx[String], size: String)(implicit app: Environment) = { - val elem = `object`(`type` := "image/svg+xml", "data".attr := app.asset("leds/led.svg"), width := size)( - "Error loading image.").render - - Obs(color, skipInitial = true) { - val svg = elem.contentDocument - svg.getElementById("light").setAttribute("fill", color()) - } - elem - } - private def instrument(name: String)(implicit app: Environment) = { val path = app.asset("images/instruments/" + name + ".svg") `object`(`type` := "image/svg+xml", "data".attr := path, width := "100%")( @@ -40,21 +28,34 @@ object Components { div(style := s"width: $size; height: $size; display: inline-block;")( elem) } + + def led(color: Rx[String], size: String)(implicit app: Environment) = { + val elem = `object`(`type` := "image/svg+xml", "data".attr := app.asset("leds/led.svg"), width := size)( + "Error loading image.").render + + Obs(color, skipInitial = true) { + val svg = elem.contentDocument + svg.getElementById("light").setAttribute("fill", color()) + } + elem + } - def attitude(pitchRoll: Rx[(Double, Double)], size: String)(implicit app: Environment) = { - val inst = instrument("attitude") + def horizon(pitchRoll: Rx[(Double, Double)], size: String)(implicit app: Environment) = { + val inst = instrument("horizon") Obs(pitchRoll, skipInitial = true) { val svg = inst.contentDocument val pitch = svg.getElementById("pitch") val roll = svg.getElementById("roll") - pitch.setAttribute("transform", "translate(0, " + pitchRoll()._1 / math.Pi * 180 + ")"); - roll.setAttribute("transform", "rotate(" + pitchRoll()._2 / math.Pi * 180 + ")"); + pitch.style.transition = "transform 250ms ease-out" + roll.style.transition = "transform 250ms ease-out" + pitch.style.transform = "translate(0px, " + pitchRoll()._1 + "px)" + roll.style.transform = "rotate(" + pitchRoll()._2 + "deg)" } frame(inst, size) } - def altitude(value: Rx[Double], size: String)(implicit app: Environment) = { - val inst = instrument("altitude") + def altimeter(value: Rx[Double], size: String)(implicit app: Environment) = { + val inst = instrument("altimeter") Obs(value, skipInitial = true) { val svg = inst.contentDocument // 36deg === 1m @@ -63,14 +64,29 @@ object Components { frame(inst, size) } - def heading(value: Rx[Double], size: String)(implicit app: Environment) = { - val inst = instrument("heading") + def compass(value: Rx[Double], size: String)(implicit app: Environment) = { + val inst = instrument("compass") Obs(value, skipInitial = true) { val svg = inst.contentDocument - // 1deg === 1deg - svg.getElementById("heading").setAttribute("transform", "rotate(" + value() / math.Pi * 180 + ")"); + val heading = svg.getElementById("heading") + heading.style.transition = "transform 250ms ease-out" + heading.style.transform = "rotate(" + value() + "deg)" } frame(inst, size) } + + def basic(value: Rx[Double], size: String)(implicit app: Environment) = { + val inst = instrument("basic") + Obs(value, skipInitial = true) { + val svg = inst.contentDocument + val hand = svg.getElementById("hand") + hand.style.transform = "rotate(" + value() * 270 / 100 + "deg)"; + hand.style.transition = "transform 250ms ease-out" + svg.getElementById("unit").textContent = "%" + svg.getElementById("value").textContent = value().toString + } + frame(inst, size) + } + +} -}
\ No newline at end of file diff --git a/vfd-frontend/src/main/scala/vfd/frontend/ui/panels/Communication.scala b/vfd-frontend/src/main/scala/vfd/frontend/ui/panels/Communication.scala index b93ad27..ba0d490 100644 --- a/vfd-frontend/src/main/scala/vfd/frontend/ui/panels/Communication.scala +++ b/vfd-frontend/src/main/scala/vfd/frontend/ui/panels/Communication.scala @@ -15,10 +15,31 @@ import scalatags.JsDom.all.td import scalatags.JsDom.all.tr import vfd.frontend.util.Environment import vfd.frontend.util.Framework.RxStr +import vfd.frontend.ui.Components +import rx.core.Var +import rx.core.Obs +import org.mavlink.messages._ object Communication { - def apply(packets: Rx[Int], crcs: Rx[Int], overflows: Rx[Int], wrongIds: Rx[Int])(implicit app: Environment) = { + def apply(packets: Rx[Int], crcs: Rx[Int], overflows: Rx[Int], wrongIds: Rx[Int], message: Rx[Message])(implicit app: Environment) = { + + val m0 = Var(0.0) + val m1 = Var(0.0) + val m2 = Var(0.0) + val m3 = Var(0.0) + + Obs(message) { + message() match { + case Motor(_m0, _m1, _m2, _m3) => + m0() = _m0 + m1() = _m1 + m2() = _m2 + m3() = _m3 + case _ => () + } + } + div( "Link Status", table(`class` := "table table-condensed")( @@ -42,7 +63,9 @@ object Communication { td("OFLW"), td(overflows), td("BID"), - td(wrongIds))))) + td(wrongIds)))), + div( + Components.basic(m0, "25%"),Components.basic(m1, "25%"),Components.basic(m2, "25%"),Components.basic(m3, "25%"))) } }
\ No newline at end of file diff --git a/vfd-frontend/src/main/scala/vfd/frontend/ui/panels/Primary.scala b/vfd-frontend/src/main/scala/vfd/frontend/ui/panels/Primary.scala index 738a84a..4517ea0 100644 --- a/vfd-frontend/src/main/scala/vfd/frontend/ui/panels/Primary.scala +++ b/vfd-frontend/src/main/scala/vfd/frontend/ui/panels/Primary.scala @@ -1,7 +1,6 @@ package vfd.frontend.ui.panels -import org.mavlink.messages.Message - +import org.mavlink.messages._ import rx.core.Obs import rx.core.Rx import rx.core.Var @@ -18,14 +17,17 @@ object Primary { Obs(message) { message() match { + case Attitude(roll, pitch, yaw) => + pitchRoll() = (roll, pitch) + heading() = yaw case _ => () } } div( - Components.heading(heading, "33%"), - Components.attitude(pitchRoll, "33%"), - Components.altitude(altitude, "33%")) + Components.compass(heading, "33%"), + Components.horizon(pitchRoll, "33%"), + Components.altimeter(altitude, "33%")) } }
\ No newline at end of file diff --git a/vfd-uav/src/main/scala/vfd/uav/MockConnection.scala b/vfd-uav/src/main/scala/vfd/uav/MockConnection.scala index 126fa9a..d427aef 100644 --- a/vfd-uav/src/main/scala/vfd/uav/MockConnection.scala +++ b/vfd-uav/src/main/scala/vfd/uav/MockConnection.scala @@ -1,15 +1,15 @@ package vfd.uav import java.util.concurrent.TimeUnit.MILLISECONDS - import scala.concurrent.duration.FiniteDuration import scala.util.Random - import Connection.Received import akka.actor.Actor import akka.actor.ActorLogging import akka.actor.Props import akka.util.ByteString +import org.mavlink.messages._ +import org.mavlink.Packet class MockConnection extends Actor with ActorLogging with Connection { import Connection._ @@ -36,7 +36,21 @@ object MockConnection { object MockPackets { - def random() = Random.nextInt(2) match { + private implicit class RichMessage(val message: Message) extends AnyVal { + def bytes: Array[Byte] = { + val (id, payload) = Message.pack(message) + Packet(5, 42, 1, id, payload).toSeq.toArray + } + } + + def random(): Array[Byte] = Random.nextInt(4) match { + case 0 => randomInvalid() + case 1 => Heartbeat(0).bytes + case 2 => Motor(Random.nextInt(101).toByte, Random.nextInt(101).toByte, Random.nextInt(101).toByte, Random.nextInt(101).toByte).bytes + case 3 => Attitude((Random.nextInt(160) - 80).toShort, (Random.nextInt(160) - 80).toShort.toShort, Random.nextInt(360).toShort).bytes + } + + def randomInvalid() = Random.nextInt(2) match { case 0 => invalidCrc case 1 => invalidOverflow } |