Monitor
DestijlCommandManager.cs
Go to the documentation of this file.
1 //
2 // DestijlCommandManager.cs
3 //
4 // Author:
5 // Di MERCURIO Sébastien <dimercur@insa-toulouse.fr>
6 //
7 // Copyright (c) 2018 INSA - DGEI
8 //
9 // This program is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 3 of the License, or
12 // (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 
22 using System;
23 
24 namespace monitor
25 {
29  public static class DestijlCommandList
30  {
31  public const string HeaderMtsComDmb = "COM";
32  public const string HeaderMtsDmbOrder = "DMB";
33  public const string HeaderMtsCamera = "CAM";
34  public const string HeaderMtsMessage = "MSG";
35 
36  public const string DataComOpen = "o";
37  public const string DataComClose = "C";
38 
39  public const string DataCamOpen = "A";
40  public const string DataCamClose = "I";
41  public const string DataCamAskArena = "y";
42  public const string DataCamArenaConfirm = "x";
43  public const string DataCamInfirm = "z";
44  public const string DataCamComputePosition = "p";
45  public const string DataCamStopComputePosition = "s";
46 
47  public const string HeaderStmAck = "ACK";
48  public const string HeaderStmNoAck = "NAK";
49  public const string HeaderStmLostDmb = "LCD";
50  public const string HeaderStmImage = "IMG";
51  public const string HeaderStmPos = "POS";
52  public const string HeaderStmMes = "MSG";
53  public const string HeaderStmBat = "BAT";
54  }
55 
59  public static class RobotCommandList
60  {
61  public const string RobotPing = "p";
62  public const string RobotReset = "r";
63  public const string RobotStartWithoutWatchdog = "u";
64  public const string RobotStartWithWatchdog = "W";
65  public const string RobotGetBattery = "v";
66  public const string RobotGetBusyState = "b";
67  public const string RobotMove = "M";
68  public const string RobotTurn = "T";
69  public const string RobotGetVersion = "V";
70  public const string RobotPowerOff = "z";
71  }
72 
76  public class DestijlCommandManager
77  {
81  private CommandManager commandManager = null;
82 
86  private string receivedHeader = null;
87 
91  private string receivedData = null;
92 
96  public delegate void CommandReceivedEvent(string header, string data, byte[] buffer);
97  public CommandReceivedEvent commandReceivedEvent = null;
98 
102  public double timeout = 100;
103 
107  public enum CommandStatus
108  {
109  Success,
110  Rejected,
111  InvalidAnswer,
112  Busy,
113  CommunicationLostWithRobot,
114  CommunicationLostWithServer
115  }
116 
121  public DestijlCommandManager(CommandReceivedEvent callback)
122  {
123  commandManager = new CommandManager(OnCommandReceived);
124  this.commandReceivedEvent += callback;
125  }
126 
132  {
133  if (commandManager != null) commandManager.Close();
134  }
135 
141  private void OnCommandReceived(string msg, byte[] buffer)
142  {
143  // Firstly, split message in (at least) two part : header, and data
144  string[] msgs = msg.Split(':');
145 
146  // If it exist at least on element in string array, it should be command header
147  if (msgs.Length >= 1) receivedHeader = msgs[0];
148  else receivedHeader = null;
149 
150  // if msgs array contains at least two elements, second element is normally data
151  if (msgs.Length >= 2) receivedData = msgs[1];
152  else receivedData = null;
153 
154  // when split is done, provide data to application
155  this.commandReceivedEvent?.Invoke(receivedHeader, receivedData, buffer);
156  }
157 
163  public bool Open(string hostname)
164  {
165  return this.Open(hostname, Client.defaultPort);
166  }
167 
174  public bool Open(string hostname, int port)
175  {
176  if (commandManager != null) return commandManager.Open(hostname, port);
177  else return false;
178  }
179 
183  public void Close()
184  {
185  if (commandManager != null) commandManager.Close();
186  }
187 
194  private string CreateCommand(string header, string data)
195  {
196  return header + ":" + data;
197  }
198 
205  private CommandStatus DecodeStatus(CommandManager.CommandManagerStatus localStatus, string answer)
206  {
207  CommandStatus status = CommandStatus.Success;
208 
209  // if timeout occures, return CommandStatus.CommunicationLostWithServer
210  if (localStatus == CommandManager.CommandManagerStatus.Timeout) status = CommandStatus.CommunicationLostWithServer;
211  // if a command is currently processed, return Busy
212  else if (localStatus == CommandManager.CommandManagerStatus.Busy) status = CommandStatus.Busy;
213  else
214  {
215  if (answer != null)
216  {
217  // if command is not acknowledged, return Rejected
218  if (answer.ToUpper().Contains(DestijlCommandList.HeaderStmNoAck)) status = CommandStatus.Rejected;
219  // if communication is lost with robot, return CommunicationLostWithRobot
220  else if (answer.ToUpper().Contains(DestijlCommandList.HeaderStmLostDmb)) status = CommandStatus.CommunicationLostWithRobot;
221  // if answer is empty, communication with robot is lost
222  else if (answer.Length == 0) status = CommandStatus.CommunicationLostWithServer;
223  //else status = CommandStatus.InvalidAnswer;
224  }
225  }
226 
227  return status;
228  }
229 
235  {
237  string answer;
238 
239  localStatus = commandManager.SendCommand(
241  out answer,
242  this.timeout);
243 
244  return DecodeStatus(localStatus, answer);
245  }
246 
252  {
254  string answer;
255 
256  localStatus = commandManager.SendCommand(
258  out answer,
259  this.timeout);
260 
261  return DecodeStatus(localStatus, answer);
262  }
263 
269  {
271  string answer;
272 
273  localStatus = commandManager.SendCommand(
275  out answer,
276  this.timeout);
277 
278  return DecodeStatus(localStatus, answer);
279  }
280 
286  {
288  string answer;
289 
290  localStatus = commandManager.SendCommand(
292  out answer,
293  0);
294 
295  return DecodeStatus(localStatus, answer);
296  }
297 
303  {
305  string answer;
306 
307  localStatus = commandManager.SendCommand(
309  out answer,
310  this.timeout);
311 
312  return DecodeStatus(localStatus, answer);
313  }
314 
320  {
322  string answer;
323 
324  localStatus = commandManager.SendCommand(
326  out answer,
327  this.timeout);
328 
329  return DecodeStatus(localStatus, answer);
330  }
331 
337  public CommandStatus RobotMove(int distance)
338  {
340  string answer;
341 
342  localStatus = commandManager.SendCommand(
343  CreateCommand(DestijlCommandList.HeaderMtsDmbOrder, RobotCommandList.RobotMove + "=" + distance),
344  out answer,
345  0);
346 
347  return DecodeStatus(localStatus, answer);
348  }
349 
355  public CommandStatus RobotTurn(int angle)
356  {
358  string answer;
359 
360  localStatus = commandManager.SendCommand(
361  CreateCommand(DestijlCommandList.HeaderMtsDmbOrder, RobotCommandList.RobotTurn + "=" + angle),
362  out answer,
363  0);
364 
365  return DecodeStatus(localStatus, answer);
366  }
367 
373  {
375  string answer;
376 
377  localStatus = commandManager.SendCommand(
379  out answer,
380  0);
381 
382  return DecodeStatus(localStatus, answer);
383  }
384 
390  public CommandStatus RobotGetVersion(out string version)
391  {
393  CommandStatus status = CommandStatus.Success;
394  version = "";
395 
396  string answer;
397 
398  localStatus = commandManager.SendCommand(
400  out answer,
401  this.timeout);
402 
403  if (localStatus == CommandManager.CommandManagerStatus.AnswerReceived)
404  {
405  string[] msg = answer.Split(':');
406 
407  if (msg.Length > 1)
408  {
409  version = msg[1];
410  }
411  }
412  else if (localStatus == CommandManager.CommandManagerStatus.Timeout)
413  {
414  status = CommandStatus.CommunicationLostWithServer;
415  }
416 
417  return status;
418  }
419 
425  {
427  string answer;
428 
429  localStatus = commandManager.SendCommand(
431  out answer,
432  0);
433 
434  return DecodeStatus(localStatus, answer);
435  }
436 
442  {
444  string answer;
445 
446  localStatus = commandManager.SendCommand(
448  out answer,
449  this.timeout);
450 
451  return DecodeStatus(localStatus, answer);
452  }
453 
459  {
461  string answer;
462 
463  localStatus = commandManager.SendCommand(
465  out answer,
466  0);
467 
468  return DecodeStatus(localStatus, answer);
469  }
470 
476  {
478  string answer;
479 
480  localStatus = commandManager.SendCommand(
482  out answer,
483  0);
484 
485  return DecodeStatus(localStatus, answer);
486  }
487 
493  {
495  string answer;
496 
497  localStatus = commandManager.SendCommand(
499  out answer,
500  0);
501 
502  return DecodeStatus(localStatus, answer);
503  }
504 
510  {
512  string answer;
513 
514  localStatus = commandManager.SendCommand(
516  out answer,
517  0);
518 
519  return DecodeStatus(localStatus, answer);
520  }
521 
527  {
529  string answer;
530 
531  localStatus = commandManager.SendCommand(
533  out answer,
534  0);
535 
536  return DecodeStatus(localStatus, answer);
537  }
538 
544  {
546  string answer;
547 
548  localStatus = commandManager.SendCommand(
550  out answer,
551  0);
552 
553  return DecodeStatus(localStatus, answer);
554  }
555  }
556 }
CommandStatus RobotGetVersion(out string version)
Request robot firmware version
CommandStatus RobotStartWithoutWatchdog()
Start robot, without enabling watchdog
const int defaultPort
Default server port number
Definition: Client.cs:41
CommandStatus CameraArenaInfirm()
Reject arena detected (after requesting image of detected arena, using CameraAskArena ...
bool Open(string hostname)
Open the specified hostname server, using default port number.
Command Manager. Use for timeout managment during reception of data Used as intermediate layer betwee...
void Close()
Close connection to server
void OnCommandReceived(string msg, byte[] buffer)
Callback used for receiving data from lower layer (CommandManager class)
CommandStatus RobotGetBattery()
Request robot battery level
CommandStatus RobotStartWithWatchdog()
Start robot, enabling watchdog
CommandManagerStatus SendCommand(string cmd, out string answer, double timeout)
Sends a command to TCP server
bool Open(string hostname, int port)
Open connection to server "host", with port number "port"
Commands used for robot messages
Specialization class for command manager, which implemnent destijl protocol between monitor and serve...
CommandStatus RobotPing()
Ping the robot.
CommandStatus CameraComputePosition()
Request robot position computing
CommandStatus CameraStopComputePosition()
Stop robot position computing
CommandStatus CameraArenaConfirm()
Confirm arena detection (after requesting image of detected arena, using CameraAskArena ...
CommandStatus
List of available return status
CommandStatus CameraAskArena()
Request still image of detected arena
CommandStatus RobotReset()
Reset robot and let it in idle mode
CommandStatus CameraClose()
Close camera on remote device
DestijlCommandManager(CommandReceivedEvent callback)
Initializes a new instance of the monitor.DestijlCommandManager class.
CommandStatus RobotTurn(int angle)
Make robot turn left or right, for a given angle
string CreateCommand(string header, string data)
Creates the command to send to server, based on header and data provided
CommandStatus CameraOpen()
Open camera on remote device
CommandStatus RobotPowerOff()
Power off robot
Static class for TCP client
Definition: Client.cs:31
~DestijlCommandManager()
Releases unmanaged resources and performs other cleanup operations before the monitor.DestijlCommandManager is reclaimed by garbage collection.
CommandStatus RobotCloseCom()
Close communication with robot and wait acknowledge
CommandStatus RobotMove(int distance)
Move robot forward or backward, for a distance expressed in millimeter
CommandManagerStatus
Available status when sending command
CommandStatus RobotOpenCom()
Open communication with robot and wait acknowledge
CommandStatus DecodeStatus(CommandManager.CommandManagerStatus localStatus, string answer)
Provide DestijlCommandManager.CommandStatus based on status received by CommandManager.SendCommand and answer string
Commands and options parameters used in Destijl project when communicating with server ...
bool Open(string hostname)
Open the specified hostname server, using default port number.
void Close()
Close connection to server