diff options
author | Jakob Odersky <jodersky@gmail.com> | 2014-12-18 11:57:54 +0100 |
---|---|---|
committer | Jakob Odersky <jodersky@gmail.com> | 2014-12-18 12:01:32 +0100 |
commit | 82ae4b18a62e949e7280afbaa5dde90d613c4ce6 (patch) | |
tree | ea5dc7eebaa055a493129bf76e0f1361b3dd5552 | |
parent | 5f16695c3b1c13840d0c4dc6a1dfb4adbee4e836 (diff) | |
download | mavigator-82ae4b18a62e949e7280afbaa5dde90d613c4ce6.tar.gz mavigator-82ae4b18a62e949e7280afbaa5dde90d613c4ce6.tar.bz2 mavigator-82ae4b18a62e949e7280afbaa5dde90d613c4ce6.zip |
cleanup and tweaks
-rw-r--r-- | vfd-backend/app/controllers/Application.scala | 9 | ||||
-rw-r--r-- | vfd-backend/conf/application.conf | 2 | ||||
-rw-r--r-- | vfd-backend/public/images/instruments/bar.svg | 175 | ||||
-rw-r--r-- | vfd-uav/src/main/scala/vfd/uav/MockConnection.scala | 37 | ||||
-rw-r--r-- | vfd-uav/src/main/scala/vfd/uav/SerialConnection.scala | 23 |
5 files changed, 211 insertions, 35 deletions
diff --git a/vfd-backend/app/controllers/Application.scala b/vfd-backend/app/controllers/Application.scala index 6739d3c..09e0e0d 100644 --- a/vfd-backend/app/controllers/Application.scala +++ b/vfd-backend/app/controllers/Application.scala @@ -10,13 +10,8 @@ import play.api.libs.json._ import plugins.UavPlugin object Application extends Controller { - - def use[A <: Plugin](implicit app: Application, m: Manifest[A]) = { - app.plugin[A].getOrElse(throw new RuntimeException(m.runtimeClass.toString + " plugin should be available at this point")) - } - - def uav = use[UavPlugin] + private def uav = current.plugin[UavPlugin].getOrElse(throw new RuntimeException("UAV plugin is not available")) def index = Action { implicit request => Redirect(routes.Application.uav(0)) @@ -27,7 +22,7 @@ object Application extends Controller { } def mavlink = WebSocket.acceptWithActor[Array[Byte], Array[Byte]] { implicit request => - out => use[UavPlugin].register(out) + out => uav.register(out) } }
\ No newline at end of file diff --git a/vfd-backend/conf/application.conf b/vfd-backend/conf/application.conf index e069b23..cecd0f9 100644 --- a/vfd-backend/conf/application.conf +++ b/vfd-backend/conf/application.conf @@ -69,7 +69,7 @@ uav.system_id=1 # Type of connection to use # 'mock' for a sample connection -uav.connection.type=serial +uav.connection.type=mock # Mavlink component id used by this connection (not the web frontend), # in case it needs to inject messages diff --git a/vfd-backend/public/images/instruments/bar.svg b/vfd-backend/public/images/instruments/bar.svg new file mode 100644 index 0000000..03d311a --- /dev/null +++ b/vfd-backend/public/images/instruments/bar.svg @@ -0,0 +1,175 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns: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="voltage.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" /> + <clipPath + clipPathUnits="userSpaceOnUse" + id="clipPath3111"> + <rect + y="-48.5" + x="-3.5" + height="97" + width="29" + id="rect3113" + style="fill:#00ffff;fill-opacity:1;stroke:none" + ry="3.5" /> + </clipPath> + </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="86.541936" + inkscape:cy="51.30932" + 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="true"> + <inkscape:grid + type="xygrid" + id="grid4395" + units="px" + empspacing="5" + visible="true" + enabled="true" + snapvisiblegridlinesonly="true" + spacingx="1px" + spacingy="1px" /> + </sodipodi:namedview> + <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 /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="labels"> + <text + sodipodi:linespacing="125%" + id="text5104" + y="0.71679688" + x="-29.029297" + 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"><tspan + y="0.71679688" + x="-29.029297" + id="value" + sodipodi:role="line">0</tspan></text> + <text + sodipodi:linespacing="125%" + id="text5106" + y="12.33289" + x="-29.03418" + 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"><tspan + y="12.33289" + x="-29.03418" + id="unit" + sodipodi:role="line">%</tspan></text> + </g> + <rect + style="fill:#00ff00;fill-opacity:1;stroke:none" + id="level" + width="29" + height="97" + x="-3.5" + y="-48.5" + clip-path="url(#clipPath3111)" /> + <g + id="fixed"> + <path + id="rect3022" + transform="translate(-50,-50)" + d="m 50,0 c -2.77,0 -5,2.23 -5,5 l 0,90 c 0,2.77 2.23,5 5,5 l 22,0 c 2.77,0 5,-2.23 5,-5 L 77,5 C 77,2.23 74.77,0 72,0 L 50,0 z m 0,1.5 22,0 c 1.939,0 3.5,1.561 3.5,3.5 l 0,90 c 0,1.939 -1.561,3.5 -3.5,3.5 l -22,0 c -1.939,0 -3.5,-1.561 -3.5,-3.5 l 0,-90 c 0,-1.939 1.561,-3.5 3.5,-3.5 z" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + inkscape:connector-curvature="0" /> + <rect + ry="4.2188474e-16" + y="-1" + x="-5" + height="2" + width="8" + id="rect3042" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" /> + <rect + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + id="rect3046" + width="8" + height="1" + x="-5" + y="-25.5" + ry="2.1094237e-16" /> + <rect + ry="2.1094237e-16" + y="24.5" + x="-5" + height="1" + width="8" + id="rect3048" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" /> + <rect + ry="2.1094237e-16" + y="-25.5" + x="19" + height="1" + width="8" + id="rect3054" + style="fill:#1a1a1a;fill-opacity:1;stroke:none" /> + <rect + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + id="rect3056" + width="8" + height="2" + x="19" + y="-1" + ry="4.2188474e-16" /> + <rect + style="fill:#1a1a1a;fill-opacity:1;stroke:none" + id="rect3058" + width="8" + height="1" + x="19" + y="24.5" + ry="2.1094237e-16" /> + </g> +</svg> diff --git a/vfd-uav/src/main/scala/vfd/uav/MockConnection.scala b/vfd-uav/src/main/scala/vfd/uav/MockConnection.scala index d427aef..1217291 100644 --- a/vfd-uav/src/main/scala/vfd/uav/MockConnection.scala +++ b/vfd-uav/src/main/scala/vfd/uav/MockConnection.scala @@ -15,11 +15,11 @@ class MockConnection extends Actor with ActorLogging with Connection { import Connection._ import context._ - val messageInterval = FiniteDuration(500, MILLISECONDS) + val messageInterval = FiniteDuration(250, MILLISECONDS) override def preStart() = { context.system.scheduler.schedule(messageInterval, messageInterval) { - val data = MockPackets.random() + val data = MockPackets.random this.log.debug("sending mock flight data: " + data.mkString("(", ",", ")")) sendAll(Received(ByteString(data))) @@ -42,26 +42,31 @@ object MockPackets { 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 - } - + + def messages = Heartbeat(0) :: + Motor(Random.nextInt(101).toByte, Random.nextInt(101).toByte, Random.nextInt(101).toByte, Random.nextInt(101).toByte) :: + Attitude((Random.nextInt(160) - 80).toShort, (Random.nextInt(160) - 80).toShort.toShort, Random.nextInt(360).toShort) :: + Power(Random.nextInt(12000).toShort) :: Nil + + def valid: Array[Byte] = messages.flatMap(_.bytes).toArray + val invalidCrc = Array(254, 1, 123, 13, 13).map(_.toByte) val invalidOverflow = { - val data = Array.fill[Byte](1006)(42) + val data = Array.fill[Byte](Packet.MaxPayloadLength + 10)(42) data(0) = -2 data(1) = 2 data(1) = -1 data } + + def randomInvalid = Random.nextInt(2) match { + case 0 => invalidCrc + case 1 => invalidOverflow + } + def random: Array[Byte] = if (Random.nextInt(5) == 0) { + randomInvalid + } else { + valid + } }
\ No newline at end of file diff --git a/vfd-uav/src/main/scala/vfd/uav/SerialConnection.scala b/vfd-uav/src/main/scala/vfd/uav/SerialConnection.scala index 857169e..4a1e62f 100644 --- a/vfd-uav/src/main/scala/vfd/uav/SerialConnection.scala +++ b/vfd-uav/src/main/scala/vfd/uav/SerialConnection.scala @@ -4,7 +4,9 @@ import java.util.concurrent.TimeUnit.MILLISECONDS import scala.concurrent.duration.FiniteDuration +import org.mavlink.Packet import org.mavlink.Parser +import org.mavlink.messages.Heartbeat import org.mavlink.messages.Message import com.github.jodersky.flow.Parity @@ -23,13 +25,15 @@ import akka.util.ByteString class SerialConnection(id: Byte, heartbeat: Option[FiniteDuration], port: String, settings: SerialSettings) extends Actor with ActorLogging with Connection { import context._ - val Heartbeat = ByteString( - Array(-2, 9, -121, 20, -56, 0, 0, 0, 0, 0, 2, 0, 0, 3, 3, -112, 76).map(_.toByte)) + lazy val hb = { + val (id, payload) = Message.pack(Heartbeat(0)) + Packet(5, 42, 1, id, payload).toSeq.toArray + } override def preStart() = { heartbeat foreach { interval => context.system.scheduler.schedule(interval, interval) { - self ! Connection.Send(Heartbeat) + self ! Connection.Send(ByteString(hb)) } } } @@ -58,7 +62,7 @@ class SerialConnection(id: Byte, heartbeat: Option[FiniteDuration], port: String context become opened(sender) case Connection.Send(_) => () // ignore - /* + /* * During opening, any outgoing messages are discarded. * By using some kind of message stashing, maybe messages could be treated * once the port has been opened. However, in such a case failure also needs @@ -68,14 +72,11 @@ class SerialConnection(id: Byte, heartbeat: Option[FiniteDuration], port: String */ } - - val last = new collection.mutable.Queue[Int] - - val parser = new Parser(pckt => + + val parser = new Parser(pckt => { println("Received message: " + Message.unpack(pckt.messageId, pckt.payload)) - ) - - + }) + def _opened(operator: ActorRef): Receive = { case Terminated(`operator`) => |