aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Odersky <jodersky@gmail.com>2014-12-16 00:09:12 +0100
committerJakob Odersky <jodersky@gmail.com>2014-12-16 00:09:12 +0100
commit458971f834a3af0dbf2fffe527352fa11e7d8168 (patch)
tree226675f8402f2c099cb15b21cab28eb8784f1c96
parent84c641d12187183466df936eaa7c1637d861cf62 (diff)
downloadmavigator-458971f834a3af0dbf2fffe527352fa11e7d8168.tar.gz
mavigator-458971f834a3af0dbf2fffe527352fa11e7d8168.tar.bz2
mavigator-458971f834a3af0dbf2fffe527352fa11e7d8168.zip
generate mavlink files in build
-rw-r--r--concise.xml93
-rw-r--r--project/Build.scala20
-rw-r--r--project/build.properties2
-rw-r--r--project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/Main.scala41
-rw-r--r--project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/Crc.scala24
-rw-r--r--project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/FieldTypes.scala27
-rw-r--r--project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/Name.scala14
-rw-r--r--project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/parsing.scala85
-rw-r--r--project/mavlink-library/src/main/twirl/org/mavlink/Crc.scala.txt (renamed from vfd-mavlink/src/main/scala/org/mavlink/Crc.scala)4
-rw-r--r--project/mavlink-library/src/main/twirl/org/mavlink/Packet.scala.txt59
-rw-r--r--project/mavlink-library/src/main/twirl/org/mavlink/Parser.scala.txt (renamed from vfd-mavlink/src/main/scala/org/mavlink/Parser.scala)16
-rw-r--r--project/mavlink-library/src/main/twirl/org/mavlink/_header.scala.txt5
-rw-r--r--project/mavlink-library/src/main/twirl/org/mavlink/messages/Message.scala.txt70
-rw-r--r--project/mavlink-library/src/main/twirl/org/mavlink/messages/_message_class.scala.txt14
-rw-r--r--project/mavlink-plugin/src/main/scala/com/github/jodersky/sbt/SbtMavlink.scala24
-rw-r--r--project/mavlink-plugin/src/main/scala/com/github/jodersky/sbt/mavlink/MavlinkKeys.scala14
-rw-r--r--project/plugins.sbt7
-rw-r--r--project/project/BuildBuild.scala35
-rw-r--r--project/project/plugins.sbt1
-rw-r--r--vfd-frontend/src/main/scala/org/mavlink/js.scala69
-rw-r--r--vfd-frontend/src/main/scala/vfd/frontend/Main.scala6
-rw-r--r--vfd-frontend/src/main/scala/vfd/frontend/ui/panels/Primary.scala6
-rw-r--r--vfd-mavlink/.classpath9
-rw-r--r--vfd-mavlink/.project13
-rw-r--r--vfd-mavlink/src/main/scala/org/mavlink/Packet.scala75
-rw-r--r--vfd-mavlink/src/main/scala/org/mavlink/enums/SystemStatus.scala30
-rw-r--r--vfd-mavlink/src/main/scala/org/mavlink/messages/message.scala73
-rw-r--r--vfd-mavlink/src/main/scala/org/mavlink/messages/payload.scala19
-rw-r--r--vfd-uav/src/main/scala/org/mavlink/jvm.scala48
-rw-r--r--vfd-uav/src/main/scala/vfd/uav/SerialConnection.scala17
30 files changed, 538 insertions, 382 deletions
diff --git a/concise.xml b/concise.xml
new file mode 100644
index 0000000..9be16f7
--- /dev/null
+++ b/concise.xml
@@ -0,0 +1,93 @@
+<?xml version='1.0'?>
+<mavlink>
+ <version>1</version>
+ <enums>
+ <enum name="MAV_STATE">
+ <entry value="0" name="MAV_STATE_UNINIT">
+ <description>Uninitialized system, state is unknown.</description>
+ </entry>
+ <entry value="1" name="MAV_STATE_BOOT">
+ <description>System is booting up.</description>
+ </entry>
+ <entry value="2" name="MAV_STATE_CALIBRATING">
+ <description>System is calibrating and not flight-ready.</description>
+ </entry>
+ <entry value="3" name="MAV_STATE_STANDBY">
+ <description>System is grounded and on standby. It can be launched any time.</description>
+ </entry>
+ <entry value="4" name="MAV_STATE_ACTIVE">
+ <description>System is active and might be already airborne. Motors are engaged.</description>
+ </entry>
+ <entry value="5" name="MAV_STATE_CRITICAL">
+ <description>System is in a non-normal flight mode. It can however still navigate.</description>
+ </entry>
+ <entry value="6" name="MAV_STATE_EMERGENCY">
+ <description>System is in a non-normal flight mode. It lost control over parts or over the whole airframe. It is in mayday and going down.</description>
+ </entry>
+ <entry value="7" name="MAV_STATE_POWEROFF">
+ <description>System just initialized its power-down sequence, will shut down now.</description>
+ </entry>
+ </enum>
+ </enums>
+ <messages>
+ <message id="0" name="HEARTBEAT">
+ <description>The heartbeat message shows that a system is present and responding.</description>
+ <field type="uint8_t" name="system_state" enum="MAV_STATE">Global state of system.</field>
+ </message>
+ <message id="1" name="POWER">
+ <description>Information about the main power source.</description>
+ <field type="uint16_t" name="voltage">Voltage of the source (mV)</field>
+ </message>
+ <message id="2" name="IMU">
+ <description>The IMU readings in a NED body frame</description>
+ <field type="int32_t" name="xacc">X acceleration (mm/s^2)</field>
+ <field type="int32_t" name="yacc">Y acceleration (mm/s^2)</field>
+ <field type="int32_t" name="zacc">Z acceleration (mm/s^2)</field>
+ <field type="int32_t" name="xgyro">Angular speed around X axis (mrad / sec)</field>
+ <field type="int32_t" name="ygyro">Angular speed around Y axis (mrad / sec)</field>
+ <field type="int32_t" name="zgyro">Angular speed around Z axis (mrad / sec)</field>
+ <field type="int32_t" name="xmag">X Magnetic field (uT)</field>
+ <field type="int32_t" name="ymag">Y Magnetic field (uT)</field>
+ <field type="int32_t" name="zmag">Z Magnetic field (uT)</field>
+ <field type="int32_t" name="alt">Altitude to mean sea level (mm)</field>
+ <field type="uint32_t" name="temperature">Ambient temperature (mK)</field>
+ </message>
+ <message id="3" name="DISTANCE">
+ <description>Information on distance sensors</description>
+ <field type="int16_t" name="relative_alt">Relative altitude to ground (mm)</field>
+ </message>
+ <message name="PING" id="4">
+ <description>Ping a target system, usually used to determine latency.</description>
+ <field type="uint8_t" name="target_system">System ID</field>
+ <field type="uint8_t" name="target_component">Component ID</field>
+ </message>
+ <message name="ACK" id="5">
+ <description>Acknowledgement packet</description>
+ <field type="uint8_t" name="target_system">System ID</field>
+ <field type="uint8_t" name="target_component">Component ID</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>
+ <field type="uint8_t" name="target_component">Component ID</field>
+ <field type="uint16_t" name="chan1_raw">RC channel 1 value, in microseconds. A value of UINT16_MAX means to ignore this field.</field>
+ <field type="uint16_t" name="chan2_raw">RC channel 2 value, in microseconds. A value of UINT16_MAX means to ignore this field.</field>
+ <field type="uint16_t" name="chan3_raw">RC channel 3 value, in microseconds. A value of UINT16_MAX means to ignore this field.</field>
+ <field type="uint16_t" name="chan4_raw">RC channel 4 value, in microseconds. A value of UINT16_MAX means to ignore this field.</field>
+ <field type="uint16_t" name="chan5_raw">RC channel 5 value, in microseconds. A value of UINT16_MAX means to ignore this field.</field>
+ <field type="uint16_t" name="chan6_raw">RC channel 6 value, in microseconds. A value of UINT16_MAX means to ignore this field.</field>
+ <field type="uint16_t" name="chan7_raw">RC channel 7 value, in microseconds. A value of UINT16_MAX means to ignore this field.</field>
+ <field type="uint16_t" name="chan8_raw">RC channel 8 value, in microseconds. A value of UINT16_MAX means to ignore this field.</field>
+ </message>
+ <message name="RADIO_STATUS" id="109">
+ <description>Status generated by radio</description>
+ <field type="uint8_t" name="rssi">local signal strength</field>
+ <field type="uint8_t" name="remrssi">remote signal strength</field>
+ <field type="uint8_t" name="txbuf">how full the tx buffer is as a percentage</field>
+ <field type="uint8_t" name="noise">background noise level</field>
+ <field type="uint8_t" name="remnoise">remote background noise level</field>
+ <field type="uint16_t" name="rxerrors">receive errors</field>
+ <field type="uint16_t" name="fixed">count of error corrected packets</field>
+ </message>
+ </messages>
+</mavlink>
diff --git a/project/Build.scala b/project/Build.scala
index 2728c48..4ca4b3b 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -7,18 +7,16 @@ import scala.scalajs.sbtplugin.ScalaJSPlugin
import scala.scalajs.sbtplugin.ScalaJSPlugin.ScalaJSKeys._
import Dependencies._
+import com.github.jodersky.sbt.mavlink.MavlinkKeys._
+import com.github.jodersky.sbt.SbtMavlink
object ApplicationBuild extends Build {
//settings common to all projects
val common = Seq(
scalaVersion := "2.11.4",
- scalacOptions ++= Seq("-feature", "-deprecation")
- )
-
- //settings for js/jvm projects using shared sources
- val shared = Seq(
- unmanagedSourceDirectories in Compile += (scalaSource in (mavlink, Compile)).value
+ scalacOptions ++= Seq("-feature", "-deprecation"),
+ mavlinkDialect := file(".") / "concise.xml"
)
lazy val root = Project("root", file(".")).aggregate(
@@ -27,15 +25,10 @@ object ApplicationBuild extends Build {
frontend
)
- lazy val mavlink = (
- Project("vfd-mavlink", file("vfd-mavlink"))
- settings(common: _*)
- )
-
lazy val uav = (
Project("vfd-uav", file("vfd-uav"))
+ enablePlugins(SbtMavlink)
settings(common: _*)
- settings(shared: _*)
settings(
libraryDependencies ++= Seq(
akkaActor,
@@ -48,6 +41,7 @@ object ApplicationBuild extends Build {
lazy val backend = (
Project("vfd-backend", file("vfd-backend"))
enablePlugins(PlayScala)
+ enablePlugins(SbtMavlink)
settings(common: _*)
settings(
resolvers += Resolver.url("scala-js-releases", url("http://dl.bintray.com/content/scala-js/scala-js-releases"))(Resolver.ivyStylePatterns),
@@ -64,8 +58,8 @@ object ApplicationBuild extends Build {
lazy val frontend = (
Project("vfd-frontend", file("vfd-frontend"))
settings(ScalaJSPlugin.scalaJSSettings: _*)
+ enablePlugins(SbtMavlink)
settings(common: _*)
- settings(shared: _*)
settings(
libraryDependencies ++= Seq(
rx,
diff --git a/project/build.properties b/project/build.properties
index be6c454..748703f 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version=0.13.5
+sbt.version=0.13.7
diff --git a/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/Main.scala b/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/Main.scala
new file mode 100644
index 0000000..5f77c1a
--- /dev/null
+++ b/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/Main.scala
@@ -0,0 +1,41 @@
+package com.github.jodersky.mavlink
+
+import scala.xml.XML
+import com.github.jodersky.mavlink.parsing.Protocol
+import java.io.FileWriter
+import java.io.BufferedWriter
+import scalax.file.Path
+import java.io.File
+
+object Main {
+
+ def prettify(str: String) = str.replaceAll("(\\s*\n)(\\s*\n)+", "\n\n")
+
+ private def processTemplates(protocol: Protocol, rootOut: Path) = {
+ val root = rootOut / Path.fromString("org/mavlink")
+ val mappings: List[(String, Path)] = List(
+ org.mavlink.txt.Crc().body -> Path("Crc.scala"),
+ org.mavlink.txt.Packet(protocol.messages).body -> Path("Packet.scala"),
+ org.mavlink.txt.Parser().body -> Path("Parser.scala"),
+ org.mavlink.messages.txt.Message(protocol.messages).body -> Path.fromString("messages/messages.scala")
+ )
+
+ for ((str, file) <- mappings) yield {
+ val out = root / file
+ out.createFile(true, false)
+ out.write(prettify(str))
+ out
+ }
+ }
+
+ def run(dialect: File, out: File) = {
+ val xml = XML.loadFile(dialect)
+ val protocol = Protocol.parse(xml)
+ processTemplates(protocol, Path(out)).map(_.fileOption.get)
+ }
+
+ def main(args: Array[String]): Unit = {
+ run(new File(args(0)), new File(args(1)))
+ }
+
+} \ No newline at end of file
diff --git a/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/Crc.scala b/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/Crc.scala
new file mode 100644
index 0000000..c54b7e9
--- /dev/null
+++ b/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/Crc.scala
@@ -0,0 +1,24 @@
+package com.github.jodersky.mavlink.parsing
+
+case class Crc(val crc: Int = 0xffff) extends AnyVal {
+
+ def accumulate(datum: Byte): Crc = {
+ val d = datum & 0xff
+ var tmp = d ^ (crc & 0xff)
+ tmp ^= (tmp << 4) & 0xff;
+ Crc(
+ ((crc >> 8) & 0xff) ^ (tmp << 8) ^ (tmp << 3) ^ ((tmp >> 4) & 0xff))
+ }
+
+ def accumulate(data: Seq[Byte]): Crc = {
+ var next = this
+ for (d <- data) {
+ next = next.accumulate(d)
+ }
+ next
+ }
+
+ def lsb: Byte = crc.toByte
+ def msb: Byte = (crc >> 8).toByte
+
+} \ No newline at end of file
diff --git a/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/FieldTypes.scala b/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/FieldTypes.scala
new file mode 100644
index 0000000..0cf29b4
--- /dev/null
+++ b/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/FieldTypes.scala
@@ -0,0 +1,27 @@
+package com.github.jodersky.mavlink.parsing
+
+import scala.xml.Node
+
+object FieldTypes {
+
+ sealed trait Type {
+ def width: Int
+ def scalaType: String
+ def nativeType: String
+ }
+
+ case class IntType(signed: Boolean, width: Int, scalaType: String, nativeType: String) extends Type
+
+ def parse(xml: Node): Type = xml.text match {
+ case "int8_t" => IntType(true, 1, "Byte", xml.text)
+ case "int16_t" => IntType(true, 2, "Short", xml.text)
+ case "int32_t" => IntType(true, 4, "Int", xml.text)
+ case "int64_t" => IntType(true, 8, "Long", xml.text)
+ case "uint8_t" => IntType(false, 1, "Byte", xml.text)
+ case "uint16_t" => IntType(false, 2, "Short", xml.text)
+ case "uint32_t" => IntType(false, 4, "Int", xml.text)
+ case "uint64_t" => IntType(false, 8, "Long", xml.text)
+ case _ => Parser.fatal("unsupported type \"" + xml.text + "\"", xml)
+ }
+
+} \ No newline at end of file
diff --git a/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/Name.scala b/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/Name.scala
new file mode 100644
index 0000000..6f5b6a7
--- /dev/null
+++ b/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/Name.scala
@@ -0,0 +1,14 @@
+package com.github.jodersky.mavlink.parsing
+
+object Name {
+
+ def words(raw: String) = raw.split("\\s+|_")
+
+ def className(raw: String): String = words(raw.toLowerCase()).map(_.capitalize).mkString("")
+
+ def varName(raw: String) = {
+ val (head, tail) = className(raw).splitAt(1)
+ head.toLowerCase() + tail
+ }
+
+} \ No newline at end of file
diff --git a/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/parsing.scala b/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/parsing.scala
new file mode 100644
index 0000000..e14e0c3
--- /dev/null
+++ b/project/mavlink-library/src/main/scala/com/github/jodersky/mavlink/parsing/parsing.scala
@@ -0,0 +1,85 @@
+package com.github.jodersky.mavlink.parsing
+
+import scala.xml.Node
+import scala.util.Try
+import FieldTypes._
+import Parser._
+import Name._
+
+object Parser {
+ def fatal(message: String, xml: Node) = throw new RuntimeException("Cannot parse message definition: " + message + " " + xml)
+}
+
+case class Protocol(version: String, enums: Seq[Enum], messages: Seq[Message])
+object Protocol {
+ def parse(xml: Node) = {
+ val root = xml \\ "mavlink"
+ val version = (root \ "version").text
+ val enums = (root \ "enums" \ "_") map Enum.parse
+ val messages = (root \ "messages" \ "_") map Message.parse
+ Protocol(version, enums, messages)
+ }
+}
+
+case class Enum(name: String, entries: Seq[EnumEntry]) {
+ def scalaName = className(name)
+}
+object Enum {
+ def parse(xml: Node) = {
+ val name = (xml \ "@name").headOption.map(_.text).getOrElse(fatal("no name defined", xml))
+ val entries = (xml \ "entry") map EnumEntry.parse
+ Enum(name, entries)
+ }
+}
+
+case class EnumEntry(value: Int, name: String, description: String) {
+ def scalaName = className(name)
+}
+object EnumEntry {
+ def parse(xml: Node) = {
+ val valueString = (xml \ "@value").headOption.map(_.text).getOrElse(fatal("no value defined", xml))
+ val value = Try { Integer.parseInt(valueString) }.getOrElse(fatal("value must be an integer", xml))
+ val name = (xml \ "@name").headOption.map(_.text).getOrElse(fatal("no name defined", xml))
+ val description = (xml \ "description").text
+ EnumEntry(value, name, description)
+ }
+}
+
+case class Message(id: Byte, name: String, description: String, fields: Seq[Field]) {
+ def scalaName = className(name)
+ def orderedFields = fields.sortBy(_.tpe.width)(Ordering[Int].reverse)
+
+ lazy val checksum = {
+ var c = new Crc()
+ c = c.accumulate((name + " ").getBytes)
+ for (field <- orderedFields) {
+ c = c.accumulate((field.tpe.nativeType + " ").getBytes)
+ c = c.accumulate((field.name + " ").getBytes)
+ }
+ (c.lsb ^ c.msb).toByte
+ }
+}
+object Message {
+ def parse(xml: Node): Message = {
+ val idString = (xml \ "@id").headOption.map(_.text).getOrElse(fatal("no id defined", xml))
+ val id = Try { Integer.parseInt(idString).toByte }.getOrElse(fatal("id must be an integer", xml))
+ val name = (xml \ "@name").headOption.map(_.text).getOrElse(fatal("no name defined", xml))
+ val description = (xml \ "description").text
+ val fields = (xml \ "field") map Field.parse
+ Message(id, name, description, fields)
+ }
+}
+
+case class Field(tpe: Type, name: String, enum: Option[String], description: String) {
+ def scalaName = varName(name)
+}
+object Field {
+ def parse(xml: Node): Field = {
+ val tpeNode = (xml \ "@type").headOption.getOrElse(fatal("no type defined", xml))
+ val tpe = FieldTypes.parse(tpeNode)
+ val name = (xml \ "@name").headOption.map(_.text).getOrElse(fatal("no name defined", xml))
+ val enum = (xml \ "@enum").headOption.map(_.text)
+ val description = (xml).text
+ Field(tpe, name, enum, description)
+ }
+} \ No newline at end of file
diff --git a/vfd-mavlink/src/main/scala/org/mavlink/Crc.scala b/project/mavlink-library/src/main/twirl/org/mavlink/Crc.scala.txt
index e11645e..61b5c6f 100644
--- a/vfd-mavlink/src/main/scala/org/mavlink/Crc.scala
+++ b/project/mavlink-library/src/main/twirl/org/mavlink/Crc.scala.txt
@@ -1,3 +1,5 @@
+@()
+
package org.mavlink
/**
@@ -7,7 +9,7 @@ package org.mavlink
*/
case class Crc(val crc: Int = 0xffff) extends AnyVal {
- def next(datum: Byte): Crc = {
+ def accumulate(datum: Byte): Crc = {
val d = datum & 0xff
var tmp = d ^ (crc & 0xff)
tmp ^= (tmp << 4) & 0xff;
diff --git a/project/mavlink-library/src/main/twirl/org/mavlink/Packet.scala.txt b/project/mavlink-library/src/main/twirl/org/mavlink/Packet.scala.txt
new file mode 100644
index 0000000..6f96b40
--- /dev/null
+++ b/project/mavlink-library/src/main/twirl/org/mavlink/Packet.scala.txt
@@ -0,0 +1,59 @@
+@(messages: Seq[parsing.Message])
+
+@messageCrcs() = @{
+ for (i <- 0 to 255) yield {
+ val crc = messages.find(_.id == i).map(_.checksum).getOrElse(0)
+ crc.toString
+ }
+}
+
+package org.mavlink
+
+case class Packet(
+ seq: Byte,
+ systemId: Byte,
+ componentId: Byte,
+ messageId: Byte,
+ payload: Seq[Byte]
+) {
+
+ lazy val crc = {
+ var c = new Crc()
+ c = c.accumulate(payload.length.toByte)
+ c = c.accumulate(seq)
+ c = c.accumulate(systemId)
+ c = c.accumulate(componentId)
+ c = c.accumulate(messageId)
+ for (p <- payload) {
+ c = c.accumulate(p)
+ }
+ c = c.accumulate(Packet.extraCrc(messageId))
+ c
+ }
+
+ def toSeq: Seq[Byte] = Seq(
+ Packet.Stx,
+ payload.length.toByte,
+ seq,
+ systemId,
+ componentId,
+ messageId
+ ) ++ payload ++ Seq(
+ crc.lsb,
+ crc.msb
+ )
+
+}
+
+object Packet {
+
+ final val Stx: Byte = (0xfe).toByte
+ final val MaxPayloadLength: Int = @messages.map(_.fields.map(_.tpe.width).sum).max
+
+ final val ExtraCrcs: Seq[Byte] = @messageCrcs().mkString("Array[Byte](", ", ", ")")
+
+ def extraCrc(id: Byte) = ExtraCrcs(id & 0xff)
+
+ final val Empty = Packet(0, 0, 0, -1, Array(0: Byte))
+
+} \ No newline at end of file
diff --git a/vfd-mavlink/src/main/scala/org/mavlink/Parser.scala b/project/mavlink-library/src/main/twirl/org/mavlink/Parser.scala.txt
index 3cd9dc3..f0e30dc 100644
--- a/vfd-mavlink/src/main/scala/org/mavlink/Parser.scala
+++ b/project/mavlink-library/src/main/twirl/org/mavlink/Parser.scala.txt
@@ -1,3 +1,5 @@
+@()
+
package org.mavlink
import scala.collection.mutable.ArrayBuffer
@@ -51,27 +53,27 @@ class Parser(receiver: Packet => Unit, error: Parser.ParseErrors.ParseError => U
case GotStx =>
inbound.crc = new Crc()
inbound.length = (c & 0xff)
- inbound.crc = inbound.crc.next(c)
+ inbound.crc = inbound.crc.accumulate(c)
state = GotLength
case GotLength =>
inbound.seq = c;
- inbound.crc = inbound.crc.next(c)
+ inbound.crc = inbound.crc.accumulate(c)
state = GotSeq
case GotSeq =>
inbound.systemId = c
- inbound.crc = inbound.crc.next(c)
+ inbound.crc = inbound.crc.accumulate(c)
state = GotSysId
case GotSysId =>
inbound.componentId = c
- inbound.crc = inbound.crc.next(c)
+ inbound.crc = inbound.crc.accumulate(c)
state = GotCompId
case GotCompId =>
inbound.messageId = c
- inbound.crc = inbound.crc.next(c)
+ inbound.crc = inbound.crc.accumulate(c)
if (inbound.length == 0) {
state = GotPayload
} else {
@@ -81,7 +83,7 @@ class Parser(receiver: Packet => Unit, error: Parser.ParseErrors.ParseError => U
case GotMsgId =>
inbound.payload += c
- inbound.crc = inbound.crc.next(c)
+ inbound.crc = inbound.crc.accumulate(c)
if(inbound.payload.length >= Packet.MaxPayloadLength) {
state = Idle
error(ParseErrors.OverflowError)
@@ -91,7 +93,7 @@ class Parser(receiver: Packet => Unit, error: Parser.ParseErrors.ParseError => U
}
case GotPayload =>
- inbound.crc = inbound.crc.next(Packet.MessageIdCrcEnds(inbound.messageId & 0xff))
+ inbound.crc = inbound.crc.accumulate(Packet.extraCrc(inbound.messageId))
if (c != inbound.crc.lsb) {
state = Idle
if (c == Packet.Stx) {
diff --git a/project/mavlink-library/src/main/twirl/org/mavlink/_header.scala.txt b/project/mavlink-library/src/main/twirl/org/mavlink/_header.scala.txt
new file mode 100644
index 0000000..77ad6d2
--- /dev/null
+++ b/project/mavlink-library/src/main/twirl/org/mavlink/_header.scala.txt
@@ -0,0 +1,5 @@
+@()
+
+/**
+ * This file has been machine generated.
+ */ \ No newline at end of file
diff --git a/project/mavlink-library/src/main/twirl/org/mavlink/messages/Message.scala.txt b/project/mavlink-library/src/main/twirl/org/mavlink/messages/Message.scala.txt
new file mode 100644
index 0000000..1507df4
--- /dev/null
+++ b/project/mavlink-library/src/main/twirl/org/mavlink/messages/Message.scala.txt
@@ -0,0 +1,70 @@
+@(messages: Seq[parsing.Message])
+
+@extract(field: parsing.Field, offset: Int) = {
+ @field.tpe.width match {
+ case 1 => {payload(@offset)}
+ case 2 => {((payload(@offset)) | ((payload(@{offset+1}) & 0xff) << 8)).toShort}
+ case 4 => {(payload(@offset)) | ((payload(@{offset+1}) & 0xff) << 8) | ((payload(@{offset+2}) & 0xff) << 16) | ((payload(@{offset+3}) & 0xff) << 24)}
+ case 8 => {payload(@offset) |
+ ((payload(@{offset+2}) & 0xffl) << 8) |
+ ((payload(@{offset+3}) & 0xffl) << 16) |
+ ((payload(@{offset+4}) & 0xffl) << 24) |
+ ((payload(@{offset+5}) & 0xffl) << 32) |
+ ((payload(@{offset+6}) & 0xffl) << 40) |
+ ((payload(@{offset+7}) & 0xffl) << 48) |
+ ((payload(@{offset+8}) & 0xffl) << 56)}
+ }
+}
+
+@insert(field: parsing.Field, offset: Int) = {
+ @defining("m." + field.scalaName) { attr =>
+ @if(field.tpe.width >= 1) { arr(@offset) = (@attr & 0xff).toByte }
+ @if(field.tpe.width >= 2) { arr(@{offset+1}) = ((@attr >> 8) & 0xff).toByte }
+ @if(field.tpe.width >= 3) { arr(@{offset+2}) = ((@attr >> 16) & 0xff).toByte }
+ @if(field.tpe.width >= 4) { arr(@{offset+3}) = ((@attr >> 24) & 0xff).toByte }
+ @if(field.tpe.width >= 5) { arr(@{offset+4}) = ((@attr >> 32) & 0xff).toByte }
+ @if(field.tpe.width >= 6) { arr(@{offset+5}) = ((@attr >> 40) & 0xff).toByte }
+ @if(field.tpe.width >= 7) { arr(@{offset+6}) = ((@attr >> 48) & 0xff).toByte }
+ @if(field.tpe.width >= 8) { arr(@{offset+7}) = ((@attr >> 56) & 0xff).toByte }
+ }
+}
+
+@org.mavlink.txt._header()
+
+package org.mavlink.messages
+
+sealed trait Message
+@for(message <- messages) {
+ @_message_class(message)
+}
+case class Unknown(id: Byte, payload: Seq[Byte]) extends Message
+
+object Message {
+ def unpack(id: Byte, payload: Seq[Byte]) = id match {
+ @for(message <- messages) {
+ case @message.id =>
+ @defining(message.orderedFields){ ordered =>
+ @defining(ordered.map(_.tpe.width).scanLeft(0)(_ + _)){ offsets =>
+ @for((field, offset) <- ordered zip offsets) {
+ val @field.scalaName: @field.tpe.scalaType = @extract(field, offset)
+ }}}
+ @{message.scalaName}@message.fields.map(_.scalaName).mkString("(", ", ", ")")
+ }
+
+ case id => Unknown(id, payload)
+ }
+
+ def pack(message: Message): (Byte, Seq[Byte]) = message match {
+ @for(message <- messages) {
+ case m: @message.scalaName =>
+ val arr = new Array[Byte](@message.fields.map(_.tpe.width).sum)
+ @defining(message.orderedFields) { ordered =>
+ @defining(ordered.map(_.tpe.width).scanLeft(0)(_ + _)){ offsets =>
+ @for((field, offset) <- ordered zip offsets) {
+ @insert(field, offset)
+ }
+ (@message.id, arr)
+ }}}
+ case u: Unknown => (u.id, u.payload)
+ }
+} \ No newline at end of file
diff --git a/project/mavlink-library/src/main/twirl/org/mavlink/messages/_message_class.scala.txt b/project/mavlink-library/src/main/twirl/org/mavlink/messages/_message_class.scala.txt
new file mode 100644
index 0000000..78c8326
--- /dev/null
+++ b/project/mavlink-library/src/main/twirl/org/mavlink/messages/_message_class.scala.txt
@@ -0,0 +1,14 @@
+@(message: parsing.Message)
+
+@arguments(fields: Seq[parsing.Field]) = @{
+ fields.map(f => f.scalaName + ": " + f.tpe.scalaType)
+}
+
+@comment(paragraphs: Seq[String]) = @{
+ paragraphs.mkString("/**\n * ", "\n * ", "\n */")
+}
+
+@defining(message.description.grouped(120).toSeq){intro =>
+@defining(message.fields.map(field => "@param " + field.name + " " + field.description)){ fields =>
+@comment(intro ++ fields)}}
+case class @{message.scalaName}@arguments(message.fields).mkString("(", ", ", ")") extends Message \ No newline at end of file
diff --git a/project/mavlink-plugin/src/main/scala/com/github/jodersky/sbt/SbtMavlink.scala b/project/mavlink-plugin/src/main/scala/com/github/jodersky/sbt/SbtMavlink.scala
new file mode 100644
index 0000000..58692cd
--- /dev/null
+++ b/project/mavlink-plugin/src/main/scala/com/github/jodersky/sbt/SbtMavlink.scala
@@ -0,0 +1,24 @@
+package com.github.jodersky.sbt
+
+import sbt._
+import Keys._
+import plugins._
+import mavlink.MavlinkKeys._
+import sbt.Project.Initialize
+import com.github.jodersky.mavlink.Main
+
+object SbtMavlink extends AutoPlugin {
+
+ override def requires = JvmPlugin
+
+ lazy val generate = Def.task[Seq[File]] {
+ streams.value.log.info("Generating mavlink files...")
+ Main.run((mavlinkDialect in Compile).value, (mavlinkTarget in Compile).value).map(_.getAbsoluteFile)
+ }
+
+ override val projectSettings: Seq[Setting[_]] = Seq(
+ mavlinkTarget in Compile := (sourceManaged in Compile).value,
+ mavlinkGenerate in Compile := generate.value,
+ sourceGenerators in Compile += (mavlinkGenerate in Compile).taskValue
+ )
+}
diff --git a/project/mavlink-plugin/src/main/scala/com/github/jodersky/sbt/mavlink/MavlinkKeys.scala b/project/mavlink-plugin/src/main/scala/com/github/jodersky/sbt/mavlink/MavlinkKeys.scala
new file mode 100644
index 0000000..5cbffd4
--- /dev/null
+++ b/project/mavlink-plugin/src/main/scala/com/github/jodersky/sbt/mavlink/MavlinkKeys.scala
@@ -0,0 +1,14 @@
+package com.github.jodersky.sbt
+package mavlink
+
+import sbt._
+import sbt.Keys._
+import java.io.File
+
+object MavlinkKeys {
+
+ lazy val mavlinkDialect = settingKey[File]("Dialect definition from which to generate files.")
+ lazy val mavlinkTarget = settingKey[File]("Target directory to contain all generated mavlink files.")
+ lazy val mavlinkGenerate = taskKey[Seq[File]]("Generate mavlink files.")
+
+} \ No newline at end of file
diff --git a/project/plugins.sbt b/project/plugins.sbt
deleted file mode 100644
index 2c768c0..0000000
--- a/project/plugins.sbt
+++ /dev/null
@@ -1,7 +0,0 @@
-resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
-
-// The Play plugin
-addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.4")
-
-// Scala.js plugin
-addSbtPlugin("org.scala-lang.modules.scalajs" % "scalajs-sbt-plugin" % "0.5.5") \ No newline at end of file
diff --git a/project/project/BuildBuild.scala b/project/project/BuildBuild.scala
new file mode 100644
index 0000000..201507e
--- /dev/null
+++ b/project/project/BuildBuild.scala
@@ -0,0 +1,35 @@
+import sbt._
+import sbt.Keys._
+import play.twirl.sbt.SbtTwirl
+import play.twirl.sbt.Import._
+
+object BuildBuild extends Build {
+
+ lazy val root = (
+ Project("root", file("."))
+ settings(
+ addSbtPlugin("com.typesafe.play" %% "sbt-plugin" % "2.3.4"),
+ addSbtPlugin("org.scala-lang.modules.scalajs" % "scalajs-sbt-plugin" % "0.5.5")
+ )
+ dependsOn(mavlinkPlugin)
+ )
+
+ lazy val mavlinkLibrary = (
+ Project("mavlink-library", file("mavlink-library"))
+ enablePlugins(SbtTwirl)
+ settings(
+ libraryDependencies += "com.github.scala-incubator.io" %% "scala-io-file" % "0.4.2",
+ TwirlKeys.templateImports += "com.github.jodersky.mavlink._"
+ )
+ )
+
+ lazy val mavlinkPlugin = (
+ Project("mavlink-plugin", file("mavlink-plugin"))
+ settings(
+ sbtPlugin := true
+ )
+ dependsOn(mavlinkLibrary)
+ )
+
+}
+
diff --git a/project/project/plugins.sbt b/project/project/plugins.sbt
new file mode 100644
index 0000000..7b458b6
--- /dev/null
+++ b/project/project/plugins.sbt
@@ -0,0 +1 @@
+addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.0.4") \ No newline at end of file
diff --git a/vfd-frontend/src/main/scala/org/mavlink/js.scala b/vfd-frontend/src/main/scala/org/mavlink/js.scala
deleted file mode 100644
index b9bcd2b..0000000
--- a/vfd-frontend/src/main/scala/org/mavlink/js.scala
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.mavlink
-
-import scala.language.implicitConversions
-import scala.scalajs.js.JSConverters.array2JSRichGenTrav
-import scala.scalajs.js.typedarray.DataView
-import scala.scalajs.js.typedarray.Int8Array
-
-import org.mavlink.messages.PayloadReader
-import org.mavlink.messages.PayloadWriter
-
-package object messages {
- import org.mavlink.messages.PayloadReader
- import org.mavlink.messages.PayloadWriter
-
- implicit def mkReader(s: Seq[Byte]) = new BufferedPayloadReader(s.toArray)
- implicit def mkWriter(a: Array[Byte]) = new BufferedPayloadWriter(a)
-
-}
-
-package messages {
-
- class BufferedPayloadReader(payload: Array[Byte]) extends PayloadReader {
- private val buffer = new Int8Array(payload.toJSArray)
- private val view = new DataView(buffer.buffer)
- private var pos = 0
-
- def int8 = {
- val r = view.getInt8(pos)
- pos += 1
- r
- }
- def int16 = {
- val r = view.getInt16(pos, true)
- pos += 2
- r
- }
- def int32 = {
- val r = view.getInt32(pos, true)
- pos += 4
- r
- }
- def int64 = {
- val l = int32
- val m = int32
- (m.asInstanceOf[Long] << 32) | l.asInstanceOf[Long]
- }
- def float = {
- val r = view.getFloat32(pos, true)
- pos += 4
- r
- }
- def double = {
- val r = view.getFloat64(pos, true)
- pos += 8
- r
- }
-
- }
-
- class BufferedPayloadWriter(payload: Array[Byte]) extends PayloadWriter {
- def int8(x: Byte) = ???
- def int16(x: Short) = ???
- def int32(x: Int) = ???
- def int64(x: Long) = ???
- def float(x: Float) = ???
- def double(x: Double) = ???
- }
-}
-
diff --git a/vfd-frontend/src/main/scala/vfd/frontend/Main.scala b/vfd-frontend/src/main/scala/vfd/frontend/Main.scala
index d9f42c4..5c22a4b 100644
--- a/vfd-frontend/src/main/scala/vfd/frontend/Main.scala
+++ b/vfd-frontend/src/main/scala/vfd/frontend/Main.scala
@@ -1,7 +1,6 @@
package vfd.frontend
import org.mavlink.messages.Message
-
import rx.ops.RxOps
import scalatags.JsDom.all.ExtendedString
import scalatags.JsDom.all.button
@@ -17,6 +16,7 @@ import scalatags.JsDom.all.stringStyle
import scalatags.JsDom.all.width
import vfd.frontend.ui.panels
import vfd.frontend.util.Environment
+import rx.core.Obs
object Main {
@@ -29,6 +29,10 @@ object Main {
val message = socket.packet.map { p =>
Message.unpack(socket.packet().messageId, socket.packet().payload)
}
+
+ Obs(message) {
+ println(message().toString())
+ }
val element = div(`class` := "container-fluid")(
div(`class` := "row")(
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 ab58263..738a84a 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,8 +1,6 @@
package vfd.frontend.ui.panels
-import org.mavlink.messages.Attitude
import org.mavlink.messages.Message
-import org.mavlink.messages.Pressure
import rx.core.Obs
import rx.core.Rx
@@ -20,10 +18,6 @@ object Primary {
Obs(message) {
message() match {
- case Attitude(time, roll, pitch, h) =>
- pitchRoll() = (pitch, roll)
- heading() = h
- case Pressure(time, p, _, t) => altitude() = p
case _ => ()
}
}
diff --git a/vfd-mavlink/.classpath b/vfd-mavlink/.classpath
deleted file mode 100644
index d097af6..0000000
--- a/vfd-mavlink/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-<classpath>
- <classpathentry kind="src" path="src/main/scala" output="target/scala-2.10/classes"/>
- <classpathentry kind="src" path="src/main/java" output="target/scala-2.10/classes"/>
- <classpathentry kind="src" path="src/test/scala" output="target/scala-2.10/test-classes"/>
- <classpathentry kind="src" path="src/test/java" output="target/scala-2.10/test-classes"/>
- <classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="output" path="bin"/>
-</classpath> \ No newline at end of file
diff --git a/vfd-mavlink/.project b/vfd-mavlink/.project
deleted file mode 100644
index c05ef5d..0000000
--- a/vfd-mavlink/.project
+++ /dev/null
@@ -1,13 +0,0 @@
-<projectDescription>
- <name>vfd-mavlink</name>
- <buildSpec>
- <buildCommand>
- <name>org.scala-ide.sdt.core.scalabuilder</name>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.scala-ide.sdt.core.scalanature</nature>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
- <linkedResources> </linkedResources>
-</projectDescription> \ No newline at end of file
diff --git a/vfd-mavlink/src/main/scala/org/mavlink/Packet.scala b/vfd-mavlink/src/main/scala/org/mavlink/Packet.scala
deleted file mode 100644
index 59f91eb..0000000
--- a/vfd-mavlink/src/main/scala/org/mavlink/Packet.scala
+++ /dev/null
@@ -1,75 +0,0 @@
-package org.mavlink
-
-case class Packet(
- seq: Byte,
- systemId: Byte,
- componentId: Byte,
- messageId: Byte,
- payload: Seq[Byte]
-) {
-
- lazy val crc = {
- var c = new Crc()
- c = c.next(payload.length.toByte)
- c = c.next(seq)
- c = c.next(systemId)
- c = c.next(componentId)
- c = c.next(messageId)
- for (p <- payload) {
- c = c.next(p)
- }
- c = c.next(Packet.MessageIdCrcEnds(messageId & 0xff))
- c
- }
-
- def toSeq: Seq[Byte] = Seq(
- Packet.Stx,
- payload.length.toByte,
- seq,
- systemId,
- componentId,
- messageId
- ) ++ payload ++ Seq(
- crc.lsb,
- crc.msb
- )
-
-}
-
-object Packet {
-
- final val Stx: Byte = (0xfe).toByte;
- final val MaxPayloadLength: Int = 255
-
- final val MessageIdCrcEnds: Seq[Byte] = Array(
- 50, 124, 137, 0, 237, 217, 104, 119, 0, 0,
- 0, 89, 0, 0, 0, 0, 0, 0, 0, 0,
- 214, 159, 220, 168, 24, 23, 170, 144, 67, 115,
- 39, 246, 185, 104, 237, 244, 222, 212, 9, 254,
- 230, 28, 28, 132, 221, 232, 11, 153, 41, 39,
- 0, 0, 0, 0, 15, 3, 0, 0, 0, 0,
- 0, 153, 183, 51, 82, 118, 148, 21, 0, 243,
- 124, 0, 0, 38, 20, 158, 152, 143, 0, 0,
- 0, 106, 49, 22, 143, 140, 5, 150, 0, 231,
- 183, 63, 54, 0, 0, 0, 0, 0, 0, 0,
- 175, 102, 158, 208, 56, 93, 211, 108, 32, 185,
- 84, 0, 0, 124, 119, 4, 76, 128, 56, 116,
- 134, 237, 203, 250, 87, 203, 220, 25, 226, 0,
- 29, 223, 85, 6, 229, 203, 1, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 154, 49, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 8, 204,
- 49, 170, 44, 83, 46, 0
- ).map(_.toByte)
-
- final val Empty = Packet(0, 0, 0, -1, Array(0: Byte))
-
-} \ No newline at end of file
diff --git a/vfd-mavlink/src/main/scala/org/mavlink/enums/SystemStatus.scala b/vfd-mavlink/src/main/scala/org/mavlink/enums/SystemStatus.scala
deleted file mode 100644
index 69d0889..0000000
--- a/vfd-mavlink/src/main/scala/org/mavlink/enums/SystemStatus.scala
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.mavlink.enums
-
-object SystemStatus extends Enumeration {
- type SystemStatus = Value
-
- /** Uninitialized system, state is unknown. */
- val Uninitialized = Value(0)
-
- /** System is booting up. */
- val Booting = Value(1)
-
- /** System is calibrating and not flight-ready. */
- val Calibrating = Value(2)
-
- /** System is grounded and ready to fly. */
- val Standby = Value(3)
-
- /** System is active an might already be airborne. */
- val Active = Value(4)
-
- /** System is in a non-normal flight mode. It can however still navigate. */
- val Critical = Value(5)
-
- /** System is in a non-normal flight mode. It lost control over parts or over the whole airframe. It is in mayday and going down. */
- val Emergency = Value(6)
-
- /** System just initialized its power-down sequence, will shut down now. */
- val Poweroff = Value(7)
-
-} \ No newline at end of file
diff --git a/vfd-mavlink/src/main/scala/org/mavlink/messages/message.scala b/vfd-mavlink/src/main/scala/org/mavlink/messages/message.scala
deleted file mode 100644
index cf8694a..0000000
--- a/vfd-mavlink/src/main/scala/org/mavlink/messages/message.scala
+++ /dev/null
@@ -1,73 +0,0 @@
-package org.mavlink.messages
-
-import org.mavlink.Packet
-
-import org.mavlink.enums.SystemStatus
-import org.mavlink.enums.SystemStatus._
-
-sealed trait Message
-case class Heartbeat(`type`: Byte, autopilot: Byte, baseMode: Byte, customMode: Int, systemStatus: SystemStatus, mavlinkVersion: Byte) extends Message
-case class RadioStatus(rssi: Byte, remoteRssi: Byte, txBuf: Byte, noise: Byte, remoteNoise: Byte, rxErrors: Short, fixed: Short) extends Message
-case class Attitude(time: Int, roll: Float, pitch: Float, heading: Float) extends Message
-case class Pressure(time: Int, pressure: Float, diffPressure: Float, temperature: Short) extends Message
-case class Battery(id: Byte, function: Byte, `type`: Byte, temperature: Short,
- voltages: Seq[Short], current: Short, currentConsumed: Int, energyConsumed: Int, remaining: Byte) extends Message
-case class Unknown(id: Int, payload: Seq[Byte]) extends Message
-
-object Message {
-
- def unpack(id: Byte, payload: Seq[Byte])(implicit mkReader: Seq[Byte] => PayloadReader): Message = {
- val r = mkReader(payload)
-
- id & 0xff match {
- case 0 =>
- val cm = r.int32
- Heartbeat(r.int8, r.int8, r.int8, cm, SystemStatus(r.int8), r.int8)
- case 29 =>
- Pressure(r.int32, r.float, r.float, r.int16)
- case 30 =>
- Attitude(r.int32, r.float, r.float, r.float)
- case 109 =>
- val re = r.int16
- val fi = r.int16
- RadioStatus(r.int8, r.int8, r.int8, r.int8, r.int8, re, fi)
- case 147 =>
- val cc = r.int32
- val ec = r.int32
- val t = r.int16
- val v = for (i <- 0 until 10) yield r.int16
- val c = r.int16
- val id = r.int8
- val fct = r.int8
- val tpe = r.int8
- val rm = r.int8
- Battery(id, fct, tpe, t, v, c, cc, ec, rm)
-
- case u => Unknown(u, payload)
- }
- }
-
- def pack(m: Message)(implicit mkWriter: Array[Byte] => PayloadWriter): (Byte, Seq[Byte]) = {
- val (id, size) = m match {
- case _: Heartbeat => (0, 9)
- case _: RadioStatus => (109, 9)
- case u: Unknown => (u.id, u.payload.length)
- }
-
- val arr = new Array[Byte](size)
- val w = mkWriter(arr)
-
- m match {
- case Heartbeat(tp, a, b, cm, s, mv) => w.int32(cm); w.int8(tp); w.int8(b); w.int8(s.id.toByte); w.int8(mv);
- case RadioStatus(r, rr, tx, n, rn, rx, fi) => w.int16(rx); w.int16(fi); w.int8(r); w.int8(rr); w.int8(tx); w.int8(n); w.int8(rn);
- case Unknown(_, payload) => for (p <- payload) w.int8(p)
- }
-
- (id.toByte, arr)
-
- }
-
-
-
-}
- \ No newline at end of file
diff --git a/vfd-mavlink/src/main/scala/org/mavlink/messages/payload.scala b/vfd-mavlink/src/main/scala/org/mavlink/messages/payload.scala
deleted file mode 100644
index 76076b2..0000000
--- a/vfd-mavlink/src/main/scala/org/mavlink/messages/payload.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.mavlink.messages
-
-trait PayloadReader {
- def int8: Byte
- def int16: Short
- def int32: Int
- def int64: Long
- def float: Float
- def double: Double
-}
-
-trait PayloadWriter {
- def int8(x: Byte)
- def int16(x: Short)
- def int32(x: Int)
- def int64(x: Long)
- def float(x: Float)
- def double(x: Double)
-} \ No newline at end of file
diff --git a/vfd-uav/src/main/scala/org/mavlink/jvm.scala b/vfd-uav/src/main/scala/org/mavlink/jvm.scala
deleted file mode 100644
index ac711be..0000000
--- a/vfd-uav/src/main/scala/org/mavlink/jvm.scala
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.mavlink
-
-import scala.language.implicitConversions
-
-import java.nio.ByteBuffer
-import java.nio.ByteOrder
-
-package object messages {
- import org.mavlink.messages.PayloadReader
- import org.mavlink.messages.PayloadWriter
-
- implicit def mkReader(s: Seq[Byte]) = new BufferedPayloadReader(s.toArray)
- implicit def mkWriter(a: Array[Byte]) = new BufferedPayloadWriter(a)
-
-}
-
-package messages {
-
- class BufferedPayloadReader(payload: Array[Byte]) extends PayloadReader {
- private val buffer = ByteBuffer.wrap(payload)
-
- //mavlink uses little endian
- buffer.order(ByteOrder.LITTLE_ENDIAN)
-
- def int8 = buffer.get()
- def int16 = buffer.getShort()
- def int32 = buffer.getInt()
- def int64 = buffer.getLong()
- def float = buffer.getFloat()
- def double = buffer.getDouble()
-
- }
-
- class BufferedPayloadWriter(payload: Array[Byte]) extends PayloadWriter {
- private val buffer = ByteBuffer.wrap(payload)
-
- //mavlink uses little endian
- buffer.order(ByteOrder.LITTLE_ENDIAN)
-
- def int8(x: Byte) = buffer.put(x)
- def int16(x: Short) = buffer.putShort(x)
- def int32(x: Int) = buffer.putInt(x)
- def int64(x: Long) = buffer.putLong(x)
- def float(x: Float) = buffer.putFloat(x)
- def double(x: Double) = buffer.putDouble(x)
- }
-}
-
diff --git a/vfd-uav/src/main/scala/vfd/uav/SerialConnection.scala b/vfd-uav/src/main/scala/vfd/uav/SerialConnection.scala
index 7fe9d23..857169e 100644
--- a/vfd-uav/src/main/scala/vfd/uav/SerialConnection.scala
+++ b/vfd-uav/src/main/scala/vfd/uav/SerialConnection.scala
@@ -1,21 +1,24 @@
package vfd.uav
import java.util.concurrent.TimeUnit.MILLISECONDS
+
import scala.concurrent.duration.FiniteDuration
+
import org.mavlink.Parser
import org.mavlink.messages.Message
+
import com.github.jodersky.flow.Parity
import com.github.jodersky.flow.Serial
import com.github.jodersky.flow.SerialSettings
+
import akka.actor.Actor
+import akka.actor.ActorLogging
import akka.actor.ActorRef
import akka.actor.Props
import akka.actor.Terminated
import akka.actor.actorRef2Scala
import akka.io.IO
import akka.util.ByteString
-import akka.actor.ActorLogging
-import org.mavlink.messages.Battery
class SerialConnection(id: Byte, heartbeat: Option[FiniteDuration], port: String, settings: SerialSettings) extends Actor with ActorLogging with Connection {
import context._
@@ -68,14 +71,8 @@ class SerialConnection(id: Byte, heartbeat: Option[FiniteDuration], port: String
val last = new collection.mutable.Queue[Int]
- val parser = new Parser(pckt =>
- Message.unpack(pckt.messageId, pckt.payload) match {
- case b: Battery =>
- last enqueue b.voltages(0)
- if (last.size > 20) last.dequeue
- println("batt: " + last.sum / last.size)
- case _ => ()//println(pckt.messageId)
- }
+ val parser = new Parser(pckt =>
+ println("Received message: " + Message.unpack(pckt.messageId, pckt.payload))
)