added status of mobile robot in UI

implemented battery state for both robots in RobotLib
main
Jonas Arnold 4 years ago
parent 82c449ba29
commit 630f504785
  1. 16
      ADIS_Csharp/RobotClientWpf/Utilities/UIAccessHelpers.cs
  2. 2
      ADIS_Csharp/RobotClientWpf/Views/ConfigView.xaml
  3. 8
      ADIS_Csharp/RobotClientWpf/Views/ConfigView.xaml.cs
  4. 13
      ADIS_Csharp/RobotClientWpf/Views/MainView.xaml
  5. 17
      ADIS_Csharp/RobotClientWpf/Views/MainView.xaml.cs
  6. 40
      ADIS_Csharp/RobotLib/Battery/DevBattery.cs
  7. 2
      ADIS_Csharp/RobotLib/Communication/MqttPublisherSubscriber.cs
  8. 20
      ADIS_Csharp/RobotLib/Robot.cs

@ -3,6 +3,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Shapes;
namespace RobotClientWpf.Utilities
{
@ -99,5 +100,20 @@ namespace RobotClientWpf.Utilities
textBlock.Foreground = foregroundColor;
}
}
public static void SetShapeVisibility(Shape shape, bool visible)
{
if (!Application.Current.Dispatcher.CheckAccess())
{
Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
SetShapeVisibility(shape, visible);
}));
}
else
{
shape.Opacity = visible?100:0;
}
}
}
}

@ -76,7 +76,7 @@
<StackPanel Orientation="Vertical">
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal" VerticalAlignment="Top">
<Label DockPanel.Dock="Left" Content="Hostname:" Margin="5 0" Height="30" Width="100"/>
<TextBox DockPanel.Dock="Left" x:Name="tbRobotConfiguratorHostname" Width="200" Height="30" Margin="5" TextChanged="tbRobotConfiguratorHostname_TextChanged"/>
<TextBox DockPanel.Dock="Left" x:Name="tbRobotConfiguratorHostname" Width="300" Height="30" Margin="5" Text="ADISRobotExx.simple.eee.intern" TextChanged="tbRobotConfiguratorHostname_TextChanged"/>
<Button DockPanel.Dock="Left" x:Name="btnClearRobotConfHostname" Content="Clear" Margin="5" Width="50" Height="30" Click="btnClearRobotConfHostname_Click" />
</StackPanel>
<StackPanel Orientation="Horizontal">

@ -101,10 +101,10 @@ namespace RobotClientWpf.Views
private void EnableRobotConfigurationOptions(bool enabled)
{
UIAccessHelpers.SetButtonState(btnSetBrokerIp, enabled);
UIAccessHelpers.SetButtonState(btnReboot, enabled);
UIAccessHelpers.SetButtonState(btnSetModeStationary, enabled);
UIAccessHelpers.SetButtonState(btnSetModeMobile, enabled);
if (btnSetBrokerIp != null) UIAccessHelpers.SetButtonState(btnSetBrokerIp, enabled);
if (btnReboot != null) UIAccessHelpers.SetButtonState(btnReboot, enabled);
if (btnSetModeStationary != null) UIAccessHelpers.SetButtonState(btnSetModeStationary, enabled);
if (btnSetModeMobile != null) UIAccessHelpers.SetButtonState(btnSetModeMobile, enabled);
}
private void btnClearRobotConfHostname_Click(object sender, RoutedEventArgs e)

@ -9,7 +9,7 @@
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="400"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="200"/>
@ -21,11 +21,20 @@
<GroupBox Header="Splitflap Display" Margin="10" HorizontalAlignment="Right" Width="180">
<TextBox x:Name="tbSplitflapText" Height="70" Width="150" FontSize="30" IsReadOnly="True" TextWrapping="NoWrap" HorizontalAlignment="Left"/>
</GroupBox>
<GroupBox Header="Robot battery" Margin="10" HorizontalAlignment="Right" Width="180">
<GroupBox Header="Robot" Margin="10" HorizontalAlignment="Right" Width="350">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Label Content="Battery" Margin="10 0"/>
<TextBox x:Name="tbRoboVoltage" Height="25" Width="100" FontSize="15" IsReadOnly="True" TextWrapping="NoWrap" HorizontalAlignment="Left">NaN</TextBox>
<Label Content="V" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="State" Margin="10 0"/>
<Ellipse Fill="Red" x:Name="ellipseRed" Width="20" Height="20" Margin="15 0" Opacity="0"/>
<Ellipse Fill="Green" x:Name="ellipseGreen" Width="20" Height="20" Margin="0 0" Opacity="0"/>
</StackPanel>
</StackPanel>
</GroupBox>
</StackPanel>

@ -12,7 +12,7 @@ namespace RobotClientWpf.Views
private static readonly NLog.Logger log = NLog.LogManager.GetCurrentClassLogger();
private ChallengeFactory? challenge;
private MainWindow? mainWindow;
private const int AMOUNT_SPEED_ADDED_PER_CLICK = 500;
private const int AMOUNT_SPEED_ADDED_PER_CLICK = 200;
private const int TURN_ANGLE_PER_CLICK = 30;
public MainView()
@ -27,6 +27,21 @@ namespace RobotClientWpf.Views
// subscribe to events
this.challenge.RobotStationary.SplitFlap.SplitFlapDisplayChanged += this.SplitFlap_SplitFlapDisplayChanged;
this.challenge.RobotMobile.Battery.BatteryChanged += Battery_BatteryChanged;
this.challenge.RobotMobile.Battery.SecondsSinceLastResponseUpdate += Battery_SecondsSinceLastResponseUpdate;
}
private void Battery_SecondsSinceLastResponseUpdate(object? sender, int e)
{
if(e > 15)
{
UIAccessHelpers.SetShapeVisibility(ellipseRed, true);
UIAccessHelpers.SetShapeVisibility(ellipseGreen, false);
}
else
{
UIAccessHelpers.SetShapeVisibility(ellipseRed, false);
UIAccessHelpers.SetShapeVisibility(ellipseGreen, true);
}
}
private void Battery_BatteryChanged(object? sender, RobotLib.Battery.BatteryEventArgs e)

@ -1,6 +1,7 @@
using RobotLib.Communication;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.Json;
namespace RobotLib.Battery
@ -8,11 +9,15 @@ namespace RobotLib.Battery
public class DevBattery : DevBase
{
private float voltage;
private int secondsSinceLastResponse = 0;
private Stopwatch stopwatchLastResponse = new();
private const string TOPIC_ROBO_REQ_BATTERY = "/mobile/cmd/battery/get_volt";
private const string TOPIC_ROBO_REQ_BATTERY = "/both/cmd/battery/get_volt";
private const string TOPIC_ROBO_RESP_BATTERY = "/mobile/state/battery/voltage";
private const string TOPIC_STAT_RESP_BATTERY = "/stationary/state/battery/voltage";
public event EventHandler<BatteryEventArgs> BatteryChanged;
public event EventHandler<int> SecondsSinceLastResponseUpdate;
public float Voltage
{
@ -29,17 +34,46 @@ namespace RobotLib.Battery
}
}
public DevBattery(IPublisherSubscriber com) : base(com, new List<string>() { TOPIC_ROBO_RESP_BATTERY }) { }
public int SecondsSinceLastResponse
{
get { return secondsSinceLastResponse; }
private set
{
secondsSinceLastResponse = value;
SecondsSinceLastResponseUpdate?.Invoke(this, secondsSinceLastResponse);
}
}
public DevBattery(IPublisherSubscriber com, RobotMode mode) : base(com, GenerateListOfRelevantTopics(mode)) { }
private static List<string> GenerateListOfRelevantTopics(RobotMode mode)
{
if (mode == RobotMode.Stationary)
{
return new List<string>() { TOPIC_STAT_RESP_BATTERY };
}
else
{
return new List<string>() { TOPIC_ROBO_RESP_BATTERY };
}
}
public void RequestBatteryVoltage()
{
base.SendMessage(TOPIC_ROBO_REQ_BATTERY, true.ToString());
if (this.stopwatchLastResponse.IsRunning)
{
SecondsSinceLastResponse = this.stopwatchLastResponse.Elapsed.Seconds;
}
}
protected override void ParseMessage(string fromTopic, string message)
{
if (fromTopic == TOPIC_ROBO_RESP_BATTERY)
if (fromTopic == TOPIC_ROBO_RESP_BATTERY || fromTopic == TOPIC_STAT_RESP_BATTERY)
{
this.stopwatchLastResponse.Stop();
this.stopwatchLastResponse.Start();
SecondsSinceLastResponse = 0;
var parsedString = GetValueFromMesage<string>("voltage", message);
if (parsedString == null) parsedString = "?";

@ -136,7 +136,7 @@ namespace RobotLib.Communication
lock (clientLock)
{
IsConnected = false;
log.Info($"Connection was closed.");
log.Warn($"Connection was closed.");
}
}

@ -9,38 +9,40 @@ namespace RobotLib
{
public class Robot
{
public Robot(IPublisherSubscriber com, RobotMode type)
public Robot(IPublisherSubscriber com, RobotMode mode)
{
Com = com;
Type = type;
if(type == RobotMode.Undefined)
Mode = mode;
if(mode == RobotMode.Undefined)
{
throw new System.ArgumentException("Undefined robot mode, must define mode!");
}
if(type == RobotMode.Mobile)
// battery is applicable for both modes
Battery = new DevBattery(Com, mode);
if(mode == RobotMode.Mobile)
{
//Buzzer = new DevBuzzer(Com);
Battery = new DevBattery(Com);
LineSensor = new DevLineSensor(com);
Movement = new DevMovement(com);
Status = new DevStatus(com);
}
else if(type == RobotMode.Stationary)
else if(mode == RobotMode.Stationary)
{
SplitFlap = new DevSplitFlap(com);
}
Timer timer = new Timer
{
Interval = 10000
Interval = 15000
};
timer.Enabled= true;
timer.Elapsed += Timer_Elapsed;
}
public IPublisherSubscriber Com { get; }
public RobotMode Type { get; }
public RobotMode Mode { get; }
//public DevBuzzer Buzzer { get; }
public DevBattery Battery { get; }
@ -64,7 +66,7 @@ namespace RobotLib
{
if (Com.IsConnected)
{
Battery?.RequestBatteryVoltage();
//Battery?.RequestBatteryVoltage();
}
}
}

Loading…
Cancel
Save