aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2014-12-18 11:57:54 +0100
committerJakob Odersky <jodersky@gmail.com>2014-12-18 12:01:32 +0100
commit82ae4b18a62e949e7280afbaa5dde90d613c4ce6 (patch)
treeea5dc7eebaa055a493129bf76e0f1361b3dd5552
parent5f16695c3b1c13840d0c4dc6a1dfb4adbee4e836 (diff)
downloadmavigator-82ae4b18a62e949e7280afbaa5dde90d613c4ce6.tar.gz
mavigator-82ae4b18a62e949e7280afbaa5dde90d613c4ce6.tar.bz2
mavigator-82ae4b18a62e949e7280afbaa5dde90d613c4ce6.zip
cleanup and tweaks
-rw-r--r--vfd-backend/app/controllers/Application.scala9
-rw-r--r--vfd-backend/conf/application.conf2
-rw-r--r--vfd-backend/public/images/instruments/bar.svg175
-rw-r--r--vfd-uav/src/main/scala/vfd/uav/MockConnection.scala37
-rw-r--r--vfd-uav/src/main/scala/vfd/uav/SerialConnection.scala23
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`) =>