The VisAO Camera
ESPMotorCtrl.cpp
1 #include "ESPMotorCtrl.h"
2 
3 
4 namespace VisAO
5 {
6 
7 #define _debug
8 
10 {
11  numAxes = 0;
12  default_timeout = 1000;
13 }
14 
16 {
17  numAxes = 0; //must initialize or setNumAxes will fail.
18  setNumAxes(no);
19  default_timeout = 1000;
20 }
21 
23 {
24  return;
25 }
26 
27 void ESPMotorCtrl::getStageName(int axis, std::string &sname)
28 {
29  std::string com, resp;
30  char errc;
31 
32  errStr.str("");
33 
34  if(makeCom(com, axis, "ZX?") < 0)
35  {
36  errStr << "Error making command ZX?" << __FILE__ << " " << __LINE__ << '\n';
37  return;
38  }
39 
40  sendCommand(com, resp, default_timeout);
41 
42 
43  errc = getError(axis);
44  if(errc != '@')
45  {
46  //std::cerr << "An Error occurred\n";
47  errStr << "An error occurred (" << errc << ") " << __FILE__ << " " << __LINE__ << '\n';
48  sname = "";
49  return;
50  }
51 
52 
53  if(axis < 10)
54  {
55  sname = resp.substr(3, resp.length()-3);
56  }
57  else
58  {
59  sname = resp.substr(4, resp.length()-4);
60  }
61 
62 }
63 
65 {
66  errStr.str("");
67  if(numAxes != 0)
68  {
69  errStr << "Already initialized. Can't change number of axes " << __FILE__ << " " << __LINE__ << '\n';
70  return -1;
71  }
72 
73  numAxes = no;
74 
75  axisAddress.resize(numAxes);
76  for(int i=0;i<numAxes;i++) axisAddress[i] = i+1;
77 
78  stageName.resize(numAxes);
79 
80  return 0;
81 }
82 
84 {
85  std::string com, resp, err;
86 
87  errStr.str("");
88 
89  if(numAxes == 0)
90  {
91  errStr << "Not initialized. Must set number of axes. "<< __FILE__ << " " << __LINE__ << '\n';
92  return -1;
93  }
94 
95  #ifdef _debug
96  std::cout << "Power on initialization\n";
97  #endif
98 
99  for(int i=0;i<numAxes;i++)
100  {
101  getStageName(i+1, stageName[i]);
102  if(stageName[i] == "" && errStr.str() != "")
103  {
104  errStr << "Error getting stagename " << i << " " << __FILE__ << " " << __LINE__ << '\n';
105  return -1;
106  }
107  }
108 
109  #ifdef _debug
110  std::cout << "Got stage names\n";
111  #endif
112 
113  std::string state;
114  for(int i=0;i<numAxes;i++)
115  {
116  if(getCtrlState(i+1, state) != 0)
117  {
118  errStr << "Error getting controller " << i+1 << " state." << __FILE__ << " " << __LINE__ << "\n";
119  return -1;
120  }
121 
122  /*if(state[0] != '0' || state[1] != '0' || (state[2] != '0' && state[2] != '4') || (state[3] != '0' && state[3] != '1' && state[3] != '2'))
123  {
124  errStr << "Unacceptable positioner " << i+1 << " error. State: " << state << " " << __FILE__ << " " << __LINE__ << "\n";
125  return -1;
126  }*/
127 
128  if(state[0] == '0' || (state[0] == '1' && state[1] == '1'))
129  {
130  if(home(i+1) < 0)
131  {
132  errStr << "Power on homing error " << __FILE__ << " " << __LINE__ << "\n";
133  return -1;
134  }
135  }
136  /*else if (state[4] == '1' && (state[5] == 'E' || state[5] == 'F')) curState = STATE_HOMING;
137  else if (state[4] == '2') curState = STATE_OPERATING;
138  else if (state[4] == '3' && isnum(state[5])) curState = STATE_READY;
139  else curState = STATE_INVALID;*/
140  }
141 
142  #ifdef _debug
143  std::cout << "Power on init complete\n";
144  #endif
145 
146  return 0;
147 }
148 
149 char ESPMotorCtrl::getError(int axis)
150 {
151  std::string com, resp;
152 
153  errStr.str("");
154  if(axis < 1 || axis > numAxes)
155  {
156  errStr << "Bad axis " << __FILE__ << " " << __LINE__ << '\n';
157  return -1;
158  }
159 
160  if(makeCom(com, axis, "TE") < 0)
161  {
162  errStr << "Error making command TE" << __FILE__ << " " << __LINE__ << '\n';
163  return -1;
164  }
165 
166  sendCommand(com, resp, default_timeout);
167 
168  if(axis < 10)
169  {
170  return resp[3];
171  }
172  else
173  {
174  return resp[4];
175  }
176 
177 }
178 
179 std::string ESPMotorCtrl::getStageName(int axis)
180 {
181  if(axis < 1 || axis > numAxes)
182  {
183  errStr << "Bad Axis " << __FILE__ << " " << __LINE__ << '\n';
184  return "";
185  }
186 
187  return stageName[axis-1];
188 }
189 
190 int ESPMotorCtrl::getCtrlState(int axis, std::string &state)
191 {
192  std::string com, resp;
193  errStr.str("");
194 
195  if(makeCom(com, axis, "TS") < 0)
196  {
197  errStr << "Error making command TS" << __FILE__ << " " << __LINE__ << '\n';
198  return 0;
199  }
200 
201  sendCommand(com, resp, default_timeout);
202 
203  int raxis;
204  std::string rcom, rval;
205 
206  splitResponse(raxis, rcom, rval, resp);
207 
208  if(rcom == "")
209  {
210  errStr << "An Error occurred " << __FILE__ << " " << __LINE__ << '\n';
211  return -1;
212  }
213 
214  if(raxis != axis)
215  {
216  errStr << "Wrong axis returned " << __FILE__ << " " << __LINE__ << '\n';
217  return -1;
218  }
219 
220  if(rcom != "TS")
221  {
222  errStr << "Wrong command returned " << __FILE__ << " " << __LINE__ << '\n';
223  return -1;
224  }
225 
226  if(rval.length() != 6)
227  {
228  errStr << "Incorrect response length "<< __FILE__ << " " << __LINE__ << '\n';
229  return -1;
230  }
231 
232  state = rval.substr(4, 2);
233 
234  return 0;
235 }
236 
237 
238 double ESPMotorCtrl::getCurPos(int axis)
239 {
240  std::string com, resp;
241 
242  if(makeCom(com, axis, "TP") < 0)
243  {
244  errStr << "Error making command TP" << __FILE__ << " " << __LINE__ << '\n';
245  return -1;
246  }
247 
248  sendCommand(com, resp, default_timeout);
249 
250  int raxis;
251  std::string rcom, rval;
252  splitResponse(raxis, rcom, rval, resp);
253 
254  if(rcom == "")
255  {
256  errStr << "An Error occurred " << __FILE__ << " " << __LINE__ << '\n';
257  return -1;
258  }
259 
260  if(raxis != axis)
261  {
262  errStr << "Wrong axis returned " << __FILE__ << " " << __LINE__ << '\n';
263  return -1;
264  }
265 
266  if(rcom != "TP")
267  {
268  errStr << "Wrong command returned " << __FILE__ << " " << __LINE__ << '\n';
269  return -1;
270  }
271 
272  return strtod(rval.c_str(),0);
273 
274 }
275 
276 int ESPMotorCtrl::home(int axis)
277 {
278  std::string com, resp;
279 
280  if(makeCom(com, axis, "OR") < 0)
281  {
282  errStr << "Error making command OR" << __FILE__ << " " << __LINE__ << '\n';
283  return 0;
284  }
285 
286  moveStart();
287 
288  if(sendCommand(com) < 0)
289  {
290  errStr << "Error sending command OR" << __FILE__ << " " << __LINE__ << '\n';
291  return 0;
292  }
293 
294  char errc = getError(axis);
295  if(errc != '@')
296  {
297  errStr << "An error occurred in homing (" << errc << ") " << __FILE__ << " " << __LINE__ << '\n';
298  return -1;
299  }
300 
301  return 0;
302 
303 }
304 
305 int ESPMotorCtrl::stop(int axis)
306 {
307  std::string com;
308 
309  if(axis == 0)
310  {
311  com = "0ST";
312  }
313  else
314  {
315  if(makeCom(com, axis, "ST") < 0)
316  {
317  errStr << "Error making command ST" << __FILE__ << " " << __LINE__ << '\n';
318  errStr << "Sending 0ST" << __FILE__ << " " << __LINE__ << '\n';
319  com = "0ST";
320  }
321  }
322 
323  if(sendCommand(com) < 0)
324  {
325  errStr << "Error sending command ST" << __FILE__ << " " << __LINE__ << '\n';
326  return -1;
327  }
328 
329  char errc = getError(axis);
330  if(errc != '@')
331  {
332  errStr << "An error occurred in stopping (" << errc << ") " << __FILE__ << " " << __LINE__ << '\n';
333  return -1;
334  }
335 
336  return 0;
337 }
338 
339 int ESPMotorCtrl::gotoAbsPos(int axis, double apos)
340 {
341  std::string com;
342 
343  if(makeCom(com, axis, "PA", apos) < 0)
344  {
345  errStr << "Error making command PA " << __FILE__ << " " << __LINE__ << '\n';
346  return -1;
347  }
348 
349  moveStart();
350 
351  if(sendCommand(com) < 0)
352  {
353  errStr << "Error sending command PA " << __FILE__ << " " << __LINE__ << '\n';
354  return -1;
355  }
356 
357  char errc = getError(axis);
358  if(errc != '@')
359  {
360  errStr << "An error occurred in goto abs. pos. (" << errc << ") " << __FILE__ << " " << __LINE__ << '\n';
361  return -1;
362  }
363 
364  return 0;
365 }
366 
367 int ESPMotorCtrl::gotoRelPos(int axis, double apos)
368 {
369  std::string com;
370  errStr.str("");
371 
372  //Don't do a relative move less than the minimum resolution
373  if(fabs(apos) < MOVE_RESOLUTION) return 0;
374 
375  if(makeCom(com, axis, "PR", apos) < 0)
376  {
377  errStr << "Error making command PR " << __FILE__ << " " << __LINE__ << '\n';
378  return -1;
379  }
380 
381  moveStart();
382 
383  if(sendCommand(com) < 0)
384  {
385  errStr << "Error sending command PR" << __FILE__ << " " << __LINE__ << '\n';
386  return -1;
387  }
388 
389  char errc = getError(axis);
390  if(errc != '@')
391  {
392  errStr << "An error occurred in goto rel. pos. (" << errc << ") " << __FILE__ << " " << __LINE__ << '\n';
393  return -1;
394  }
395 
396  return 0;
397 }
398 
399 
400 int ESPMotorCtrl::makeCom(std::string &str, int axis, const char *com)
401 {
402  char tmp[10];
403 
404  if(axis < 1 || axis > numAxes)
405  {
406  errStr << "Bad axis " << __FILE__ << " " << __LINE__ << '\n';
407  return -1;
408  }
409 
410  snprintf(tmp, 10, "%i", axisAddress[axis-1]);
411 
412  str = tmp;
413 
414  str += com;
415 
416  return 0;
417 }
418 
419 int ESPMotorCtrl::makeCom(std::string &str, int axis, const char *com, int val)
420 {
421  char tmp[10];
422 
423  errStr.str("");
424  if(axis < 1 || axis > numAxes)
425  {
426  errStr << "Bad axis " << __FILE__ << " " << __LINE__ << '\n';
427  return -1;
428  }
429 
430  snprintf(tmp, 10, "%i", axisAddress[axis-1]);
431 
432  str = tmp;
433 
434  str += com;
435 
436  snprintf(tmp, 10, "%i", val);
437 
438  str += tmp;
439 
440  return 0;
441 }
442 
443 int ESPMotorCtrl::makeCom(std::string &str, int axis, const char *com, double val)
444 {
445  char tmp[10];
446 
447  errStr.str("");
448  if(axis < 1 || axis > numAxes)
449  {
450  errStr << "Bad axis " << __FILE__ << " " << __LINE__ << '\n';
451  return -1;
452  }
453 
454  snprintf(tmp, 10, "%i", axisAddress[axis-1]);
455 
456  str = tmp;
457 
458  str += com;
459 
460  snprintf(tmp, 10, "%f", val);
461 
462  str += tmp;
463 
464  return 0;
465 }
466 
467 int ESPMotorCtrl::makeCom(std::string &str, int axis, const char *com, std::string &val)
468 {
469  char tmp[10];
470 
471  errStr.str("");
472  if(axis < 1 || axis > numAxes)
473  {
474  errStr << "Bad axis " << __FILE__ << " " << __LINE__ << '\n';
475  return -1;
476  }
477 
478  snprintf(tmp, 10, "%i", axisAddress[axis-1]);
479 
480  str = tmp;
481 
482  str += com;
483 
484  str += val;
485 
486  return 0;
487 }
488 
489 int ESPMotorCtrl::splitResponse(int &axis, std::string &com, std::string &val, std::string &resp)
490 {
491  if(resp.length() < 3)
492  {
493  errStr << "Invalid response " << __FILE__ << " " << __LINE__;
494  return -1;
495  }
496 
497  if(isalpha(resp[0]))
498  {
499  errStr << "Invalid response " << __FILE__ << " " << __LINE__;
500  axis = 0;
501  com = "";
502  val = resp;
503  return 0;
504  }
505 
506  if(isalpha(resp[1]))
507  {
508  axis = resp[0] - '0';
509  }
510  else
511  {
512  axis = atoi(resp.substr(0,2).c_str());
513  }
514 
515  if(axis < 10)
516  {
517 
518  com = resp.substr(1,2);
519  if(resp.length() < 4 ) val = "";
520  else val = resp.substr(3, resp.length()-3);
521  }
522  else
523  {
524  if(resp.length() < 4)
525  {
526  errStr << "Invalid response " << __FILE__ << " " << __LINE__;
527  com = "";
528  val = "";
529  return -1;
530  }
531  com = resp.substr(2,2);
532  if(resp.length() < 5) val = "";
533  else val = resp.substr(4, resp.length()-4);
534  }
535 
536  return 0;
537 }
538 
539 
540 int ESPMotorCtrl::sendCommand(std::string &com, std::string &resp, int timeout __attribute__((unused)))
541 {
542  std::cout << com << "\n";
543  std::cin >> resp;
544  return 0;
545 }
546 
547 int ESPMotorCtrl::sendCommand(std::string &com)
548 {
549  std::cout << com << "\n";
550  return 0;
551 }
552 
554 {
555  std::cout << "ESP moveStart\n";
556  return;
557 }
558 
559 }//namespace VisAO
560 
int numAxes
Number of motor controllers.
Definition: ESPMotorCtrl.h:53
Declarations for a Newport ESP motor controller.
std::vector< int > axisAddress
The controller address of each axis.
Definition: ESPMotorCtrl.h:55
int powerOnInit()
Checks the controllers for current errors, and populates the stageName vector.
ESPMotorCtrl()
Default constructor.
Definition: ESPMotorCtrl.cpp:9
virtual void moveStart()
Called before starting a move. Empty here, to be overridden.
std::vector< std::string > stageName
The names of the connected motors.
Definition: ESPMotorCtrl.h:57
The namespace of VisAO software.
int setNumAxes(int no)
Sets the number of axes. Can only be called when uninitialized.
virtual ~ESPMotorCtrl()
Destructor.