aboutsummaryrefslogtreecommitdiff
path: root/vfd-uav/src/main/scala/vfd/uav/MockConnection.scala
blob: d08a8b69df493835b2e37f9429bf62f55e1d035c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package vfd.uav

import java.util.concurrent.TimeUnit.MILLISECONDS
import scala.concurrent.duration.FiniteDuration
import scala.util.Random
import org.mavlink.Packet
import org.mavlink.enums.MavAutopilot
import org.mavlink.enums.MavModeFlag
import org.mavlink.enums.MavState
import org.mavlink.enums.MavType
import org.mavlink.messages.Heartbeat
import Connection.Received
import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.Props
import akka.util.ByteString
import scala.concurrent.duration._
import org.mavlink.messages.Message
import vfd.uav.mock.RandomFlightPlan

class MockConnection(
  localSystemId: Byte,
  localComponentId: Byte,
  remoteSystemId: Byte,
  prescaler: Int)
    extends Actor with ActorLogging with Connection with MavlinkUtil {

  import Connection._
  import context._

  override val systemId = remoteSystemId
  override val componentId = remoteSystemId
  
  val plan = new RandomFlightPlan
  
  def scheduleMessage(delay: FiniteDuration)(fct: => Message) = system.scheduler.schedule(delay, delay){
    sendAll(Received(assemble(fct)))
  }
  def scheduleBytes(delay: FiniteDuration)(fct: => Array[Byte]) = system.scheduler.schedule(delay, delay){
    sendAll(Received(ByteString(fct)))
  }

  override def preStart() = {
    //increment state
    system.scheduler.schedule(0.01.seconds * prescaler, 0.01.seconds * prescaler){plan.tick(0.01)}
    
    //send messages
    scheduleMessage(0.1.seconds * prescaler)(plan.position)
    scheduleMessage(0.05.seconds * prescaler)(plan.attitude)
    scheduleMessage(0.05.seconds * prescaler)(plan.motors)
    scheduleMessage(0.1.seconds * prescaler)(plan.distance)
    scheduleMessage(1.seconds)(plan.heartbeat)
    
    //simulate noisy line
    scheduleBytes(0.3.seconds * prescaler)(MockPackets.invalidCrc)
    scheduleBytes(1.5.seconds * prescaler)(MockPackets.invalidOverflow)
  }

  def receive = registration

}

object MockConnection {
  def apply(systemId: Byte, componentId: Byte, remoteSystemId: Byte, prescaler: Int = 1) =
    Props(classOf[MockConnection], systemId, componentId, remoteSystemId, prescaler)
}

object MockPackets {
  val invalidCrc = Array(254, 1, 123, 13, 13).map(_.toByte)
  val invalidOverflow = {
    val data = Array.fill[Byte](Packet.MaxPayloadLength + 100)(42)
    data(0) = -2
    data(1) = 2
    data(1) = -1
    data
  }
}