diff options
author | Jakob Odersky <jodersky@gmail.com> | 2014-10-03 23:22:10 +0200 |
---|---|---|
committer | Jakob Odersky <jodersky@gmail.com> | 2014-10-03 23:22:10 +0200 |
commit | ab19a9d1a3124f310bbb48de0779b5b96801940e (patch) | |
tree | 9392461ee5605dc10deae89d96ded417c26dc9a2 /vfd-uav/src/main/scala | |
parent | e269a40911f901cac415269916d34032e167a618 (diff) | |
download | mavigator-ab19a9d1a3124f310bbb48de0779b5b96801940e.tar.gz mavigator-ab19a9d1a3124f310bbb48de0779b5b96801940e.tar.bz2 mavigator-ab19a9d1a3124f310bbb48de0779b5b96801940e.zip |
modularize project
Diffstat (limited to 'vfd-uav/src/main/scala')
-rw-r--r-- | vfd-uav/src/main/scala/vfd/uav/Connection.scala | 27 | ||||
-rw-r--r-- | vfd-uav/src/main/scala/vfd/uav/DummyConnection.scala | 43 | ||||
-rw-r--r-- | vfd-uav/src/main/scala/vfd/uav/FcuConnection.scala | 53 | ||||
-rw-r--r-- | vfd-uav/src/main/scala/vfd/uav/Framer.scala | 70 |
4 files changed, 193 insertions, 0 deletions
diff --git a/vfd-uav/src/main/scala/vfd/uav/Connection.scala b/vfd-uav/src/main/scala/vfd/uav/Connection.scala new file mode 100644 index 0000000..b4e6493 --- /dev/null +++ b/vfd-uav/src/main/scala/vfd/uav/Connection.scala @@ -0,0 +1,27 @@ +package vfd.uav + +import akka.actor.Actor +import akka.actor.ActorRef +import akka.actor.Props +import scala.collection.mutable.ArrayBuffer + +object Connection { + def dummy = Props(classOf[DummyConnection]) + def fcu(port: String, baud: Int) = Props(classOf[FcuConnection], port, baud) + + trait Event + trait Command + case object Register extends Command + case class NewDataFrame(df: DataFrame) extends Event + +} + +trait Connection {that: Actor => + private val _clients = new ArrayBuffer[ActorRef] + def clients = _clients.toSeq + def register(client: ActorRef) = { + _clients += client; + that.context.watch(client) + } + def unregister(client: ActorRef) = _clients -= client +} diff --git a/vfd-uav/src/main/scala/vfd/uav/DummyConnection.scala b/vfd-uav/src/main/scala/vfd/uav/DummyConnection.scala new file mode 100644 index 0000000..bf8714f --- /dev/null +++ b/vfd-uav/src/main/scala/vfd/uav/DummyConnection.scala @@ -0,0 +1,43 @@ +package vfd.uav + +import akka.actor.Actor +import akka.actor.Terminated +import scala.concurrent.duration.FiniteDuration +import java.util.concurrent.TimeUnit._ + +class DummyConnection extends Actor with Connection { + import context._ + + var time = 0.0 + val messageInterval = FiniteDuration(20, MILLISECONDS) + + def flightData(time: Double) = { + val speed = 5.0 / 1000 + val roll = 5.0/180*math.Pi + val pitch = 10.0/180*math.Pi + Connection.NewDataFrame(DataFrame( + roll, + pitch, + (roll * time * speed) % math.Pi, + (pitch * time * speed), + 22 + )) + } + + + override def preStart() = { + context.system.scheduler.schedule(messageInterval, messageInterval){ + time += messageInterval.toMillis + clients foreach (_ ! flightData(time)) + } + } + + def receive = { + case Connection.Register => register(sender) + case Terminated(client) => unregister(client) + } + +} + + + diff --git a/vfd-uav/src/main/scala/vfd/uav/FcuConnection.scala b/vfd-uav/src/main/scala/vfd/uav/FcuConnection.scala new file mode 100644 index 0000000..f9f267d --- /dev/null +++ b/vfd-uav/src/main/scala/vfd/uav/FcuConnection.scala @@ -0,0 +1,53 @@ +package vfd.uav + +import akka.actor.Actor +import akka.actor.Props +import akka.actor.Terminated +import akka.io.IO +import com.github.jodersky.flow._ +import com.github.jodersky.flow.Serial + + +class FcuConnection(port: String, baud: Int) extends Actor with Connection { + import context._ + + val settings = SerialSettings( + baud = this.baud, + characterSize = 8, + twoStopBits = false, + parity = Parity.None + ) + + override def preStart() = { + IO(Serial) ! Serial.Open(port, settings) + } + + def receive = { + case Connection.Register => register(sender) + case Terminated(client) => unregister(client) + case Serial.CommandFailed(cmd: Serial.Open, reason: AccessDeniedException) => println("you're not allowed to open that port!") + case Serial.CommandFailed(cmd: Serial.Open, reason) => println("could not open port for some other reason: " + reason) + case Serial.Opened(settings) => { + val operator = sender + + } + case Serial.Received(bstr) => + val str = (new String(bstr.toArray, "UTF-8")).trim + + + val LinePattern = ".*[(](.+)[)].*".r + val Number = "([-]?\\d+[.]\\d+?)".r + val Components = "(.+),(.+),(.+),(.+),(.+)".r + + str match { + case LinePattern(Components(Number(r),Number(p),Number(h),Number(a),Number(t))) => + val data = Connection.NewDataFrame(DataFrame(r.toDouble, p.toDouble, h.toDouble, a.toDouble, t.toDouble)) + println(data) + for (client <- clients) { + client ! data + } + case _ => println("unknown message: " + str) + } + } + +} diff --git a/vfd-uav/src/main/scala/vfd/uav/Framer.scala b/vfd-uav/src/main/scala/vfd/uav/Framer.scala new file mode 100644 index 0000000..f587c9e --- /dev/null +++ b/vfd-uav/src/main/scala/vfd/uav/Framer.scala @@ -0,0 +1,70 @@ +package vfd.uav + +import scala.collection.mutable.ArrayBuffer + +class Framer { + final val MTU: Int = 1024 + + final val START: Byte = 0xfd.toByte + final val STOP: Byte = 0xfe.toByte + final val ESCAPE: Byte = 0xff.toByte + + final val WAITING = 0 + final val RECEIVING = 1 + final val ESCAPING = 2 + + private val data = new Array[Byte](MTU) + private var index = 0 + private var state = WAITING + + private def add(byte: Byte): Unit = { + data(index) = byte + index += 1 + if (index >= MTU) index = 0 + } + + private def clear(): Unit = index = 0 + + + def push(byte: Byte): Option[Array[Byte]] = state match { + case WAITING => + if (byte == START) { + clear() + state = RECEIVING + } + None + + case RECEIVING => byte match { + case START => + clear() + state = RECEIVING + None + case ESCAPE => + state = ESCAPING + None + case STOP => + state = WAITING + Some(java.util.Arrays.copyOfRange(data, 0, index)) + + case _ => + add(byte) + None + } + case ESCAPING => + add(byte) + state = RECEIVING + None + } + + def push(bytes: Array[Byte]): Seq[Array[Byte]] = { + val messages = new ArrayBuffer[Array[Byte]] + + for (byte <- bytes) push(byte) match { + case None => () + case Some(message) => messages += message + } + + messages + } + +}
\ No newline at end of file |