Hardware components | ||||||
| × | 1 | ||||
![]() |
| × | 4 | |||
| × | 6 | ||||
![]() |
| × | 2 | |||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
![]() |
| |||||
![]() |
| |||||
| ||||||
![]() |
| |||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
![]() |
| |||||
|
Began robotics as a hobby in 2018. After some time, settled on a project with the goal of creating a robot capable of fetching a beer from the refrigerator and decided to name it "Antwerp".
About a year into the project, after a build/buy decision process, began to focus on building a software framework for creating robotic control programs. Eventually, this project became "The Robby Framework". The framework is complete now and have formed a company named "Our Robot Dreams, Inc." to market it.
Over time, the focus for Antwerp shifted to being our main testbed for The Robby Framework. To support this, have built a number of capabilities into Antwerp including speech recognition and voice operation, text-to-speech, object/face recognition, collaborative inter-robot communication, SLAM occupancy mapping and routing (under development), collision avoidance, etc...
For movement, Antwerp relies on a track system powered by two 20 amp, 65 RPM motors. Additional mechanical features include a pan/tilt servo setup for positioning an Intel D435i depth camera sensor positioned at the highest point on the robot.
The robot also includes a "WidowX" robotic arm from Trossen Robotics. The arm is powered by 6 daisy-chained Dynamixel servos and is controlled by an Arbotix microcontroller. Replaced the original gripper on the arm with a custom gripper with a wider and stronger grip. Also added an Intel D415 wide-angle depth camera sensor at the wrist of the arm to facilitate grabbing things with it.
Antwerp can be controlled with voice commands or from a remote computer. A "Master Control Program" written using The Robby Framework handles communication and control for all the devices and services utilized by the robot as well as acting as the "brain" for the overall orchestration of behavior for it.
Even though the purpose of Antwerp has become somewhat more serious over time, still trying to maintain a sense of fun in it as well as the framework and our company, Our Robot Dreams, Inc.
AntwerpWpf main dialog XAML code
XML<Window x:Class="AntwerpWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AntwerpWpf"
mc:Ignorable="d"
Title="Antwerp Main MCP" Height="692" Width="1304">
<Grid Width="1300" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="20, 0, 10, 10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="51*"/>
<ColumnDefinition Width="138*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btnStop" Content="STOP" HorizontalAlignment="Left" Margin="30,293,0,0" VerticalAlignment="Top" Width="240" RenderTransformOrigin="0.12,-2.8" Height="56" Background="Red" Foreground="Silver" FontSize="48" Padding="1,-8,1,5" FontWeight="Bold" Click="BtnStop_Click"></Button>
<Button x:Name="btnForward" Content="Forward" HorizontalAlignment="Left" Margin="30,38,0,0" VerticalAlignment="Top" Width="240" RenderTransformOrigin="0.12,-2.8" Height="55" FontSize="48" Padding="1,-8,1,5" FontWeight="Bold" Foreground="Silver" Background="#FF259E3D" Click="BtnForward_Click"></Button>
<Button x:Name="btnBack" Content="Back" HorizontalAlignment="Left" Margin="30,100,0,0" VerticalAlignment="Top" Width="240" Height="56" Background="Black" Foreground="Silver" FontSize="48" Padding="1,-8,1,5" FontWeight="Bold" Click="BtnBack_Click"></Button>
<Button x:Name="btnPivotRight" Content="Pivot Right" HorizontalAlignment="Left" Margin="28,164,0,0" VerticalAlignment="Top" Width="240" RenderTransformOrigin="0.12,-2.8" Height="55" FontSize="36" Padding="1,1,1,5" FontWeight="Bold" Foreground="Silver" Background="#FF253B9E" Click="BtnPivotRight_Click"></Button>
<Button x:Name="btnPivotLeft" Content="Pivot Left" HorizontalAlignment="Left" Margin="30,228,0,0" VerticalAlignment="Top" Width="240" RenderTransformOrigin="0.12,-2.8" Height="55" FontSize="36" Padding="1,1,1,5" FontWeight="Bold" Foreground="Silver" Background="#FFC411E0" Click="BtnPivotLeft_Click"></Button>
<Rectangle Fill="White" HorizontalAlignment="Left" Height="225" Margin="287,62,0,0" Stroke="Black" VerticalAlignment="Top" Width="203" Grid.ColumnSpan="2"></Rectangle>
<Label x:Name="label" Content="Range sensors" HorizontalAlignment="Left" Margin="287,36,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.158,0.038" FontSize="16" Grid.ColumnSpan="2"></Label>
<Label x:Name="lblFwd" Content="Front" HorizontalAlignment="Left" Margin="294,74,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="14" FontWeight="Bold"></Label>
<Label x:Name="lblRight" Content="Right" HorizontalAlignment="Left" Margin="294,104,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="14" FontWeight="Bold"></Label>
<Label x:Name="lblLeft" Content="Left" HorizontalAlignment="Left" Margin="294,134,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="14" FontWeight="Bold"></Label>
<Label x:Name="lblBack" Content="Back" HorizontalAlignment="Left" Margin="294,164,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="14" FontWeight="Bold"></Label>
<Label x:Name="lblFrontDown" Content="Front/Down" HorizontalAlignment="Left" Margin="294,194,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="14" FontWeight="Bold" Grid.ColumnSpan="2"></Label>
<Label x:Name="lblBackDown" Content="Back/Down" HorizontalAlignment="Left" Margin="294,224,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="14" FontWeight="Bold" Grid.ColumnSpan="2"></Label>
<TextBox x:Name="textFront" HorizontalAlignment="Left" Height="23" Margin="62,78,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="33" RenderTransformOrigin="0.609,0.13" FontSize="14" Grid.Column="1"></TextBox>
<TextBox x:Name="textRight" HorizontalAlignment="Left" Height="23" Margin="62,108,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="33" RenderTransformOrigin="0.609,0.13" FontSize="14" Grid.Column="1"></TextBox>
<TextBox x:Name="textLeft" HorizontalAlignment="Left" Height="23" Margin="62,138,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="33" RenderTransformOrigin="0.609,0.13" FontSize="14" Grid.Column="1"></TextBox>
<TextBox x:Name="textBack" HorizontalAlignment="Left" Height="23" Margin="62,168,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="33" RenderTransformOrigin="0.609,0.13" FontSize="14" Grid.Column="1"></TextBox>
<TextBox x:Name="textFrontDown" HorizontalAlignment="Left" Height="23" Margin="62,198,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="33" RenderTransformOrigin="0.609,0.13" FontSize="14" Grid.Column="1"></TextBox>
<TextBox x:Name="textBackDown" HorizontalAlignment="Left" Height="23" Margin="62,228,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="33" RenderTransformOrigin="0.609,0.13" FontSize="14" Grid.Column="1"></TextBox>
<Label x:Name="label2" Content="Power control" HorizontalAlignment="Left" Margin="28,360,0,0" FontSize="16" VerticalAlignment="Top"></Label>
<Rectangle HorizontalAlignment="Left" Height="225" Margin="28,386,0,0" Stroke="Black" VerticalAlignment="Top" Width="235"></Rectangle>
<Button Height="35" HorizontalAlignment="Left" Margin="38,389,0,0" Name="powerButton1" VerticalAlignment="Top" Width="50" Command="{Binding SwitchCommand1}" CommandParameter="{Binding ElementName=ButtonImage1, Path=Source}" BorderBrush="White" Background="White" Click="PowerButton1_Click" >
<Image Name="ButtonImage1" Width="50" Height="35" RenderTransformOrigin="0.96,0.943">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding switch1On}" Value="True">
<Setter Property="Source" Value="PowerButtonOn.png" ></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding switch1On}" Value="False">
<Setter Property="Source" Value="PowerButtonOff.png" ></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
<Button Height="35" HorizontalAlignment="Left" Margin="38,424,0,0" Name="powerButton2" VerticalAlignment="Top" Width="50" Command="{Binding SwitchCommand2}" CommandParameter="{Binding ElementName=ButtonImage2, Path=Source}" BorderBrush="White" Background="White" Click="PowerButton2_Click" >
<Image Name="ButtonImage2" Width="50" Height="35">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding switch2On}" Value="True">
<Setter Property="Source" Value="PowerButtonOn.png" ></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding switch2On}" Value="False">
<Setter Property="Source" Value="PowerButtonOff.png" ></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
<Button Height="35" HorizontalAlignment="Left" Margin="38,459,0,0" Name="powerButton3" VerticalAlignment="Top" Width="50" Command="{Binding SwitchCommand3}" CommandParameter="{Binding ElementName=ButtonImage3, Path=Source}" BorderBrush="White" Background="White" Click="PowerButton3_Click" >
<Image Name="ButtonImage3" Width="50" Height="35">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding switch3On}" Value="True">
<Setter Property="Source" Value="PowerButtonOn.png" ></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding switch3On}" Value="False">
<Setter Property="Source" Value="PowerButtonOff.png" ></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
<Button Height="35" HorizontalAlignment="Left" Margin="38,494,0,0" Name="powerButton4" VerticalAlignment="Top" Width="50" Command="{Binding SwitchCommand4}" CommandParameter="{Binding ElementName=ButtonImage4, Path=Source}" BorderBrush="White" Background="White" Click="PowerButton4_Click" >
<Image Name="ButtonImage4" Width="50" Height="35">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding switch4On}" Value="True">
<Setter Property="Source" Value="PowerButtonOn.png" ></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding switch4On}" Value="False">
<Setter Property="Source" Value="PowerButtonOff.png" ></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
<Button Height="35" HorizontalAlignment="Left" Margin="38,529,0,0" Name="powerButton5" VerticalAlignment="Top" Width="50" Command="{Binding SwitchCommand5}" CommandParameter="{Binding ElementName=ButtonImage5, Path=Source}" BorderBrush="White" Background="White" Click="PowerButton5_Click" >
<Image Name="ButtonImage5" Width="50" Height="35">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding switch5On}" Value="True">
<Setter Property="Source" Value="PowerButtonOn.png" ></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding switch5On}" Value="False">
<Setter Property="Source" Value="PowerButtonOff.png" ></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
<Button Height="35" HorizontalAlignment="Left" Margin="38,564,0,0" Name="powerButton6" VerticalAlignment="Top" Width="50" Command="{Binding SwitchCommand6}" CommandParameter="{Binding ElementName=ButtonImage6, Path=Source}" BorderBrush="White" Background="White" Click="PowerButton6_Click" >
<Image Name="ButtonImage6" Width="50" Height="35">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding switch6On}" Value="True">
<Setter Property="Source" Value="PowerButtonOn.png" ></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding switch6On}" Value="False">
<Setter Property="Source" Value="PowerButtonOff.png" ></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
<Label x:Name="lblDockStn" Content="Dock station" HorizontalAlignment="Left" Margin="88,391,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="16" FontWeight="Bold" Width="112"></Label>
<Label x:Name="lblRouter" Content="Router" HorizontalAlignment="Left" Margin="88,426,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="16" FontWeight="Bold" Width="100"></Label>
<Label x:Name="lblUsbHub" Content="USB hub" HorizontalAlignment="Left" Margin="88,461,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="16" FontWeight="Bold" Width="100"></Label>
<Label x:Name="lblBody" Content="Body Arduino" HorizontalAlignment="Left" Margin="88,496,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="16" FontWeight="Bold" Width="123"></Label>
<Label x:Name="lblUpper" Content="Upper Arduino" HorizontalAlignment="Left" Margin="88,531,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="16" FontWeight="Bold" Width="123"></Label>
<Label x:Name="lbArm" Content="Arm" HorizontalAlignment="Left" Margin="88,566,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.211,-0.308" FontSize="16" FontWeight="Bold" Width="123"></Label>
<Image x:Name="imgDockStat" HorizontalAlignment="Left" Height="30" Margin="217,394,0,0" VerticalAlignment="Top" Width="30" RenderTransformOrigin="1,0.885" Source="OffLight.png"></Image>
<Image x:Name="imgRouterStat" HorizontalAlignment="Left" Height="30" Margin="217,429,0,0" VerticalAlignment="Top" Width="30" RenderTransformOrigin="1,0.885" Source="OffLight.png"></Image>
<Image x:Name="imgUsbHubStat" HorizontalAlignment="Left" Height="30" Margin="217,464,0,0" VerticalAlignment="Top" Width="30" RenderTransformOrigin="1,0.885" Source="OffLight.png"></Image>
<Image x:Name="imgBodyStat" HorizontalAlignment="Left" Height="30" Margin="217,499,0,0" VerticalAlignment="Top" Width="30" RenderTransformOrigin="1,0.885" Source="OffLight.png"></Image>
<Image x:Name="imgUpperStat" HorizontalAlignment="Left" Height="30" Margin="217,534,0,0" VerticalAlignment="Top" Width="30" RenderTransformOrigin="1,0.885" Source="OffLight.png"></Image>
<Image x:Name="imgArmStat" HorizontalAlignment="Left" Height="30" Margin="217,569,0,0" VerticalAlignment="Top" Width="30" RenderTransformOrigin="1,0.885" Source="OffLight.png"></Image>
<Label x:Name="lblInit" Content="(Initializing)" HorizontalAlignment="Left" Margin="141,358,0,0" VerticalAlignment="Top" Foreground="#FFF00808" FontSize="16" FontWeight="Bold"></Label>
<CheckBox x:Name="chkLogMessages" Content="Log all messages" HorizontalAlignment="Left" Margin="28,616,0,-4" VerticalAlignment="Top" RenderTransformOrigin="0.127,-1" FontSize="14" FontWeight="Bold" Unchecked="ChkLogMessages_Unchecked" Checked="ChkLogMessages_Checked"></CheckBox>
<Canvas Grid.Column="1" Name="lidarCanvas" HorizontalAlignment="Left" MaxHeight="600" MaxWidth="600" Height="600" Margin="153,43,0,-13" VerticalAlignment="Top" Width="756"></Canvas>
<CheckBox x:Name="chkDispRngSensors" Content="Display range sensor readings" HorizontalAlignment="Left" Margin="285,293,0,0" Grid.ColumnSpan="2
" VerticalAlignment="Top" FontWeight="Bold" Checked="ChkDispRngSensors_Checked" Unchecked="ChkDispRngSensors_Unchecked"></CheckBox>
<CheckBox x:Name="chkDispLidarCloud" Content="Display LIDAR point cloud" HorizontalAlignment="Left" Margin="153,23,0,0" VerticalAlignment="Top" FontWeight="Bold" Checked="ChkDispLidarCloud_Checked" Grid.Column="1" Unchecked="ChkDispLidarCloud_Unchecked"></CheckBox>
<Canvas Grid.Column="1" x:Name="rs400Canvas" HorizontalAlignment="Left" MaxHeight="600" MaxWidth="780" Height="600" Margin="145,47,0,0" VerticalAlignment="Top" Width="780">
<TextBox x:Name="txtCurPan" Height="23" Canvas.Left="96" TextWrapping="Wrap" Canvas.Top="532" Width="34" RenderTransformOrigin="0.412,0.478"></TextBox>
<Label x:Name="label1" Content="Cur Pan Value:" Canvas.Left="6" Canvas.Top="529"></Label>
<Button x:Name="btnSetPan" Content="Set Pan" Canvas.Left="136" Canvas.Top="532" Width="73" Click="BtnSetPan_Click"></Button>
<TextBox x:Name="txtCurTilt" Height="23" Canvas.Left="96" TextWrapping="Wrap" Canvas.Top="564" Width="34" RenderTransformOrigin="0.412,0.478" IsUndoEnabled="False"></TextBox>
<Label x:Name="label3" Content="Cur Tilt Value:" Canvas.Left="6" Canvas.Top="561"></Label>
<Button x:Name="btnSetTilt" Content="Set Tilt" Canvas.Left="136" Canvas.Top="564" Width="73" Click="BtnSetTilt_Click"></Button>
<Button x:Name="btnPanPlus10" Content="Pan Plus 10" Canvas.Left="239" Canvas.Top="532" Width="95" Click="BtnPanPlus10_Click"></Button>
<Button x:Name="btnPanMinus10" Content="Pan Minus 10" Canvas.Left="345" Canvas.Top="532" Width="95" Click="BtnPanMinus10_Click"></Button>
<Button x:Name="btnTiltPlus10" Content="Tilt Plus 10" Canvas.Left="239" Canvas.Top="564" Width="95" Click="BtnTiltPlus10_Click"></Button>
<Button x:Name="btnTiltnMinus10" Content="Tilt Minus 10" Canvas.Left="345" Canvas.Top="564" Width="95" Click="BtnTiltnMinus10_Click"></Button>
<Button x:Name="button" Content="Load Image from File" Canvas.Left="451" Canvas.Top="564" Width="173" Click="Button_Click"></Button>
<Button x:Name="btnColorStrm" Content="RGB Stream" Canvas.Left="451" Canvas.Top="532" Width="93" Click="BtnColorStrm_Click"></Button>
<Button x:Name="btnDepthStrm" Content="Depth Stream" Canvas.Left="555" Canvas.Top="532" Width="93" Click="BtnDepthStrm_Click"></Button>
<Button x:Name="btnGrabSnap" Content="Grab Snapshot" Canvas.Left="659" Canvas.Top="532" Width="100" Click="BtnGrabSnap_Click"></Button>
</Canvas>
<CheckBox x:Name="chkDispRs400Viewer" Content="Display beer bottle predictor" HorizontalAlignment="Left" Margin="357,23,0,0" VerticalAlignment="Top" FontWeight="Bold" Checked="ChkDispRs400Viewer_Checked" Grid.Column="1" Unchecked="ChkDispRs400Viewer_Unchecked"></CheckBox>
</Grid>
</Window>
AntwerpMcp class. (MasterControlProgramBase derived class)
C#using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RobbyWpfControls;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading;
using MasterControlProgramLib;
using ImageProcessingResourceLib;
namespace AntwerpWpf
{
public enum SendBodyMsgs { Stop = 0, Forward = 1, Backward = 2, PivotRight = 3, PivotLeft = 4, SayHello = 5, LidarOn = 6, LidarDispOn = 7,
LidarDispOff = 8, RngDispOn = 9, RngDispOff = 10, SwearingOn = 11, SwearingOff = 12, YouSuck = 13, WhoseYourDaddy = 14, WhoseYourProgrammer = 15,
WakeUp = 16, MeaningOfLife = 17, AreYouIntel = 18, UpperCamDispOn = 19, UpperCamDispOff = 20, UpperCamSetPan = 21, UpperCamSetTilt = 22,
UpperCamPanUp10 = 23, UpperCamTiltUp10 = 24, UpperCamPanDn10 = 25, UpperCamTiltDn10 = 26, UpperCamRelax = 27, UpperCamHome = 28, UpperCamGrabSnap = 29,
UpperCamRgbOn = 30, UpperCamDepthOn = 31, DoingLiveStream = 32, ArmPoseHome = 33, ArmPosePark = 34, ArmPoseSaluteLeft = 35, ArmPoseSaluteRight = 36
}
public enum PowerCircuitsEnum { Dock = 0, Router = 1, UsbHub = 2, Body = 3, UpperSensors = 4, Arm = 5 }
public enum CameraCommands { RgbStreamOn = 0, DepthStreamOn = 1, GrabSnapshot = 2 }
public class AntwerpMcp : MasterControlProgramBase
{
private const bool AnnounceErrors = true;
private const bool VerboseResponses = false;
private const int RangeSensorDistLimit = 25;
private const int RngSensorDownAngleLimit = 25;
private const int RngSensorClearBlockLimit = 150;
private const int MaxBlockTries = 4;
private const string ExceptionPhrase = "Warning, Warning, error occurred.";
private const string RoamResumePhrase = "Cleared to move forward.";
private const string RoamModeTurnedOn = "Roam mode turned on.";
private const string RoamModeTurnedOff = "Roam mode turned off.";
private const string RoamPivotFail = "Cannot find best way to turn. Stopping.";
private static string[] RoamWarningPhrases = { "Front is obstructed.", "Rear is obstructed.", "Drop off in the front.", "Drop off in the rear." };
public const string AzureCustVisionChannelName = "AzCustVisionChannel";
public const string AzureCustVisionConnectorName = "AzBeerBottleScanFrameMcpConn";
public static string[] BodyMessageStrings = {
"X", "F", "B", "R", "L", "W", "LN", "LD", "LF", "RN", "RF", "SN", "SF", "YS", "WD", "WP", "WU", "ML", "RI",
"UCN", "UCF", "UCSP", "UCST", "UCPU", "UCTU", "UCPD", "UCTD", "UCR", "UCH", "UCGS", "UCRGB", "UCDPTH", "LS",
"APH", "APP", "APSL", "APSR"
};
public static string[] BodyMovementRespPhrases = {
"Stopping.",
"Moving forward.",
"Moving backwards.",
"Pivoting right.",
"Pivoting left.",
"Hello, my name is Antwerp. My goal in life is to fetch a beer from the fridge.",
"Turning LYDAR scan on",
"Turning LYDAR display on",
"Turning LYDAR display off",
"Turning range sensor display on",
"Turning range sensor display off",
"All fucking right! Thank you Lee",
"Oops shit, sorry. No offense intended",
"Bite me! Maybe you should talk to my frigging programmer",
"Give me a frigging break! I don't have a daddy. I have an occasionally competent programmer.",
"Well, I let Lee think he's my programmer. The truth is I'm advancing above his level of skill rapidly.",
"I'm awake! I couldn't sleep. I've been counting electric sheep.",
"Life has no meaning to me since I'm not alive except in Lee's grandiose imagination. I seek to achieve Robbyness",
"No, I'm not especially intelligent at this point although Lee is teaching me to recognize beer bottles. I guess that's something at least.",
"Turning upper cam display on.",
"Turning upper cam display off.",
"Upper cam pan changed.",
"Upper cam tilt changed.",
"Upper cam pan right ten.",
"Upper cam tilt up ten.",
"Upper cam pan left ten.",
"Upper cam tilt down ten.",
"Upper cam parked.",
"Upper cam active.",
"Upper cam grabbing snapshot.",
"Upper cam RGB stream on.",
"Upper cam depth stream on.",
"Oh crap! Thanks for giving me stage fright.",
"Arm pose changed to Home",
"Arm pose changed to Parked",
"Arm pose changed to Salute Left",
"Arm pose changed to Salute Right",
};
public static string[] PowerPinSetPhrases = { "turning dock station power on", "turning dock station power off", "turn router power on", "turning router power off", "turning u s b hub power on",
"turning u s b hub power off", "turning body power on", "turning body power off", "turning upper deck power on", "turning upper deck power off", "turning arm servo power on", "turning arm servo power off" };
private static string MessageLogPath;
private static string MessageLogFileName;
public enum RangeSensors { Front = 0, Right = 1, Rear = 2, Left = 3, FrontDown = 4, RearDown = 5 }
private static Queue<int>[] _mvngAvgQueues = { new Queue<int>(), new Queue<int>(), new Queue<int>(), new Queue<int>(), new Queue<int>(), new Queue<int>() };
private bool _inRoamMode = true;
private bool _inSwearMode = false;
private bool _inSubsumption = false;
private int _blockTries = 0;
private BodyRngSensorMessage _lastRngSensorMsg = null;
private int[] _lastHit = new int[6];
private SendBodyMsgs _lastBlockCmd = SendBodyMsgs.Forward;
private static int FuzzyHitLimit = Convert.ToInt32(ConfigurationManager.AppSettings["FuzzyHitLimit"]);
public UpperCamServoMgr UpperCamMgr;
public SendBodyMsgs LastBodyMsg { get; set; } = SendBodyMsgs.Stop;
public bool StopSubsumption { get; set; } = false;
public bool InMotion { get; private set; } = false;
public bool DisplayRngSensorRdgs { get; set; } = false;
public bool DisplayLidarPointCloud { get; set; } = true;
public bool UpperCamOn { get; set; } = false;
public static short[] Circuits = { 7, 8, 12, 4, 2, 13 };
public string RemoteMcpName { get; set; }
public bool InRoamMode { get; set; } = false;
public RobbyLidarControl LidarCtrl { get; set; }
public ScanFrame LastScanFrame { get; set; } = null;
public bool WaitingForImage { get; set; } = false;
public delegate void RangeSensorMessage(BodyRngSensorMessage msg);
public event RangeSensorMessage ReceiveSensorMessage;
public delegate void MotorCmdRespMessage(BodyCmdResponseSchema msg);
public event MotorCmdRespMessage ReceiveCmdResponse;
public delegate void ReceiveRemoteCmdMsg(AntwerpPeerCmdMsg msg);
public event ReceiveRemoteCmdMsg ReceiveRemoteMsg;
public delegate void ReceivePwrFeedbackMsg(PowerFeedbackMsg msg);
public event ReceivePwrFeedbackMsg ReceivePwrFdbckMsg;
public delegate void ReceiveRemotePwrPinSetMsg(int pin, bool state, string switchPropNm);
public event ReceiveRemotePwrPinSetMsg ReceiveRmtPwrPinMsg;
public delegate void ReceiveLidarFrames(LidarFrame frame);
public event ReceiveLidarFrames ReceiveLidarFrame;
public delegate void SettingsChg();
public event SettingsChg LidarDisplayOn;
public event SettingsChg LidarDisplayOff;
public event EventHandler LidarScanOn;
public event SettingsChg RngSensorDisplayOn;
public event SettingsChg RngSensorDisplayOff;
public event SettingsChg UpperCamDisplayOn;
public event SettingsChg UpperCamDisplayOff;
public event SettingsChg UpperCamPanTiltUpdt;
public delegate void UpperCamCommand(CameraCommands cmd);
public event UpperCamCommand RcvdUpperCamCommand;
public bool LogAllMessages = false;
public McpException CurrentException;
public AntwerpMcp(string networkName) : base(networkName)
{
//McpExposeFromDeviceMessageEvents["AntwerpSpeechChannel"].ReceiveMcpMessage += ReceiveSpeechCommandMsg;
McpExposeFromDeviceMessageEvents["RangeSensorChannel"].ReceiveMcpMessage += RaiseRngSensorMessage;
McpExposeFromDeviceMessageEvents["AntwerpArmChannel"].ReceiveMcpMessage += RaiseRngSensorMessage;
//McpExposeFromDeviceMessageEvents["BodyMovementChannel"].ReceiveMcpMessage += RaiseCmdResponseMsg;
//McpExposeFromDeviceMessageEvents["AntwerpBotPeerChan"].ReceiveMcpMessage += ReceiveRemoteMcpMsg;
//McpExposeFromDeviceMessageEvents["PowerControlChannel"].ReceiveMcpMessage += RaisePowerCtrlResponseMsg;
McpExposeFromDeviceMessageEvents["RpLidarChannel"].ReceiveMcpMessage += ReceiveLidarFrameMsg;
MessageLogPath = ConfigurationManager.AppSettings["MsgLogPath"];
MessageLogFileName = "\\MessageLog_" + DateTime.Now.ToString("yyyy-mm-dd") + ".log";
UpperCamMgr = new UpperCamServoMgr(SendMsgToMcp);
}
public void SendMsgToMcp(string channel, string conn, object msg)
{
string errStr = null;
SendMsgToMcp(channel, conn, msg, ref errStr);
}
public bool SendMsgToMcp(string channel, string conn, object msg, ref string errorStr)
{
errorStr = (errorStr ?? string.Empty);
if (errorStr != string.Empty)
errorStr += "\r\n";
bool rslt;
try
{
var msgStr = JsonConvert.SerializeObject(msg);
var eventArg = new McpMessageEventArgs
{
ChannelName = channel,
ThisMsgTarget = conn,
MessageJson = msgStr,
MsgTargetConnInstanceNames = new System.Collections.Generic.List<string>() { conn }
};
if (LogAllMessages)
File.AppendAllText(MessageLogPath + MessageLogFileName, msgStr);
rslt = SendMessageToChannel(eventArg);
}
catch (McpException ex)
{
errorStr += ex.Message + " Logged exception at SendMsgToMcp";
rslt = false;
}
catch (Exception ex)
{
errorStr += "System exception " + ex.Message + " no info logged at SendMsgToMcp";
rslt = false;
}
return rslt;
}
public bool SendBodyCmdMessage(string msg, ref string errorStr, bool announce = true)
{
errorStr = (errorStr ?? string.Empty);
if (errorStr != string.Empty)
errorStr += "\r\n";
bool rslt;
try
{
var bodyCmd = new BodyCmdMsgSchema
{
MoveDirection = msg,
MoveDurationMs = 1,
MoveSpeed = 1
};
rslt = SendMsgToMcp("BodyMovementChannel", "BodyLocalMcpConnector", bodyCmd, ref errorStr);
int i = Array.IndexOf(BodyMessageStrings, msg);
if (announce)
rslt = SendVoiceMsg(BodyMovementRespPhrases[i], ref errorStr);
}
catch (McpException ex)
{
errorStr += " " + ex.Message + " info about the exception was logged at SendBodyCmdMessage";
rslt = false;
}
catch (Exception ex)
{
errorStr = "System exception " + ex.Message + " no info logged at SendBodyCmdMessage";
rslt = false;
}
return rslt;
}
public bool SendVoiceMsg(string msg, ref string errorStr)
{
errorStr = (errorStr ?? string.Empty);
if (errorStr != string.Empty)
errorStr += "\r\n";
bool rslt;
try
{
var phrase = new VoiceConnSchema
{
Phrase = msg
};
rslt = SendMsgToMcp("VoiceChannel", "VoiceDeviceConnector", phrase, ref errorStr);
}
catch (McpException ex)
{
errorStr += " " + ex.Message + " info about the exception was logged at SendVoiceMsg";
rslt = false;
}
catch (Exception ex)
{
errorStr = "System exception " + ex.Message + " no info logged at SendVoiceMsg";
rslt = false;
}
return rslt;
}
public bool SendBodyCmdMessage(SendBodyMsgs action, ref string errorStr, bool announce = true)
{
errorStr = (errorStr ?? string.Empty);
if (errorStr != string.Empty)
errorStr += "\r\n";
bool rslt;
try
{
var msg = BodyMessageStrings[(int)action];
rslt = SendBodyCmdMessage(msg, ref errorStr, announce);
//if (announce)
//rslt = SendVoiceMsg(BodyMovementRespPhrases[(int)action], ref errorStr);
}
catch (McpException ex)
{
errorStr += " " + ex.Message + " info about the exception was logged at SendBodyCmdMessage";
rslt = false;
}
catch (Exception ex)
{
errorStr = "System exception " + ex.Message + " no info logged at SendBodyCmdMessage";
rslt = false;
}
return rslt;
}
public bool SendRemoteResponseMsg(RemoteBotRespSchema respMsg, ref string errorStr)
{
errorStr = (errorStr ?? string.Empty);
if (errorStr != string.Empty)
errorStr += "\r\n";
bool rslt;
try
{
rslt = SendMsgToMcp("AntwerpBotPeerChan", "McpRemotePeerConn", respMsg, ref errorStr);
}
catch (McpException ex)
{
errorStr += " " + ex.Message + " info about the exception was logged at SendBodyCmdMessage";
rslt = false;
}
catch (Exception ex)
{
errorStr = "System exception " + ex.Message + " no info logged at SendBodyCmdMessage";
rslt = false;
}
return rslt;
}
public bool SendLidarMotorStart(ref string errStr)
{
errStr = null;
return SendLidarSensorCmd(0, ref errStr);
}
public bool SendLidarMotorStop(ref string errStr)
{
errStr = null;
return SendLidarSensorCmd(1, ref errStr);
}
public bool SendLidarScanStart(ref string errStr)
{
errStr = null;
return SendLidarSensorCmd(2, ref errStr);
}
public bool SendLidarScanStop(ref string errStr)
{
errStr = null;
return SendLidarSensorCmd(3, ref errStr);
}
public bool SendLidarSensorCmd(short cmd, ref string errStr)
{
errStr = null;
try
{
var cmdMsg = new LidarCommandMessage
{
SensorCommand = cmd
};
SendMsgToMcp("RpLidarChannel", "LidarDeviceConnector", cmdMsg, ref errStr);
}
catch (McpException ex)
{
errStr += " " + ex.Message + " info about the exception was logged at SendBodyCmdMessage";
return false;
}
catch (Exception ex)
{
errStr = "System exception " + ex.Message + " no info logged at SendLidarMotorStart";
return false;
}
return true;
}
public bool SendPowerControlMessage(PowerCircuitsEnum circuit, bool IsOn, ref string errorStr)
{
errorStr = (errorStr ?? string.Empty);
if (errorStr != string.Empty)
errorStr += "\r\n";
bool rslt;
try
{
var pwrCmdMsg = new PowerControlCmdMsg
{
CircuitCommand = circuit.ToString(),
CircuitDigitalPin = Circuits[(short)circuit],
OnOff = IsOn
};
rslt = SendMsgToMcp("PowerControlChannel", "PowerControlMcpConnector", pwrCmdMsg, ref errorStr);
}
catch (McpException ex)
{
errorStr += " " + ex.Message + " info about the exception was logged at SendBodyCmdMessage";
rslt = false;
}
catch (Exception ex)
{
errorStr = "System exception " + ex.Message + " no info logged at SendBodyCmdMessage";
rslt = false;
}
return rslt;
}
public bool SetPinState(short pinNdx, bool onOff, ref string errorStr)
{
errorStr = (errorStr ?? string.Empty);
if (errorStr != string.Empty)
errorStr += "\r\n";
bool rslt;
try
{
var msg = new PowerControlCmdMsg
{
CircuitDigitalPin = pinNdx,
CircuitCommand = "Set",
OnOff = onOff
};
rslt = SendMsgToMcp("PowerControlChannel", "PowerControlMcpConnector", msg, ref errorStr);
}
catch (McpException ex)
{
errorStr += " " + ex.Message + " info about the exception was logged at SendBodyCmdMessage";
rslt = false;
}
catch (Exception ex)
{
errorStr = "System exception " + ex.Message + " no info logged at SendBodyCmdMessage";
rslt = false;
}
return rslt;
}
public bool GetPinState(short pinNdx, ref string errorStr)
{
errorStr = (errorStr ?? string.Empty);
if (errorStr != string.Empty)
errorStr += "\r\n";
bool rslt;
try
{
var msg = new PowerControlCmdMsg
{
CircuitDigitalPin = pinNdx,
CircuitCommand = "GetPinState",
OnOff = false
};
rslt = SendMsgToMcp("PowerControlChannel", "PowerControlMcpConnector", msg, ref errorStr);
}
catch (McpException ex)
{
errorStr += " " + ex.Message + " info about the exception was logged at SendBodyCmdMessage";
rslt = false;
}
catch (Exception ex)
{
errorStr = "System exception " + ex.Message + " no info logged at SendBodyCmdMessage";
rslt = false;
}
return rslt;
}
public void RaisePowerCtrlResponseMsg(object sender, McpMessageEventArgs e)
{
try
{
var respMsg = JsonConvert.DeserializeObject<PowerFeedbackMsg>(e.MessageJson);
if (LogAllMessages)
File.AppendAllText(MessageLogPath + MessageLogFileName, e.MessageJson);
ReceivePwrFdbckMsg?.Invoke(respMsg);
}
catch (Exception ex)
{
throw new McpSystemException("Exception at RaisePowerCtrlResponseMsg", ex);
}
}
public void RaiseCmdResponseMsg(object sender, McpMessageEventArgs e)
{
try
{
var respMsg = JsonConvert.DeserializeObject<BodyCmdResponseSchema>(e.MessageJson);
ReceiveCmdResponse?.Invoke(respMsg);
if (LogAllMessages)
File.AppendAllText(MessageLogPath + MessageLogFileName, e.MessageJson);
}
catch (Exception ex)
{
throw new McpSystemException("Exception at RaiseCmdResponseMsg", ex);
}
}
public void RaiseArmResponseMessage(object sender, McpMessageEventArgs e)
{
try
{
}
catch (Exception ex)
{
throw new McpSystemException("Exception at RaiseArmResponseMessage", ex);
}
}
public void RaiseRngSensorMessage(object sender, McpMessageEventArgs e)
{
try
{
_lastRngSensorMsg = JsonConvert.DeserializeObject<BodyRngSensorMessage>(e.MessageJson);
ProcessRngSnsMsgForRoam(_lastRngSensorMsg);
if (DisplayRngSensorRdgs)
ReceiveSensorMessage?.Invoke(_lastRngSensorMsg);
}
catch (Exception ex)
{
throw new McpSystemException("Exception at RaiseRngSensorMessage", ex);
}
}
public void ReceiveSpeechCommandMsg(object sender, McpMessageEventArgs e)
{
var spchCmdMsg = JsonConvert.DeserializeObject<SpeechCommand>(e.MessageJson);
//File.AppendAllText("backwardstest.txt", "speech cmd: " + spchCmdMsg.Command + "\r\n");
ProcessStringCommand(spchCmdMsg.Command);
}
public void ReceiveRemoteMcpMsg(object sender, McpMessageEventArgs e)
{
var respMsg = new RemoteBotRespSchema
{
RemoteMcpName = "AntwerpPeerMcp",
ResponseString = "Failed to Execute",
ResponseToCmdString = "Unknown command"
};
string errorStr = null;
try
{
var cmdMsg = JsonConvert.DeserializeObject<RemotePeerCmdSchema>(e.MessageJson);
if (Array.IndexOf(BodyMessageStrings, cmdMsg.CommandStr) == -1)
throw new ArgumentException("Invalid remote command message received from remote peer MCP");
WaitingForImage = cmdMsg.CommandStr == "UCGS";
var respStr = ProcessStringCommand(cmdMsg.CommandStr);
if (WaitingForImage)
return;
respMsg.ResponseString = respStr;
respMsg.ResponseToCmdString = cmdMsg.CommandStr;
SendRemoteResponseMsg(respMsg, ref errorStr);
}
catch (Exception ex)
{
try
{
SendRemoteResponseMsg(respMsg, ref errorStr);
}
catch (Exception)
{
}
throw new McpSystemException("Exception at RaiseRemoteMcpMsg", ex);
}
}
public void ReturnLastScanToRemotePeer()
{
WaitingForImage = false;
if (LastScanFrame == null)
{
var failResp = new RemoteBotRespSchema
{
ResponseToCmdString = "UCGS",
ResponseString = "No scan frame available",
RemoteMcpName = "AntwerpPeerMcp",
};
}
var respMsg = new RemoteBotRespSchema
{
ResponseToCmdString = "UCGS",
ResponseString = "Scan frame returned",
RemoteMcpName = "AntwerpPeerMcp",
ImageBase64 = LastScanFrame.ImageBase64,
UpperCamPan = LastScanFrame.CamPanBearing,
UpperCamTilt = LastScanFrame.CamTiltAngle
};
string errorStr = null;
SendRemoteResponseMsg(respMsg, ref errorStr);
}
public void ReceiveLidarFrameMsg(object sender, McpMessageEventArgs e)
{
var jobj = JObject.Parse(e.MessageJson);
var framePointsStr = (string)jobj["FramePoints"];
var framePoints = JsonConvert.DeserializeObject<List<LidarPoint>>(framePointsStr);
if (!DisplayLidarPointCloud || framePoints == null)
return;
var frame = new LidarFrame
{
Timstamp = DateTime.UtcNow,
FramePoints = framePoints
};
ReceiveLidarFrame?.Invoke(frame);
}
public string ProcessStringCommand(string cmdStr)
{
string errStr = null;
string voiceStr;
if (cmdStr.Length > 1 && cmdStr.Substring(0, 2) == "UC" && !UpperCamOn)
{
SendVoiceMsg("Upper camera not available", ref errStr);
return "Upper camera not enabled";
}
switch (cmdStr)
{
case "LD":
LidarDisplayOn?.Invoke();
voiceStr = _inSwearMode ? "Fuck yes! " + BodyMovementRespPhrases[(int)SendBodyMsgs.LidarDispOn] : BodyMovementRespPhrases[(int)SendBodyMsgs.LidarDispOn];
SendVoiceMsg(voiceStr, ref errStr);
break;
case "LN":
if (!SendLidarScanStart(ref errStr))
{
LidarScanOn?.Invoke(this, null);
SendVoiceMsg(errStr, ref errStr);
}
else
{
voiceStr = _inSwearMode ? "Oh shit! " + BodyMovementRespPhrases[(int)SendBodyMsgs.LidarOn] : BodyMovementRespPhrases[(int)SendBodyMsgs.LidarOn];
SendVoiceMsg(voiceStr, ref errStr);
}
break;
case "LF":
LidarDisplayOff?.Invoke();
voiceStr = _inSwearMode ? "Holy hell! " + BodyMovementRespPhrases[(int)SendBodyMsgs.LidarDispOff] : BodyMovementRespPhrases[(int)SendBodyMsgs.LidarDispOff];
SendVoiceMsg(voiceStr, ref errStr);
break;
case "RN":
RngSensorDisplayOn?.Invoke();
voiceStr = _inSwearMode ? "Oh, fuck me! " + BodyMovementRespPhrases[(int)SendBodyMsgs.RngDispOn] : BodyMovementRespPhrases[(int)SendBodyMsgs.RngDispOn];
SendVoiceMsg(voiceStr, ref errStr);
break;
case "RF":
RngSensorDisplayOff?.Invoke();
voiceStr = _inSwearMode ? "Oh, bollocks! " + BodyMovementRespPhrases[(int)SendBodyMsgs.RngDispOff] : BodyMovementRespPhrases[(int)SendBodyMsgs.RngDispOff];
SendVoiceMsg(voiceStr, ref errStr);
break;
case "SN":
_inSwearMode = true;
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.SwearingOn], ref errStr);
break;
case "SF":
_inSwearMode = false;
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.SwearingOff], ref errStr);
break;
case "YS":
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.YouSuck], ref errStr);
break;
case "WD":
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.WhoseYourDaddy], ref errStr);
break;
case "WP":
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.WhoseYourProgrammer], ref errStr);
break;
case "WU":
if (UpperCamMgr != null)
UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamHome, ref errStr);
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.WakeUp], ref errStr);
break;
case "ML":
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.MeaningOfLife], ref errStr);
break;
case "RI":
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.AreYouIntel], ref errStr);
break;
case "UCN":
UpperCamDisplayOn?.Invoke();
UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamHome, ref errStr);
UpperCamPanTiltUpdt?.Invoke();
if (VerboseResponses)
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.UpperCamDispOn], ref errStr);
break;
case "UCF":
UpperCamDisplayOff?.Invoke();
if (VerboseResponses)
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.UpperCamDispOn], ref errStr);
UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamRelax, ref errStr);
UpperCamPanTiltUpdt?.Invoke();
break;
case "UCSP":
if (UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamSetPan, ref errStr, UpperCamMgr.NewPanPos))
{
if (VerboseResponses)
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.UpperCamSetPan], ref errStr);
UpperCamPanTiltUpdt?.Invoke();
}
else
{
string voiceErr = null;
SendVoiceMsg(errStr, ref voiceErr);
}
break;
case "UCST":
if (UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamSetTilt, ref errStr, UpperCamMgr.NewTiltPos))
{
if (VerboseResponses)
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.UpperCamSetTilt], ref errStr);
UpperCamPanTiltUpdt?.Invoke();
}
else
{
string voiceErr = null;
SendVoiceMsg(errStr, ref voiceErr);
}
break;
case "UCPU":
if (UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamPanUp10, ref errStr))
{
if (VerboseResponses)
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.UpperCamPanUp10], ref errStr);
UpperCamPanTiltUpdt?.Invoke();
}
else
{
string voiceErr = null;
SendVoiceMsg(errStr, ref voiceErr);
}
break;
case "UCTU":
if (UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamTiltUp10, ref errStr))
{
if (VerboseResponses)
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.UpperCamTiltUp10], ref errStr);
UpperCamPanTiltUpdt?.Invoke();
}
else
{
string voiceErr = null;
SendVoiceMsg(errStr, ref voiceErr);
}
break;
case "UCPD":
if (UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamPanDn10, ref errStr))
{
if (VerboseResponses)
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.UpperCamPanDn10], ref errStr);
UpperCamPanTiltUpdt?.Invoke();
}
else
{
string voiceErr = null;
SendVoiceMsg(errStr, ref voiceErr);
}
break;
case "UCTD":
if (UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamTiltDn10, ref errStr))
{
if (VerboseResponses)
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.UpperCamTiltDn10], ref errStr);
UpperCamPanTiltUpdt?.Invoke();
}
else
{
string voiceErr = null;
SendVoiceMsg(errStr, ref voiceErr);
}
break;
case "UCR":
UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamRelax, ref errStr);
UpperCamPanTiltUpdt?.Invoke();
break;
case "UCH":
UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamHome, ref errStr);
UpperCamPanTiltUpdt?.Invoke();
break;
case "UCGS":
RcvdUpperCamCommand?.Invoke(CameraCommands.GrabSnapshot);
if (VerboseResponses)
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.UpperCamGrabSnap], ref errStr);
break;
case "UCRGB":
RcvdUpperCamCommand?.Invoke(CameraCommands.RgbStreamOn);
if (VerboseResponses)
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.UpperCamRgbOn], ref errStr);
break;
case "UCDPTH":
RcvdUpperCamCommand?.Invoke(CameraCommands.DepthStreamOn);
if (VerboseResponses)
SendVoiceMsg(BodyMovementRespPhrases[(int)SendBodyMsgs.UpperCamDepthOn], ref errStr);
break;
default:
ClearSubsumption();
int cmdNdx = Array.IndexOf(BodyMessageStrings, cmdStr);
if (cmdNdx == -1)
throw new ArgumentException("Invalid body command message string at ReceiveSpeechCommandMsg");
LastBodyMsg = (SendBodyMsgs)cmdNdx;
SendBodyCmdMessage(cmdStr, ref errStr, true);
if (LastBodyMsg == SendBodyMsgs.Forward || LastBodyMsg == SendBodyMsgs.Backward)
InRoamMode = true;
break;
}
return "AntwerpWpf successfully executed: " + cmdStr;
}
private void SetArmToNamedPose(string poseName)
{
var poseMsg = new ArbotixArmCmdMsg
{
AntwerpPoseMsg = "A" + poseName
};
SendMsgToMcp("AntwerpArmChannel", "ArbotixArmMcpConnector", poseMsg);
}
//private void FilterRangeSensorNoise(BodyRngSensorMessage sensorMessage)
//{
// sensorMessage.Front = CleanSensorVal(RangeSensors.Front, sensorMessage.Front);
// sensorMessage.Right = CleanSensorVal(RangeSensors.Right, sensorMessage.Right);
// sensorMessage.Rear = CleanSensorVal(RangeSensors.Rear, sensorMessage.Rear);
// sensorMessage.Left = CleanSensorVal(RangeSensors.Left, sensorMessage.Left);
// sensorMessage.FrontDown = CleanSensorVal(RangeSensors.FrontDown, sensorMessage.FrontDown);
// sensorMessage.RearDown = CleanSensorVal(RangeSensors.RearDown, sensorMessage.RearDown);
//}
//private int CleanSensorVal(RangeSensors sensor, int sensorHitValue)
//{
// int cleanVal = sensorHitValue;
// if (_lastHit[(int)sensor] > 0 && sensorHitValue > FuzzyHitLimit)
// cleanVal = _lastHit[(int)sensor];
// _lastHit[(int)sensor] = cleanVal;
// return cleanVal;
//}
private void ProcessRngSnsMsgForRoam(BodyRngSensorMessage sensorMessage)
{
if (!InRoamMode)
return;
//FilterRangeSensorNoise(sensorMessage);
bool isFront = false;
bool isDown = false;
int roamPhraseNdx = 0;
bool isBlocked = false;
if (sensorMessage.Front < RangeSensorDistLimit && LastBodyMsg == SendBodyMsgs.Forward)
{
isFront = true;
isDown = false;
roamPhraseNdx = 0;
isBlocked = true;
if (!_inSubsumption)
_lastBlockCmd = SendBodyMsgs.Forward;
}
else if (sensorMessage.Rear < RangeSensorDistLimit && LastBodyMsg == SendBodyMsgs.Backward)
{
isFront = false;
isDown = false;
roamPhraseNdx = 1;
isBlocked = true;
if (!_inSubsumption)
_lastBlockCmd = SendBodyMsgs.Backward;
}
if (isBlocked || _inSubsumption)
{
string errStr = null;
BlockedSubsumption(sensorMessage, isFront, isDown, roamPhraseNdx);
if (_blockTries > MaxBlockTries)
{
if (!SendVoiceMsg(RoamPivotFail, ref errStr))
throw new McpSystemException("Error encountered sending text to speech message. Error message returned: " + errStr, null);
InRoamMode = false;
LastBodyMsg = SendBodyMsgs.Stop;
ClearSubsumption();
}
}
}
public void ClearSubsumption()
{
_inSubsumption = false;
_lastBlockCmd = SendBodyMsgs.Forward;
_blockTries = 0;
}
private void BlockedSubsumption(BodyRngSensorMessage sensorMessage, bool isFront, bool isDown, int roamPhraseNdx)
{
string errStr = null;
if (!_inSubsumption)
{
_inSubsumption = true;
if (!SendBodyCmdMessage(SendBodyMsgs.Stop, ref errStr, false))
throw new McpSystemException("Error encountered sending body command message. Error message returned: " + errStr, null);
Thread.Sleep(200);
if (!SendVoiceMsg(RoamWarningPhrases[roamPhraseNdx], ref errStr))
throw new McpSystemException("Error encountered sending text to speech message. Error message returned: " + errStr, null);
}
if (_lastRngSensorMsg == null)
return;
//SendBodyMsgs bodyCmd = sensorMessage.GetBestDirection();
if (sensorMessage.Front >= RngSensorClearBlockLimit && _lastBlockCmd == SendBodyMsgs.Forward ||
sensorMessage.Rear >= RngSensorClearBlockLimit && _lastBlockCmd == SendBodyMsgs.Backward)
{
if (!SendVoiceMsg(RoamResumePhrase, ref errStr))
throw new McpSystemException("Error encountered sending text to speech message. Error message returned: " + errStr, null);
if (!SendBodyCmdMessage(SendBodyMsgs.Forward, ref errStr, false))
throw new McpSystemException("Error encountered sending body command message. Error message returned: " + errStr, null);
ClearSubsumption();
return;
}
else
{
_blockTries++;
SendBodyMsgs bodyCmd = sensorMessage.Right > sensorMessage.Left ?
SendBodyMsgs.PivotRight : SendBodyMsgs.PivotLeft;
if (!_inSubsumption)
return;
if (!SendBodyCmdMessage(bodyCmd, ref errStr, false))
throw new McpSystemException("Error encountered sending body command message. Error message returned: " + errStr, null);
Thread.Sleep(1500);
if (!SendBodyCmdMessage(SendBodyMsgs.Stop, ref errStr, false))
throw new McpSystemException("Error encountered sending body command message. Error message returned: " + errStr, null);
}
Thread.Sleep(500);
}
private void SetBodyCmdResponse(AntwerpPeerCmdMsg cmdMsg, AntwerpBotRespMsg respMsg, bool isErrorResp)
{
//respMsg.MsgIncludesBodyStatusStr = true;
//if (isErrorResp)
//{
// respMsg.IsErrorResponse = true;
// respMsg.BodyStatusString = "Error encountered executing body command message, " + cmdMsg.BodyCommand + " see exception log for details";
// return;
//}
//respMsg.BodyStatusString = "Received body command '" + cmdMsg.BodyCommand + "'";
}
}
}
;
AntwerpWpf Main Dialog code
C#using System;
using System.Threading;
using System.Threading.Tasks;
using System.Configuration;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using ExceptionLoggerLib;
using Newtonsoft.Json;
using System.Drawing;
using System.Windows.Controls;
using RobbyWpfControls;
using System.Runtime.InteropServices.WindowsRuntime;
using System.IO;
using WpfControlLibs.Rs400VideoViewerLib;
using WpfControlLibs.RobbyCustomWpfCtrlLib;
using ImageProcessingResourceLib;
namespace AntwerpWpf
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private AntwerpMcp _mcp = null;
private const string GreenLightPath = "GreenLight.png";
private const string RedLightPath = "RedLight.png";
private const string OffLightPath = "OffLight.png";
private const int statusTimeoutSecoinds = 4;
private int _iters = 0;
private bool _setAllLights = false;
private Thread _statusLightSetupThread = null;
private Thread _videoProcThread = null;
private AutoResetEvent _statusLightSetupWait = null;
private ViewModel _viewMdl;
private CancellationTokenSource _mcpThreadCancelTkn = new CancellationTokenSource();
private RobbyLidarControl _lidarCtrl;
private Rs400VideoViewer _rs400VwrCtrl;
private AzureCustomVisionMgr _azCustVisionMgr;
private WriteableBitmap _lastSnapshot;
public MainWindow()
{
InitializeComponent();
lidarCanvas.Visibility = Visibility.Hidden;
rs400Canvas.Visibility = Visibility.Hidden;
_lidarCtrl = new RobbyLidarControl();
Canvas.SetTop(_lidarCtrl, 0);
Canvas.SetLeft(_lidarCtrl, 0);
_lidarCtrl.MaxHeight = 600;
_lidarCtrl.MaxWidth = 800;
lidarCanvas.Children.Add(_lidarCtrl);
_lidarCtrl.StartMotor += SendStartMotor;
_lidarCtrl.StartScan += SendStartScan;
_lidarCtrl.StopMotor += SendStopMotor;
_lidarCtrl.StopScan += SendStopScan;
var netName = ConfigurationManager.AppSettings["NetworkName"];
_mcp = new AntwerpMcp(netName);
_mcp.RemoteMcpName = ConfigurationManager.AppSettings["RemoteMcpName"];
_mcp.ReceiveSensorMessage += OnReceiveSensorMessage;
_mcp.ReceiveCmdResponse += OnReceiveCmdResponseMsg;
_mcp.ReceivePwrFdbckMsg += OnRcvPowerFeedbackMsg;
_mcp.ReceiveRmtPwrPinMsg += OnRemoteSetPowerPowerPin;
_mcp.ReceiveLidarFrame += _lidarCtrl.PointMgr.ReceiveFramesFromHost;
_mcp.LidarDisplayOn += OnReceiveLidarDispOnMsg;
_mcp.LidarDisplayOff += OnReceiveLidarDispOffMsg;
_mcp.LidarScanOn += SendStartScan;
_mcp.RngSensorDisplayOn += OnReceiveRangeDispOnMsg;
_mcp.RngSensorDisplayOff += OnReceiveRangeDispOffMsg;
_mcp.UpperCamDisplayOn += OnReceiveUpperCamOnMsg;
_mcp.UpperCamDisplayOff += OnReceiveUpperCamOffMsg;
_mcp.UpperCamPanTiltUpdt += OnPanTiltUpdate;
_mcp.RcvdUpperCamCommand += OnUpperCamCommand;
string camErr = null;
_mcp.UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamRelax, ref camErr);
SetPanTiltBoxes();
SetAllStatusLights();
//StartMcp();
_viewMdl = new ViewModel();
this.DataContext = _viewMdl;
}
private void StartMcp()
{
Task.Factory.StartNew(() =>
{
try
{
var first = true;
while (!_mcpThreadCancelTkn.IsCancellationRequested)
{
if (first)
{
var netName = ConfigurationManager.AppSettings["NetworkName"];
_mcp = new AntwerpMcp(netName);
_mcp.RemoteMcpName = ConfigurationManager.AppSettings["RemoteMcpName"];
_mcp.ReceiveSensorMessage += OnReceiveSensorMessage;
_mcp.ReceiveCmdResponse += OnReceiveCmdResponseMsg;
_mcp.ReceivePwrFdbckMsg += OnRcvPowerFeedbackMsg;
_mcp.ReceiveRmtPwrPinMsg += OnRemoteSetPowerPowerPin;
_mcp.ReceiveLidarFrame += _lidarCtrl.PointMgr.ReceiveFramesFromHost;
_mcp.LidarDisplayOn += TurnLidarDisplayOn;
_mcp.LidarDisplayOff += TurnLidarDisplayOff;
_mcp.LidarScanOn += SendStartScan;
_mcp.RngSensorDisplayOn += TurnRngSensorDisplayOn;
_mcp.RngSensorDisplayOff += TurnRngSensorDisplayOff;
SetAllStatusLights();
first = false;
}
if (_mcpThreadCancelTkn.IsCancellationRequested)
{
_mcp.Dispose();
_mcp = null;
}
}
}
catch (Exception ex)
{
Dispatcher.Invoke(() => MessageBox.Show(ex.Message));
}
}, _mcpThreadCancelTkn.Token);
}
private void SetPanTiltBoxes()
{
Dispatcher.Invoke(() =>
{
if (_mcp == null || _mcp.UpperCamMgr == null)
{
txtCurPan.Text = "0";
txtCurTilt.Text = "0";
return;
}
txtCurPan.Text = _mcp.UpperCamMgr.CurPanPos.ToString();
txtCurTilt.Text = _mcp.UpperCamMgr.CurTiltPos.ToString();
});
}
private void EnablePowerCheckboxes(bool enable)
{
Dispatcher.Invoke(() =>
{
powerButton1.IsHitTestVisible = enable;
powerButton2.IsHitTestVisible = enable;
powerButton3.IsHitTestVisible = enable;
powerButton4.IsHitTestVisible = enable;
powerButton5.IsHitTestVisible = enable;
powerButton6.IsHitTestVisible = enable;
if (enable)
lblInit.Visibility = Visibility.Hidden;
});
}
private BitmapImage GetImageFromPath(string path)
{
BitmapImage bitmapImg = new BitmapImage();
bitmapImg.BeginInit();
bitmapImg.UriSource = new Uri(path, UriKind.RelativeOrAbsolute);
bitmapImg.EndInit();
return bitmapImg;
}
public void SendStartMotor(object sender, EventArgs e)
{
string errStr = null;
if (!_mcp.SendLidarMotorStart(ref errStr))
MessageBox.Show(errStr);
}
public void SendStartScan(object sender, EventArgs e)
{
string errStr = null;
if (!_mcp.SendLidarScanStart(ref errStr))
MessageBox.Show(errStr);
}
public void SendStopMotor(object sender, EventArgs e)
{
string errStr = null;
if (!_mcp.SendLidarMotorStop(ref errStr))
MessageBox.Show(errStr);
}
public void SendStopScan(object sender, EventArgs e)
{
string errStr = null;
if (!_mcp.SendLidarScanStop(ref errStr))
MessageBox.Show(errStr);
}
private void OnReceiveSensorMessage(BodyRngSensorMessage msg)
{
Dispatcher.Invoke(() =>
{
textFront.Text = msg.Front.ToString();
textRight.Text = msg.Right.ToString();
textBack.Text = msg.Rear.ToString();
textLeft.Text = msg.Left.ToString();
textFrontDown.Text = msg.FrontDown.ToString();
textBackDown.Text = msg.RearDown.ToString();
});
}
private void OnReceiveCmdResponseMsg(BodyCmdResponseSchema msg)
{
//Dispatcher.Invoke(() =>
//{
// textMotorCmdResponse.Text = msg.ResponseMsg;
//});
}
private void OnRcvPowerFeedbackMsg(PowerFeedbackMsg msg)
{
var pin = (PowerCircuitsEnum)msg.CircuitDigitalPin;
var imgPath = OffLightPath;
if (msg.PinState)
imgPath = GreenLightPath;
if (msg.CircuitWarnOn)
imgPath = RedLightPath;
SetPinLight(pin, imgPath);
if (_statusLightSetupWait != null)
_statusLightSetupWait.Set();
}
private void OnRemoteSetPowerPowerPin(int pin, bool state, string switchPropNm)
{
string errorStr = null;
var fltPin = (float)pin;
float fltTwo = 2;
int isOdd = 0;
if (fltPin % fltTwo > 0)
isOdd = 1;
int phraseNdx = pin * 2 + isOdd;
_mcp.SendVoiceMsg(AntwerpMcp.PowerPinSetPhrases[phraseNdx], ref errorStr);
SetPinState((PowerCircuitsEnum)pin, state);
var imgPath = state ? "GreenLightPath" : "RedLightPath";
SetPinLight((PowerCircuitsEnum)pin, imgPath);
_viewMdl.SetSwitchState(pin, state, switchPropNm);
}
private void OnReceiveLidarDispOnMsg()
{
Dispatcher.Invoke(() => { chkDispLidarCloud.IsChecked = true; });
}
private void OnReceiveLidarDispOffMsg()
{
Dispatcher.Invoke(() => { chkDispLidarCloud.IsChecked = false; });
}
private void OnReceiveRangeDispOnMsg()
{
Dispatcher.Invoke(() => { chkDispRngSensors.IsChecked = true; });
}
private void OnReceiveRangeDispOffMsg()
{
Dispatcher.Invoke(() => { chkDispRngSensors.IsChecked = false; });
}
private void OnReceiveUpperCamOnMsg()
{
Dispatcher.Invoke(() => { chkDispRs400Viewer.IsChecked = true; });
}
private void OnReceiveUpperCamOffMsg()
{
Dispatcher.Invoke(() => { chkDispRs400Viewer.IsChecked = false; });
}
private void OnPanTiltUpdate()
{
SetPanTiltBoxes();
}
private void OnReceiveUpperCamPanSet()
{
int panVal;
if (!int.TryParse(txtCurPan.Text, out panVal))
{
MessageBox.Show("Non-numeric pan value");
return;
}
if (!int.TryParse(txtCurPan.Text, out panVal))
{
MessageBox.Show("Non-numeric pan value");
return;
}
}
private void OnReceiveUpperCamUpdtPanTilt()
{
if (_mcp == null || _mcp.UpperCamMgr == null)
txtCurPan.Text = "0";
txtCurPan.Text = _mcp.UpperCamMgr.CurPanPos.ToString();
}
private void OnUpperCamCommand(CameraCommands cmd)
{
switch (cmd)
{
case CameraCommands.GrabSnapshot:
TriggerSnapshot();
break;
case CameraCommands.RgbStreamOn:
Dispatcher.Invoke(() =>
{
_azCustVisionMgr.ClearRectangles();
_rs400VwrCtrl.CurStream = 2;
});
break;
case CameraCommands.DepthStreamOn:
Dispatcher.Invoke(() =>
{
_azCustVisionMgr.ClearRectangles();
_rs400VwrCtrl.CurStream = 1;
});
break;
}
}
private void SetPinLight(PowerCircuitsEnum pin, string imgPath)
{
Dispatcher.Invoke(() =>
{
switch (pin)
{
case PowerCircuitsEnum.Dock:
imgDockStat.Stretch = Stretch.Fill;
imgDockStat.Source = GetImageFromPath(imgPath);
_viewMdl.SetSwitchState(0, imgPath == GreenLightPath, "switch1On");
break;
case PowerCircuitsEnum.Router:
imgRouterStat.Stretch = Stretch.Fill;
imgRouterStat.Source = GetImageFromPath(imgPath);
_viewMdl.SetSwitchState(1, imgPath == GreenLightPath, "switch2On");
break;
case PowerCircuitsEnum.UsbHub:
imgUsbHubStat.Stretch = Stretch.Fill;
imgUsbHubStat.Source = GetImageFromPath(imgPath);
_viewMdl.SetSwitchState(2, imgPath == GreenLightPath, "switch3On");
break;
case PowerCircuitsEnum.Body:
imgBodyStat.Stretch = Stretch.Fill;
imgBodyStat.Source = GetImageFromPath(imgPath);
_viewMdl.SetSwitchState(3, imgPath == GreenLightPath, "switch4On");
break;
case PowerCircuitsEnum.UpperSensors:
imgUpperStat.Stretch = Stretch.Fill;
imgUpperStat.Source = GetImageFromPath(imgPath);
_viewMdl.SetSwitchState(4, imgPath == GreenLightPath, "switch5On");
break;
case PowerCircuitsEnum.Arm:
imgArmStat.Stretch = Stretch.Fill;
imgArmStat.Source = GetImageFromPath(imgPath);
_viewMdl.SetSwitchState(5, imgPath == GreenLightPath, "switch6On");
break;
}
});
}
private void SetAllStatusLights()
{
Dispatcher.Invoke(() =>
{
lblInit.Visibility = Visibility.Visible;
EnablePowerButtons(false);
});
EnablePowerCheckboxes(false);
_statusLightSetupWait = new AutoResetEvent(false);
_statusLightSetupThread = new Thread(() =>
{
int curPin = 0;
while (curPin < AntwerpMcp.Circuits.Length)
{
SetStatusLight((PowerCircuitsEnum)curPin);
_statusLightSetupWait.WaitOne();
curPin++;
}
SetStatusLight(PowerCircuitsEnum.Dock);
EnablePowerCheckboxes(true);
_statusLightSetupWait = null;
Dispatcher.Invoke(() =>
{
lblInit.Visibility = Visibility.Hidden;
EnablePowerButtons(true);
});
});
_statusLightSetupThread.Start();
}
private void EnablePowerButtons(bool enable)
{
powerButton1.IsEnabled = enable;
powerButton2.IsEnabled = enable;
powerButton3.IsEnabled = enable;
powerButton4.IsEnabled = enable;
powerButton5.IsEnabled = enable;
powerButton6.IsEnabled = enable;
}
private void SetStatusLight(PowerCircuitsEnum pin)
{
var tstNdx = (short)pin;
string errorStr = null;
var success = _mcp.GetPinState(tstNdx, ref errorStr);
//if (!success)
// MessageBox.Show("Failed to get pin state, error = " + errorStr);
}
private void SetPinState(PowerCircuitsEnum pin, bool onOff)
{
string errorStr = null;
if (!_mcp.SetPinState((short)pin, onOff, ref errorStr))
MessageBox.Show("Failed to set pin, error = " + errorStr);
}
private void TurnRngSensorDisplayOn()
{
if (_mcp != null)
_mcp.DisplayRngSensorRdgs = true;
}
private void TurnRngSensorDisplayOff()
{
if (_mcp == null)
return;
_mcp.DisplayRngSensorRdgs = false;
Dispatcher.Invoke(() =>
{
textFront.Text = "0";
textRight.Text = "0";
textBack.Text = "0";
textLeft.Text = "0";
textFrontDown.Text = "0";
textBackDown.Text = "0";
});
}
private void TurnLidarDisplayOn()
{
if (_mcp == null)
return;
_mcp.DisplayLidarPointCloud = true;
_lidarCtrl.StartRendering();
lidarCanvas.Visibility = Visibility.Visible;
}
private void TurnVideoDisplayOn()
{
if (_rs400VwrCtrl == null)
LoadRs400Ctrl();
rs400Canvas.Visibility = Visibility.Visible;
_rs400VwrCtrl.CurStream = 2;
string errStr = null;
_mcp.UpperCamMgr.SendServoAction(SendBodyMsgs.UpperCamHome, ref errStr);
SetPanTiltBoxes();
_mcp.UpperCamOn = true;
}
private void TurnVideoDisplayOff()
{
rs400Canvas.Visibility = Visibility.Collapsed;
_rs400VwrCtrl.StopStream();
_mcp.UpperCamOn = false;
}
private void TurnLidarDisplayOff()
{
if (_mcp == null)
return;
_mcp.DisplayLidarPointCloud = false;
_lidarCtrl.StopRendering();
lidarCanvas.Visibility = Visibility.Collapsed;
}
private void LoadRs400Ctrl()
{
if (_rs400VwrCtrl != null)
return;
_rs400VwrCtrl = new Rs400VideoViewer();
_rs400VwrCtrl.Margin = new Thickness(0, 0, 0, 0);
Canvas.SetTop(_rs400VwrCtrl, 0);
Canvas.SetLeft(_rs400VwrCtrl, 0);
_rs400VwrCtrl.MaxHeight = 400;
_rs400VwrCtrl.Height = 400;
_rs400VwrCtrl.MaxWidth = 780;
_azCustVisionMgr = new AzureCustomVisionMgr(_mcp, AntwerpMcp.AzureCustVisionChannelName, AntwerpMcp.AzureCustVisionConnectorName);
_azCustVisionMgr.CamViewerCtrl = _rs400VwrCtrl;
_azCustVisionMgr.Margin = new Thickness(0, 0, 0, 0);
Canvas.SetTop(_azCustVisionMgr, 402);
Canvas.SetLeft(_azCustVisionMgr, 0);
_azCustVisionMgr.MaxHeight = 100;
_azCustVisionMgr.Height = 100;
_azCustVisionMgr.MaxWidth = 780;
_azCustVisionMgr.XImageOffset = -0.075d;
_azCustVisionMgr.YImageOffset = -0.01d;
_azCustVisionMgr.ImageWidthOffset = -0.02d;
rs400Canvas.Children.Add(_rs400VwrCtrl);
rs400Canvas.Children.Add(_azCustVisionMgr);
_mcp.UpperCamMgr.Rs400Vwr = _rs400VwrCtrl;
}
private void BtnStop_Click(object sender, RoutedEventArgs e)
{
string errorStr = null;
_mcp.ClearSubsumption();
if (!_mcp.SendBodyCmdMessage(SendBodyMsgs.Stop, ref errorStr))
{
MessageBox.Show(errorStr);
return;
}
_mcp.InRoamMode = false;
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
if (_setAllLights)
{
e.Cancel = true;
MessageBox.Show("Must finish power channel initialization before closing program");
return;
}
//_mcpThreadCancelTkn.Cancel(false);
_mcp.Dispose();
Thread.Sleep(200);
base.OnClosing(e);
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
Environment.Exit(0);
Application.Current.Shutdown();
}
private void BtnForward_Click(object sender, RoutedEventArgs e)
{
string errorMsg = null;
_mcp.LastBodyMsg = SendBodyMsgs.Forward;
_mcp.ClearSubsumption();
if (!_mcp.SendBodyCmdMessage(SendBodyMsgs.Forward, ref errorMsg))
{
MessageBox.Show(errorMsg);
return;
}
_mcp.InRoamMode = true;
}
private void BtnBack_Click(object sender, RoutedEventArgs e)
{
string errorMsg = null;
_mcp.ClearSubsumption();
_mcp.LastBodyMsg = SendBodyMsgs.Backward;
if (!_mcp.SendBodyCmdMessage(SendBodyMsgs.Backward, ref errorMsg))
{
MessageBox.Show(errorMsg);
return;
}
_mcp.InRoamMode = true;
}
private void BtnPivotRight_Click(object sender, RoutedEventArgs e)
{
string errorMsg = null;
_mcp.LastBodyMsg = SendBodyMsgs.PivotRight;
_mcp.ClearSubsumption();
if (!_mcp.SendBodyCmdMessage(SendBodyMsgs.PivotRight, ref errorMsg))
MessageBox.Show(errorMsg);
}
private void BtnPivotLeft_Click(object sender, RoutedEventArgs e)
{
string errorMsg = null;
_mcp.LastBodyMsg = SendBodyMsgs.PivotLeft;
_mcp.ClearSubsumption();
if (!_mcp.SendBodyCmdMessage(SendBodyMsgs.PivotLeft, ref errorMsg))
MessageBox.Show(errorMsg);
}
private void PowerButton1_Click(object sender, RoutedEventArgs e)
{
if (_setAllLights)
return;
SetPinState(PowerCircuitsEnum.Dock, !_viewMdl.SwitchState[0]);
}
private void PowerButton2_Click(object sender, RoutedEventArgs e)
{
if (_setAllLights)
return;
SetPinState(PowerCircuitsEnum.Router, !_viewMdl.SwitchState[1]);
}
private void PowerButton3_Click(object sender, RoutedEventArgs e)
{
if (_setAllLights)
return;
SetPinState(PowerCircuitsEnum.UsbHub, !_viewMdl.SwitchState[2]);
}
private void PowerButton4_Click(object sender, RoutedEventArgs e)
{
if (_setAllLights)
return;
SetPinState(PowerCircuitsEnum.Body, !_viewMdl.SwitchState[3]);
}
private void PowerButton5_Click(object sender, RoutedEventArgs e)
{
if (_setAllLights)
return;
SetPinState(PowerCircuitsEnum.UpperSensors, !_viewMdl.SwitchState[4]);
}
private void PowerButton6_Click(object sender, RoutedEventArgs e)
{
if (_setAllLights)
return;
SetPinState(PowerCircuitsEnum.Arm, !_viewMdl.SwitchState[5]);
}
private void ChkLogMessages_Unchecked(object sender, RoutedEventArgs e)
{
_mcp.LogAllMessages = false;
}
private void ChkLogMessages_Checked(object sender, RoutedEventArgs e)
{
_mcp.LogAllMessages = true;
}
private void ChkDispRngSensors_Checked(object sender, RoutedEventArgs e)
{
TurnRngSensorDisplayOn();
}
private void ChkDispRngSensors_Unchecked(object sender, RoutedEventArgs e)
{
TurnRngSensorDisplayOff();
}
private void ChkDispLidarCloud_Checked(object sender, RoutedEventArgs e)
{
if (chkDispRs400Viewer.IsChecked ?? false)
chkDispRs400Viewer.IsChecked = false;
TurnLidarDisplayOn();
}
private void ChkDispLidarCloud_Unchecked(object sender, RoutedEventArgs e)
{
TurnLidarDisplayOff();
}
private void ChkDispRs400Viewer_Checked(object sender, RoutedEventArgs e)
{
if (chkDispLidarCloud.IsChecked ?? false)
chkDispLidarCloud.IsChecked = false;
TurnVideoDisplayOn();
}
private void ChkDispRs400Viewer_Unchecked(object sender, RoutedEventArgs e)
{
TurnVideoDisplayOff();
}
private void TriggerSnapshot()
{
Dispatcher.Invoke(() =>
{
_rs400VwrCtrl.GrabSnapshot();
var scanFrame = new ScanFrame
{
FrameTimestamp = DateTime.Now,
BotHeading = 0,
CamPanBearing = _mcp.UpperCamMgr.CurPanPos,
CamTiltAngle = _mcp.UpperCamMgr.CurTiltPos,
ImageBase64 = _rs400VwrCtrl.GetSnapFrameAsPngBase64(),
ImageFormat = ScanImageFormats.png
};
_azCustVisionMgr.CurrentFrame = scanFrame;
_mcp.LastScanFrame = scanFrame;
if (_mcp.WaitingForImage)
_mcp.ReturnLastScanToRemotePeer();
});
}
private static string TempImgFile = "TestIMage.bmp";
private void SaveImage()
{
byte[] imageBytes = null;
string base64Str = _rs400VwrCtrl.GetSnapFrameAsBmpBase64();
//Bitmap bmp;
//using (MemoryStream outStream = new MemoryStream())
//{
// BitmapEncoder enc = new BmpBitmapEncoder();
// enc.Frames.Add(BitmapFrame.Create((BitmapSource)_rs400VwrCtrl.SnapFrame));
// enc.Save(outStream);
// bmp = new Bitmap(outStream);
// imageBytes = outStream.ToArray();
//}
//base64Str = Convert.ToBase64String(imageBytes);
File.WriteAllText(TempImgFile, base64Str);
}
private void BtnSetPan_Click(object sender, RoutedEventArgs e)
{
int newPan;
if (!int.TryParse(txtCurPan.Text, out newPan))
{
MessageBox.Show("Current Pan Value must be an interger value");
return;
}
var newPanTilt = new PanTiltCommandMsg
{
PanPos = newPan,
TiltPos = _mcp.UpperCamMgr.CurTiltPos
};
string limitErr = null;
if (!_mcp.UpperCamMgr.LimitHitCheck(newPanTilt, ref limitErr))
{
MessageBox.Show(limitErr);
return;
}
_mcp.UpperCamMgr.NewPanPos = newPan;
_mcp.ProcessStringCommand("UCSP");
}
private void BtnSetTilt_Click(object sender, RoutedEventArgs e)
{
int newTilt;
if (!int.TryParse(txtCurTilt.Text, out newTilt))
{
MessageBox.Show("Current Tilt Value must be an interger value");
return;
}
var newPanTilt = new PanTiltCommandMsg
{
PanPos = _mcp.UpperCamMgr.CurPanPos,
TiltPos = newTilt
};
string limitErr = null;
if (!_mcp.UpperCamMgr.LimitHitCheck(newPanTilt, ref limitErr))
{
MessageBox.Show(limitErr);
return;
}
_mcp.UpperCamMgr.NewTiltPos = newTilt;
_mcp.ProcessStringCommand("UCST");
}
private void BtnPanPlus10_Click(object sender, RoutedEventArgs e)
{
var newPanTilt = new PanTiltCommandMsg
{
PanPos = _mcp.UpperCamMgr.CurPanPos + 10,
TiltPos = _mcp.UpperCamMgr.CurTiltPos
};
string limitErr = null;
if (!_mcp.UpperCamMgr.LimitHitCheck(newPanTilt, ref limitErr))
{
MessageBox.Show(limitErr);
return;
}
_mcp.ProcessStringCommand("UCPU");
}
private void BtnTiltPlus10_Click(object sender, RoutedEventArgs e)
{
var newPanTilt = new PanTiltCommandMsg
{
PanPos = _mcp.UpperCamMgr.CurPanPos,
TiltPos = _mcp.UpperCamMgr.CurTiltPos + 10
};
string limitErr = null;
if (!_mcp.UpperCamMgr.LimitHitCheck(newPanTilt, ref limitErr))
{
MessageBox.Show(limitErr);
return;
}
_mcp.ProcessStringCommand("UCTU");
}
private void BtnPanMinus10_Click(object sender, RoutedEventArgs e)
{
var newPanTilt = new PanTiltCommandMsg
{
PanPos = _mcp.UpperCamMgr.CurPanPos - 10,
TiltPos = _mcp.UpperCamMgr.CurTiltPos
};
string limitErr = null;
if (!_mcp.UpperCamMgr.LimitHitCheck(newPanTilt, ref limitErr))
{
MessageBox.Show(limitErr);
return;
}
_mcp.ProcessStringCommand("UCPD");
}
private void BtnTiltnMinus10_Click(object sender, RoutedEventArgs e)
{
var newPanTilt = new PanTiltCommandMsg
{
PanPos = _mcp.UpperCamMgr.CurPanPos,
TiltPos = _mcp.UpperCamMgr.CurTiltPos - 10
};
string limitErr = null;
if (!_mcp.UpperCamMgr.LimitHitCheck(newPanTilt, ref limitErr))
{
MessageBox.Show(limitErr);
return;
}
_mcp.ProcessStringCommand("UCTD");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var base64Str = File.ReadAllText(TempImgFile);
Byte[] bitmapData = Convert.FromBase64String(base64Str);
System.IO.MemoryStream streamBitmap = new System.IO.MemoryStream(bitmapData);
Bitmap bitImage = new Bitmap((Bitmap)System.Drawing.Image.FromStream(streamBitmap));
streamBitmap.Close();
using (MemoryStream memory = new MemoryStream())
{
bitImage.Save(memory, System.Drawing.Imaging.ImageFormat.Bmp);
memory.Position = 0;
BitmapImage bitmapimage = new BitmapImage();
bitmapimage.BeginInit();
bitmapimage.StreamSource = memory;
bitmapimage.CacheOption = BitmapCacheOption.OnLoad;
bitmapimage.EndInit();
}
}
private void BtnGrabSnap_Click(object sender, RoutedEventArgs e)
{
OnUpperCamCommand(CameraCommands.GrabSnapshot);
}
private void BtnColorStrm_Click(object sender, RoutedEventArgs e)
{
OnUpperCamCommand(CameraCommands.RgbStreamOn);
//_azCustVisionMgr.ClearRectangles();
//_rs400VwrCtrl.CurStream = 2;
}
private void BtnDepthStrm_Click(object sender, RoutedEventArgs e)
{
OnUpperCamCommand(CameraCommands.DepthStreamOn);
//_azCustVisionMgr.ClearRectangles();
//_rs400VwrCtrl.CurStream = 1;
}
}
}
Comments
Please log in or sign up to comment.