Bibliotheques TP RT  1.0
Bibliotheque de support pour TP/RT
robot.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018 dimercur
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
26 #include "robot.h"
27 
28 int fd;
29 
30 int getChar(char * c);
31 int readSerial(char * msg);
32 char checkSumGO(char * msg);
33 int receiveMsg(void);
34 int sendCmd(char cmd, const char * arg);
35 
36 int open_communication_robot(const char * path)
37 {
38 #ifndef __STUB__
39  struct termios options;
40  fd = open(path, O_RDWR | O_NOCTTY | O_NDELAY);
41  if(fd !=-1)
42  {
43  fcntl(fd, F_SETFL, 0);
44  tcgetattr(fd, &options);
45  options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
46  cfsetospeed (&options, B9600);
47  cfsetispeed (&options, B9600);
48  options.c_cc[VMIN]=0;
49  options.c_cc[VTIME]=0;
50  tcsetattr(fd, TCSANOW, &options);
51  return 0;
52  }
53  else
54  {
55  perror("can't openSerial");
56  return -1;
57  }
58 #else
59  return 0;
60 #endif
61 }
62 
63 
65 {
66 #ifndef __STUB__
67  return close(fd);
68 #else
69  return 0;
70 #endif
71 }
72 
73 
74 int send_command_to_robot(char cmd, const char * arg)
75 {
76 #ifndef __STUB__
77  sendCmd(cmd,arg);
78  // TODO : check return from sendCmd
79  return receiveMsg();
80 #else
81  int reponse;
82  switch(cmd)
83  {
84  case DMB_PING:
85  reponse = 0;
86  break;
87  case DMB_IDLE:
88  reponse = 0;
89  break;
90  case DMB_START_WITH_WD:
91  reponse = 0;
92  break;
93  case DMB_RELOAD_WD:
94  reponse = 0;
95  break;
96  case DMB_GET_VBAT:
97  reponse = 2;
98  break;
99  case DMB_IS_BUSY:
100  reponse = 1;
101  break;
103  reponse = 0;
104  break;
105  case DMB_MOVE:
106  reponse = 0;
107  break;
108  case DMB_TURN:
109  reponse = 0;
110  break;
111  case DMB_GO_FORWARD:
112  reponse = 0;
113  break;
114  case DMB_GO_BACK:
115  reponse = 0;
116  break;
117  case DMB_GO_LEFT:
118  reponse = 0;
119  break;
120  case DMB_GO_RIGHT:
121  reponse = 0;
122  break;
123  case DMB_STOP_MOVE:
124  reponse = 0;
125  break;
126  default:
127  reponse = 0;
128  break;
129  }
130  return reponse;
131 #endif
132 }
133 
134 /****************************/
135 /* PRIVATE */
136 /****************************/
137 
138 int sendCmd(char cmd, const char * arg)
139 {
140  char cmdWithArg[20]={};
141  cmdWithArg[0]=cmd;
142  switch(cmd)
143  {
144  case DMB_GO_FORWARD: strcpy(cmdWithArg,"M=+64000");
145  break;
146  case DMB_GO_BACK: strcpy(cmdWithArg,"M=-64000");
147  break;
148  case DMB_GO_LEFT: strcpy(cmdWithArg,"T=+64000");
149  break;
150  case DMB_GO_RIGHT: strcpy(cmdWithArg,"T=-64000");
151  break;
152  case DMB_STOP_MOVE: strcpy(cmdWithArg,"M=0");
153  break;
154  case DMB_MOVE: strcat(cmdWithArg,"=");
155  strcat(cmdWithArg,arg);
156  break;
157  case DMB_TURN: strcat(cmdWithArg,"=");
158  strcat(cmdWithArg,arg);
159  break;
160  }
161  int sizeCmd = strlen(cmdWithArg);
162  cmdWithArg[sizeCmd] = checkSumGO(cmdWithArg);
163  cmdWithArg[sizeCmd+1] = '\r';
164  cmdWithArg[sizeCmd+2] = '\0';
165  return write(fd,cmdWithArg,strlen(cmdWithArg));
166 }
167 
168 int receiveMsg(void)
169 {
170  char msg[20];
171  int b;
172  if((b = readSerial(msg))!=ROBOT_TIMED_OUT)
173  {
174  int taille = strlen(msg);
175  char checksum = msg[taille-2];
176  msg[taille-1] = 0;
177  msg[taille-2] = 0;
178  if(checksum!=checkSumGO(msg))
179  {
180  return ROBOT_CHECKSUM;
181  }
182  else
183  {
184  switch(msg[0])
185  {
186  case 'O' : return 0;
187  case 'E' : return ROBOT_ERROR;
188  case 'C' : return ROBOT_UKNOWN_CMD;
189  default : return atoi(&msg[0]);
190  }
191  }
192  }
193  else
194  {
195  return ROBOT_TIMED_OUT;
196  }
197 }
198 
199 int getChar(char * c)
200 {
201  int n =0;
202  int delay =0;
203  while((n=read(fd,c,1)) <=0)
204  {
205  usleep(5000);
206  delay++;
207  if(delay > 10)
208  {
209  return ROBOT_TIMED_OUT;
210  }
211 
212  }
213  return n;
214 }
215 
216 int readSerial(char * msg)
217 {
218  char car=0;
219  int i=0;
220  for(int j = 0 ; j < 20 ; j++)
221  msg[j]=0;
222 
223  while(car !='\r' && car!='\n') {
224  if(i>=20)
225  return -5;
226 
227  if(getChar(&car)==ROBOT_TIMED_OUT) {
228  return ROBOT_TIMED_OUT;
229  }
230 
231  msg[i] = car;
232  i++;
233  }
234  return i;
235 }
236 
237 char checkSumGO(char * msg)
238 {
239  char resultat = 0;
240  int i = 0;
241  int taille = strlen(msg);
242  for(i=0;i<taille;i++)
243  {
244  resultat^=msg[i];
245  }
246  return resultat;
247 
248 }
249 
250 
251 
#define DMB_PING
Definition: definitions.h:33
#define DMB_RELOAD_WD
Definition: definitions.h:37
#define DMB_GO_LEFT
Definition: definitions.h:44
#define DMB_START_WITH_WD
Definition: definitions.h:36
#define DMB_GO_BACK
Definition: definitions.h:43
Fonctions for communicating with robot.
char checkSumGO(char *msg)
Definition: robot.cpp:237
int readSerial(char *msg)
Definition: robot.cpp:216
#define ROBOT_ERROR
Definition: definitions.h:50
#define ROBOT_CHECKSUM
Definition: definitions.h:51
#define DMB_START_WITHOUT_WD
Definition: definitions.h:35
int receiveMsg(void)
Definition: robot.cpp:168
int getChar(char *c)
Definition: robot.cpp:199
#define ROBOT_UKNOWN_CMD
Definition: definitions.h:49
#define DMB_IDLE
Definition: definitions.h:34
#define DMB_GO_RIGHT
Definition: definitions.h:45
int sendCmd(char cmd, const char *arg)
Definition: robot.cpp:138
#define DMB_IS_BUSY
Definition: definitions.h:39
#define DMB_GET_VBAT
Definition: definitions.h:38
#define ROBOT_TIMED_OUT
Definition: definitions.h:48
#define DMB_GO_FORWARD
Definition: definitions.h:42
int send_command_to_robot(char cmd, const char *arg)
Envoi une commande au robot et attends sa réponse.
Definition: robot.cpp:74
int fd
Definition: robot.cpp:28
int open_communication_robot(const char *path)
Ouvre la communication avec le robot.
Definition: robot.cpp:36
#define DMB_STOP_MOVE
Definition: definitions.h:46
int close_communication_robot(void)
Ferme la communication avec le robot.
Definition: robot.cpp:64
#define DMB_TURN
Definition: definitions.h:41
#define DMB_MOVE
Definition: definitions.h:40