Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
IselLinearControlTwoAxis.cpp
1 #include "IselLinearControlTwoAxis.hh"
2 #include <Base/Common/W32Compat.hh>
3 #include <Base/Common/BIASpragma.hh>
4 #include <Base/Debug/Error.hh>
5 #include <cstring>
6 #include <sstream>
7 #ifndef WIN32
8 # include <termios.h>
9 #endif
10 
11 using namespace std;
12 using namespace BIAS;
13 
14 IselLinearControlTwoAxis::IselLinearControlTwoAxis()
15 {
16  steps_per_second_x_ = 40000;
17  steps_per_second_y_ = 40000;
18  //preset defaults, can be overwritten by Init.
19  steps_per_mm_x_ = 160;
20  steps_per_mm_y_ = 320;
21 }
22 
23 IselLinearControlTwoAxis::IselLinearControlTwoAxis(const int steps_per_mm_x, const int steps_per_mm_y)
24 {
25  steps_per_mm_x_ = steps_per_mm_x;
26  steps_per_mm_y_ = steps_per_mm_y;
27 }
28 
29 IselLinearControlTwoAxis::~IselLinearControlTwoAxis() {}
30 
31 int IselLinearControlTwoAxis::Reset(const int axis)
32 {
33  stringstream cmd;
34  cmd << "@0R" << axis << "\r";
35 
36  // axis should be 1-x, 2-y, or 3 x+y
37  if((axis > 0)&& (axis<4)){
38  SendRawCommand(cmd.str());
39  return CheckStatus();
40  } else {
41  return -1;
42  }
43 }
44 
45 int IselLinearControlTwoAxis::Init(const int nCOMportNumber)
46 {
47  char COMportPrefix[10] = "/dev/ttyS";
48  char COMportName[17];
49  sprintf(COMportName, "%s%d", COMportPrefix, nCOMportNumber);
50  return Init(COMportName);
51 }
52 
53 int IselLinearControlTwoAxis::Init(const char *COMportName)
54 {
55  cout << "Opening port " << COMportName << " for Isel Linear."<<endl;
56  COMstream_ = open_host_port((char*)COMportName);
57  if (COMstream_ == PORT_NOT_OPENED) {
58  return -1;
59  }
60 
61 #ifndef WIN32
62  // ofl: Set baud rate to 19200
63  struct termios info;
64 
65  info.c_iflag = IGNBRK | IGNPAR;
66  info.c_iflag &= ~(INLCR | ICRNL | IUCLC | ISTRIP | IXON | BRKINT);
67  info.c_oflag &= ~OPOST;
68  info.c_lflag &= ~(ICANON | ISIG | ECHO);
69  info.c_cflag = B19200 | CS8 | CREAD | CLOCAL;
70 
71  if (tcsetattr(COMstream_, TCSANOW, &info) < 0)
72  {
73  cout << "Error using TCSETS in ioctl" << endl;
74  close_host_port(COMstream_);
75  return -1;
76  }
77 #endif
78 
79  SendRawCommand("@03\r");
80  return CheckStatus();
81 }
82 
83 void IselLinearControlTwoAxis::Close()
84 {
85  close_host_port(COMstream_);
86 }
87 
88 
89 int IselLinearControlTwoAxis::SetSpeed(const float speedX, const float speedY)
90 {
91  int tmp_speed_in_steps_x = (int) speedX * steps_per_mm_x_;
92  int tmp_speed_in_steps_y = (int) speedY * steps_per_mm_y_;
93 
94  if (tmp_speed_in_steps_x > 0 && tmp_speed_in_steps_x <= 40000 &&
95  tmp_speed_in_steps_y > 0 && tmp_speed_in_steps_y <= 40000) {
96  steps_per_second_x_ = tmp_speed_in_steps_x;
97  steps_per_second_y_ = tmp_speed_in_steps_y;
98  return 0;
99  } else {
100  stringstream tmp;
101  tmp << "speed out of bounds, use value 1..40000 steps per second (" << (1/steps_per_mm_x_) << " < x < "<< (40000/steps_per_mm_x_) <<", " << (1/steps_per_mm_y_) << " < y < "<< (40000/steps_per_mm_y_) <<" [mm/s])";
102  BIASERR(tmp.str());
103  return -1;
104  }
105 }
106 
107 void IselLinearControlTwoAxis::GetSpeed(float &speedX, float &speedY)
108 {
109  speedX = steps_per_second_x_ / steps_per_mm_x_;
110  speedY = steps_per_second_y_ / steps_per_mm_y_;
111 }
112 
113 int IselLinearControlTwoAxis::SetAcceleration(const int accel)
114 {
115  /* TODO
116  stringstream s;
117  s << "@0_" << accel << "\r";
118  SendRawCommand(s.str());
119  return CheckStatus();
120  */
121  BIASERR("implement me");
122  return 0;
123 }
124 
125 void IselLinearControlTwoAxis::GetAcceleration(int &accel)
126 {
127  // TODO
128  BIASERR("implement me");
129 }
130 
131 int IselLinearControlTwoAxis::Move(const float millimetersX, const float millimetersY)
132 {
133  float stepsX, stepsY;
134  stepsX = millimetersX * steps_per_mm_x_;
135  stepsY = millimetersY * steps_per_mm_y_;
136 
137  int nValueX = (int)stepsX;
138  int nValueY = (int)stepsY;
139 
140  if (stepsX - (float)nValueX > 0.0f) {
141  BIASWARN("\nwant to move " << stepsX << " steps. flooring to " << nValueX << " steps, loosing precision.\n");
142  }
143 
144  if (stepsY - (float)nValueY > 0.0f) {
145  BIASWARN("\nwant to move " << stepsY << " steps. flooring to " << nValueY << " steps, loosing precision.\n");
146  }
147 
148  stringstream s;
149  s << "@0A" << nValueX << "," << steps_per_second_x_ << "," << nValueY << "," << steps_per_second_y_ << "\r";
150  SendRawCommand(s.str());
151  return CheckStatus();
152 }
153 
154 void IselLinearControlTwoAxis::GetCurrentPosition(float &millimetersX, float &millimetersY)
155 {
156  string output;
157  stringstream ss;
158  int i, size = 0;
159  SendRawCommand("@0P\r");
160  while (size == 0) {
161  size = ReadRawLine(output);
162  }
163 
164  if(size >= 18){
165  if(output.c_str()[size-18] >= '8')
166  ss << "FF";
167  else
168  ss << "0";
169  ss << output.substr(size-18,6);
170  ss >> hex >> i;
171  millimetersX = (float) i / (float) steps_per_mm_x_;
172 
173  ss.str("");
174  if(output.c_str()[size-12] >= '8')
175  ss << "FF";
176  else
177  ss << "0";
178  ss << output.substr(size-12,6);
179  ss >> hex >> i;
180  millimetersY = (float) i / (float) steps_per_mm_y_;
181  } else {
182  BIASWARN("\ncant determine position! \n");
183  }
184 }
185 
186 int IselLinearControlTwoAxis::SetPosition(const float millimetersX, const float millimetersY, const bool bWaitComplete)
187 {
188  float posX = millimetersX * (float) steps_per_mm_x_;
189  float posY = millimetersY * (float) steps_per_mm_y_;
190 
191  int nValueX = (int)posX;
192  int nValueY = (int)posY;
193 
194  if (posX - (float)nValueX > 0.0f) {
195  BIASWARN("\nwant to move to position " << posX << " in steps on x-axis. flooring to position " << nValueX << " in steps, loosing precision.\n");
196  }
197 
198  if (posY - (float)nValueY > 0.0f) {
199  BIASWARN("\nwant to move to position " << posY << " in steps on y-axis. flooring to position " << nValueY << " in steps, loosing precision.\n");
200  }
201 
202  stringstream s;
203  s << "@0M" << nValueX << "," << steps_per_second_x_ << "," << nValueY << "," << steps_per_second_y_ << "\r";
204  SendRawCommand(s.str());
205 
206  if (bWaitComplete) {
207  return CheckStatus();
208  }
209  return 0;
210 }
211 
212 void IselLinearControlTwoAxis::SendRawCommand(const string cmd) {
213  SerialStringOut(COMstream_, (unsigned char*) cmd.c_str());
214 
215 }
216 
217 int IselLinearControlTwoAxis::ReadRawLine(string &cmd) {
218  char result[0xFF];
219  int len = 0;
220  ReadSerialLine(COMstream_, (unsigned char*)result,1,&len);
221  cmd = string(result,len);
222  return len;
223 }
224 
225 int IselLinearControlTwoAxis::CheckStatus() {
226  string test;
227  unsigned int i = 0;
228  while (ReadRawLine(test) == 0) {
229  }
230  while (i < test.size() && test.c_str()[i] == '0') {
231  i++;
232  }
233  if (test.size() == i) {
234  // no error
235  return 0;
236  } else {
237  unsigned char c = test.c_str()[i];
238  switch (c) {
239  case '2':
240  BIASERR("reached limit - move free and reset");
241  SendRawCommand("@0F3\r");
242  return (CheckStatus() == 0 ? Reset() : -1);
243  case '9':
244  BIASERR("possible emergency stop - reinit and reset");
245  SendRawCommand("@03\r");
246  return (CheckStatus() == 0 ? Reset() : -1);
247  case 'D':
248  BIASERR("speed out of bounds");
249  return -1;
250  case 'R':
251  BIASERR("need to reset");
252  return Reset();
253  default:
254  BIASERR("Got Errorcode: " << test);
255  return -1;
256  }
257  }
258  BIASERR("unknown response: " << test);
259  return -1;
260 }