diff --git a/ADIS_Csharp/RaspiControl/Application.cs b/ADIS_Csharp/RaspiControl/Application.cs
index 560bbd3..38d395a 100644
--- a/ADIS_Csharp/RaspiControl/Application.cs
+++ b/ADIS_Csharp/RaspiControl/Application.cs
@@ -1,25 +1,59 @@
using NLog.LayoutRenderers;
+using RobotLib.Status;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace RaspiControl {
-
+
internal class Application {
private ChallengeFactory? challenge;
private StateMachine sm;
private readonly NLog.Logger log;
+ private Stopwatch stopwatch;
+ private uint PresentCounter;
public Application() {
this.log = NLog.LogManager.GetCurrentClassLogger();
this.sm = new StateMachine();
this.challenge = new ChallengeFactory();
this.challenge.PublisherSubscriber.ConnectionStateChanged += this.PublisherSubscriber_ConnectionStateChanged;
this.challenge.PublisherSubscriber.Connect("localhost", "ADIS", "TEST");
+ this.challenge.RobotMobile.Status.StatusChanged += Status_StatusChanged;
+ this.challenge.RobotMobile.Status.PresentChanged += Status_PresentChanged;
Joystick joystick = new Joystick();
joystick.JoystickChanged += Joystick_JoystickChanged;
+ this.stopwatch = new Stopwatch();
+ this.PresentCounter = 0;
+ }
+
+ public void Status_StatusChanged(object? sender, StatusEventArgs e) {
+ try {
+ if (e.Status == RoboStatus.Auto) {
+ this.sm.MoveNext(Command.autoMode);
+ this.smHandler();
+ }
+ if(e.Status == RoboStatus.Final) {
+ this.sm.MoveNext(Command.finished);
+ this.smHandler();
+ }
+ if(e.Status == RoboStatus.Failure) {
+ this.sm.MoveNext(Command.failure);
+ this.smHandler();
+ }
+ }catch(Exception ex) {
+ this.log.Error(ex.Message);
+ }
+ }
+
+ public void Status_PresentChanged(object? sender, PresentEventArgs e) {
+ if(this.sm.CurrentState == ProcessState.Auto) {
+ this.PresentCounter++;
+ this.challenge.RobotStationary.SplitFlap.Display(this.PresentCounter.ToString().PadLeft(4,'0'));
+ }
}
public void Run() {
@@ -27,8 +61,12 @@ namespace RaspiControl {
if (!success) {
throw new Exception("Could not connect to broker on localhost");
} else {
- this.sm.MoveNext(Command.Connected);
- this.log.Info($"Current State: {this.sm.CurrentState}");
+ try {
+ this.sm.MoveNext(Command.Connected);
+ this.log.Info($"Current State: {this.sm.CurrentState}");
+ } catch (Exception ex) {
+ this.log.Error(ex.Message);
+ }
}
}
@@ -53,6 +91,10 @@ namespace RaspiControl {
break;
case ProcessState.StartMoveManual:
// mode automatic:false
+ if (this.stopwatch.IsRunning) {
+ this.stopwatch.Stop();
+ }
+ this.stopwatch.Start();
this.challenge.RobotStationary.SplitFlap.Display("WALD");
this.challenge.RobotMobile.Movement.SetMobilityMode(false);
this.challenge.RobotMobile.Movement.AddSpeed(NavigationConstants.SPEED_FORWARD);
@@ -89,35 +131,47 @@ namespace RaspiControl {
this.challenge.RobotMobile.Movement.Stop();
break;
case ProcessState.Auto:
+ this.challenge.RobotStationary.SplitFlap.Display("AUTO");
break;
case ProcessState.Final:
+ this.PresentCounter = 0;
+ this.stopwatch.Stop();
+ long elapsedTime = stopwatch.ElapsedMilliseconds / 1000;
+ this.challenge.RobotStationary.SplitFlap.Display(elapsedTime.ToString().PadLeft(4,'0'));
break;
case ProcessState.Error:
+ //this.PresentCounter = 0;
break;
}
}
private void Joystick_JoystickChanged(object sender, JoystickEventArgs e) {
- switch (e.Button) {
- case JoystickButton.None:
- break;
- case JoystickButton.Left:
- this.sm.MoveNext(Command.JoystickLeft);
- break;
- case JoystickButton.Right:
- this.sm.MoveNext(Command.JoystickRight);
- break;
- case JoystickButton.Up:
- this.sm.MoveNext(Command.JoystickUp);
- break;
- case JoystickButton.Down:
- this.sm.MoveNext(Command.JoystickDown);
- break;
- case JoystickButton.Center:
- this.sm.MoveNext(Command.JoystickCenter);
- break;
+ try {
+ switch (e.Button) {
+ case JoystickButton.None:
+ break;
+ case JoystickButton.Left:
+ this.sm.MoveNext(Command.JoystickLeft);
+ break;
+ case JoystickButton.Right:
+ this.sm.MoveNext(Command.JoystickRight);
+ break;
+ case JoystickButton.Up:
+ this.sm.MoveNext(Command.JoystickUp);
+ break;
+ case JoystickButton.Down:
+ this.sm.MoveNext(Command.JoystickDown);
+ break;
+ case JoystickButton.Center:
+ this.sm.MoveNext(Command.JoystickCenter);
+ break;
+ }
+ if(e.Button != JoystickButton.None) {
+ this.smHandler();
+ }
+ } catch (Exception ex) {
+ this.log.Error(ex.Message);
}
- this.smHandler();
}
}
}
diff --git a/ADIS_Csharp/RaspiControl/RaspiControl.csproj b/ADIS_Csharp/RaspiControl/RaspiControl.csproj
index d41197f..4ebbd9f 100644
--- a/ADIS_Csharp/RaspiControl/RaspiControl.csproj
+++ b/ADIS_Csharp/RaspiControl/RaspiControl.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/ADIS_Csharp/RaspiControl/StateMachine.cs b/ADIS_Csharp/RaspiControl/StateMachine.cs
index 396cf85..e2f3b29 100644
--- a/ADIS_Csharp/RaspiControl/StateMachine.cs
+++ b/ADIS_Csharp/RaspiControl/StateMachine.cs
@@ -31,6 +31,8 @@ namespace RaspiControl {
JoystickRight,
JoystickCenter,
autoMode,
+ finished,
+ failure,
none
}
internal class StateMachine {
@@ -69,28 +71,48 @@ namespace RaspiControl {
{new StateTransition(ProcessState.Ready,Command.JoystickLeft), ProcessState.StartMoveManual },
{new StateTransition(ProcessState.Ready,Command.JoystickRight), ProcessState.StartMoveManual },
+
{new StateTransition(ProcessState.StartMoveManual,Command.none), ProcessState.MoveManual },
+ {new StateTransition(ProcessState.StartMoveManual, Command.autoMode), ProcessState.Auto },
{new StateTransition(ProcessState.MoveManualF, Command.none), ProcessState.MoveManual },
+ {new StateTransition(ProcessState.MoveManualF, Command.autoMode), ProcessState.Auto },
{new StateTransition(ProcessState.MoveManualB, Command.none), ProcessState.MoveManual },
+ {new StateTransition(ProcessState.MoveManualB, Command.autoMode), ProcessState.Auto },
{new StateTransition(ProcessState.MoveManualL, Command.none), ProcessState.MoveManual },
+ {new StateTransition(ProcessState.MoveManualL, Command.autoMode), ProcessState.Auto },
{new StateTransition(ProcessState.MoveManualR, Command.none), ProcessState.MoveManual },
+ {new StateTransition(ProcessState.MoveManualR, Command.autoMode), ProcessState.Auto },
{new StateTransition(ProcessState.MoveManual, Command.JoystickUp), ProcessState.MoveManualF },
{new StateTransition(ProcessState.MoveManual, Command.JoystickDown), ProcessState.MoveManualB },
{new StateTransition(ProcessState.MoveManual, Command.JoystickLeft), ProcessState.MoveManualL },
{new StateTransition(ProcessState.MoveManual, Command.JoystickRight), ProcessState.MoveManualR },
{new StateTransition(ProcessState.MoveManual, Command.JoystickCenter), ProcessState.StopManual },
+ {new StateTransition(ProcessState.MoveManual, Command.autoMode), ProcessState.Auto },
{new StateTransition(ProcessState.StopManual,Command.JoystickUp), ProcessState.ResumeMoveManual },
{new StateTransition(ProcessState.StopManual,Command.JoystickDown), ProcessState.ResumeMoveManual },
{new StateTransition(ProcessState.StopManual,Command.JoystickLeft), ProcessState.ResumeMoveManual },
{new StateTransition(ProcessState.StopManual,Command.JoystickRight), ProcessState.ResumeMoveManual },
+ {new StateTransition(ProcessState.StopManual, Command.autoMode), ProcessState.Auto },
{new StateTransition(ProcessState.ResumeMoveManual, Command.none),ProcessState.MoveManual },
-
- {new StateTransition(ProcessState.MoveManual, Command.autoMode), ProcessState.Auto },
-
+ {new StateTransition(ProcessState.ResumeMoveManual, Command.autoMode), ProcessState.Auto },
+
+ {new StateTransition(ProcessState.Auto, Command.finished), ProcessState.Final },
+ {new StateTransition(ProcessState.Auto, Command.JoystickUp), ProcessState.StartMoveManual },
+ {new StateTransition(ProcessState.Auto, Command.JoystickDown), ProcessState.StartMoveManual },
+ {new StateTransition(ProcessState.Auto, Command.JoystickLeft), ProcessState.StartMoveManual },
+ {new StateTransition(ProcessState.Auto, Command.JoystickRight), ProcessState.StartMoveManual },
+ {new StateTransition(ProcessState.Auto, Command.JoystickCenter), ProcessState.StartMoveManual },
+ {new StateTransition(ProcessState.Auto, Command.failure), ProcessState.Error },
+
+ {new StateTransition(ProcessState.Error, Command.JoystickUp), ProcessState.StartMoveManual },
+ {new StateTransition(ProcessState.Error, Command.JoystickDown), ProcessState.StartMoveManual },
+ {new StateTransition(ProcessState.Error, Command.JoystickLeft), ProcessState.StartMoveManual },
+ {new StateTransition(ProcessState.Error, Command.JoystickRight), ProcessState.StartMoveManual },
+ {new StateTransition(ProcessState.Error, Command.JoystickCenter), ProcessState.StartMoveManual },
};
}
diff --git a/ADIS_Csharp/RobotLib/Robot.cs b/ADIS_Csharp/RobotLib/Robot.cs
index edb1f5f..1f66061 100644
--- a/ADIS_Csharp/RobotLib/Robot.cs
+++ b/ADIS_Csharp/RobotLib/Robot.cs
@@ -3,6 +3,7 @@ using RobotLib.SplitFlap;
using RobotLib.Movement;
using RobotLib.Battery;
using System.Timers;
+using RobotLib.Status;
namespace RobotLib
{
@@ -23,6 +24,7 @@ namespace RobotLib
Battery = new DevBattery(Com);
LineSensor = new DevLineSensor(com);
Movement = new DevMovement(com);
+ Status = new DevStatus(com);
}
else if(type == RobotMode.Stationary)
{
@@ -46,6 +48,8 @@ namespace RobotLib
public DevMovement Movement { get; }
public DevLineSensor LineSensor { get; }
+ public DevStatus Status { get; }
+
public void Connect(string host, int port)
{
//Com.Connect(host, port);
diff --git a/ADIS_Csharp/RobotLib/Status/DevStatus.cs b/ADIS_Csharp/RobotLib/Status/DevStatus.cs
new file mode 100644
index 0000000..44ba3a2
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/Status/DevStatus.cs
@@ -0,0 +1,37 @@
+using RobotLib.Communication;
+using RobotLib.SplitFlap;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+namespace RobotLib.Status {
+ public class DevStatus: DevBase {
+ private const string TOPIC_STATUS_MODE = "/mobile/status/mode/";
+ private const string TOPIC_STATUS_PRESENT = "/mobile/status/present/";
+
+ public event EventHandler StatusChanged;
+ public event EventHandler PresentChanged;
+
+ public DevStatus(IPublisherSubscriber com) : base(com, new List() { TOPIC_STATUS_MODE, TOPIC_STATUS_PRESENT }) { }
+
+
+ protected override void ParseMessage(string fromTopic, string message) {
+ if (fromTopic == TOPIC_STATUS_MODE) {
+ StatusEventArgs eventArgs = new(message);
+ StatusChanged?.Invoke(this, eventArgs);
+ }else if(fromTopic == TOPIC_STATUS_PRESENT) {
+ PresentEventArgs presentEventArgs = new(true);
+ PresentChanged?.Invoke(this, presentEventArgs);
+ }
+ }
+
+ private T GetValueFromMesage(string parameter, string message) {
+ var data = JsonSerializer.Deserialize>(message);
+ data.TryGetValue(parameter, out T value);
+ return value;
+ }
+ }
+}
diff --git a/ADIS_Csharp/RobotLib/Status/PresentEventArgs.cs b/ADIS_Csharp/RobotLib/Status/PresentEventArgs.cs
new file mode 100644
index 0000000..c10116f
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/Status/PresentEventArgs.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RobotLib.Status {
+ public class PresentEventArgs {
+ public bool Present { get; }
+
+ public PresentEventArgs(bool present) {
+ Present = present;
+ }
+ }
+}
diff --git a/ADIS_Csharp/RobotLib/Status/RoboStatus.cs b/ADIS_Csharp/RobotLib/Status/RoboStatus.cs
new file mode 100644
index 0000000..fc6f115
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/Status/RoboStatus.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RobotLib.Status {
+
+ public static class RoboStatus {
+ public static readonly string Auto = "AUTO";
+ public static readonly string Manual = "MANUAL";
+ public static readonly string Final = "FINAL";
+ public static readonly string Failure = "FAILURE";
+ }
+}
diff --git a/ADIS_Csharp/RobotLib/Status/StatusEventArgs.cs b/ADIS_Csharp/RobotLib/Status/StatusEventArgs.cs
new file mode 100644
index 0000000..cc191b6
--- /dev/null
+++ b/ADIS_Csharp/RobotLib/Status/StatusEventArgs.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RobotLib.Status {
+ public class StatusEventArgs {
+ public string Status { get; }
+
+ public StatusEventArgs(string status) {
+ Status = status;
+ }
+ }
+}