driver.cpp
Go to the documentation of this file.
1 /*
2  * flir_ptu_driver ROS package
3  * Copyright (C) 2014 Mike Purvis (mpurvis@clearpathrobotics.com)
4  *
5  * PTU ROS Package
6  * Copyright (C) 2009 Erik Karulf (erik@cse.wustl.edu)
7  *
8  * Author: Toby Collett (University of Auckland)
9  * Date: 2003-02-10
10  *
11  * Player - One Hell of a Robot Server
12  * Copyright (C) 2000 Brian Gerkey & Kasper Stoy
13  * gerkey@usc.edu kaspers@robotics.usc.edu
14  *
15  * This program is free software; you can redistribute it and/or modify
16  * it under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 of the License, or
18  * (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28  *
29  */
30 
31 #include <boost/lexical_cast.hpp>
32 #include <boost/algorithm/string/trim.hpp>
33 #include <flir_ptu_driver/driver.h>
34 #include <serial/serial.h>
35 #include <ros/console.h>
36 
37 #include <math.h>
38 #include <string>
39 
40 using boost::lexical_cast;
41 
42 
43 namespace flir_ptu_driver
44 {
45 
49 template<typename T>
50 T parseResponse(std::string responseBuffer)
51 {
52  std::string trimmed = responseBuffer.substr(1);
53  boost::trim(trimmed);
54 
55  if (trimmed.empty())
56  {
57  trimmed = "0";
58  }
59 
60  T parsed = lexical_cast<T>(trimmed);
61  ROS_DEBUG_STREAM("Parsed response value: " << parsed);
62  return parsed;
63 }
64 
66 {
67  return !!ser_ && ser_->isOpen() && initialized_;
68 }
69 
71 {
72  ser_->write("ld "); // Disable Limits
73  ser_->read(20);
74  Lim = false;
75  return true;
76 }
77 
79 {
80  ser_->write("ft "); // terse feedback
81  ser_->write("ed "); // disable echo
82  ser_->write("ci "); // position mode
83  ser_->read(20);
84 
85  // get pan tilt encoder res
86  tr = getRes(PTU_TILT);
87  pr = getRes(PTU_PAN);
88 
97  Lim = true;
98 
99  if (tr <= 0 || pr <= 0 || PMin == -1 || PMax == -1 || TMin == -1 || TMax == -1)
100  {
101  initialized_ = false;
102  }
103  else
104  {
105  initialized_ = true;
106  }
107 
108  return initialized();
109 }
110 
111 std::string PTU::sendCommand(std::string command)
112 {
113  ser_->write(command);
114  ROS_DEBUG_STREAM("TX: " << command);
115  std::string buffer = ser_->readline(PTU_BUFFER_LEN);
116  ROS_DEBUG_STREAM("RX: " << buffer);
117  return buffer;
118 }
119 
120 bool PTU::home()
121 {
122  ROS_INFO("Sending command to reset PTU.");
123 
124  // Issue reset command
125  ser_->flush();
126  ser_->write(" r ");
127 
128  std::string actual_response, expected_response("!T!T!P!P*");
129 
130  // 30 seconds to receive full confirmation of reset action completed.
131  for (int i = 0; i < 300; i++)
132  {
133  usleep(100000);
134 
135  if (ser_->available() >= expected_response.length())
136  {
137  ROS_INFO("PTU reset command response received.");
138  ser_->read(actual_response, expected_response.length());
139  return (actual_response == expected_response);
140  }
141  }
142 
143  ROS_WARN("PTU reset command response not received before timeout.");
144  return false;
145 }
146 
147 // get radians/count resolution
148 float PTU::getRes(char type)
149 {
150  if (!ser_ || !ser_->isOpen()) return -1;
151 
152  std::string buffer = sendCommand(std::string() + type + "r ");
153 
154  if (buffer.length() < 3 || buffer[0] != '*')
155  {
156  ROS_ERROR_THROTTLE(30, "Error getting pan-tilt res");
157  return -1;
158  }
159 
160  double z = parseResponse<double>(buffer);
161  z = z / 3600; // degrees/count
162  return z * M_PI / 180; // radians/count
163 }
164 
165 // get position limit
166 int PTU::getLimit(char type, char limType)
167 {
168  if (!ser_ || !ser_->isOpen()) return -1;
169 
170  std::string buffer = sendCommand(std::string() + type + limType + " ");
171 
172  if (buffer.length() < 3 || buffer[0] != '*')
173  {
174  ROS_ERROR_THROTTLE(30, "Error getting pan-tilt limit");
175  return -1;
176  }
177 
178  return parseResponse<int>(buffer);
179 }
180 
181 
182 // get position in radians
183 float PTU::getPosition(char type)
184 {
185  if (!initialized()) return -1;
186 
187  std::string buffer = sendCommand(std::string() + type + "p ");
188 
189  if (buffer.length() < 3 || buffer[0] != '*')
190  {
191  ROS_ERROR_THROTTLE(30, "Error getting pan-tilt pos");
192  return -1;
193  }
194 
195  return parseResponse<double>(buffer) * getResolution(type);
196 }
197 
198 
199 // set position in radians
200 bool PTU::setPosition(char type, float pos, bool block)
201 {
202  if (!initialized()) return false;
203 
204  // get raw encoder count to move
205  int count = static_cast<int>(pos / getResolution(type));
206 
207  // Check limits
208  if (Lim)
209  {
210  if (count < (type == PTU_TILT ? TMin : PMin) || count > (type == PTU_TILT ? TMax : PMax))
211  {
212  ROS_ERROR_THROTTLE(30, "Pan Tilt Value out of Range: %c %f(%d) (%d-%d)\n",
213  type, pos, count, (type == PTU_TILT ? TMin : PMin), (type == PTU_TILT ? TMax : PMax));
214  return false;
215  }
216  }
217 
218  std::string buffer = sendCommand(std::string() + type + "p" +
219  lexical_cast<std::string>(count) + " ");
220 
221  if (buffer.empty() || buffer[0] != '*')
222  {
223  ROS_ERROR("Error setting pan-tilt pos");
224  return false;
225  }
226 
227  if (block)
228  {
229  while (getPosition(type) != pos)
230  {
231  usleep(1000);
232  }
233  }
234 
235  return true;
236 }
237 
238 // get speed in radians/sec
239 float PTU::getSpeed(char type)
240 {
241  if (!initialized()) return -1;
242 
243  std::string buffer = sendCommand(std::string() + type + "s ");
244 
245  if (buffer.length() < 3 || buffer[0] != '*')
246  {
247  ROS_ERROR("Error getting pan-tilt speed");
248  return -1;
249  }
250 
251  return parseResponse<double>(buffer) * getResolution(type);
252 }
253 
254 
255 
256 // set speed in radians/sec
257 bool PTU::setSpeed(char type, float pos)
258 {
259  if (!initialized()) return false;
260 
261  // get raw encoder speed to move
262  int count = static_cast<int>(pos / getResolution(type));
263 
264  // Check limits
265  if (abs(count) < (type == PTU_TILT ? TSMin : PSMin) || abs(count) > (type == PTU_TILT ? TSMax : PSMax))
266  {
267  ROS_ERROR("Pan Tilt Speed Value out of Range: %c %f(%d) (%d-%d)\n",
268  type, pos, count, (type == PTU_TILT ? TSMin : PSMin), (type == PTU_TILT ? TSMax : PSMax));
269  return false;
270  }
271 
272  std::string buffer = sendCommand(std::string() + type + "s" +
273  lexical_cast<std::string>(count) + " ");
274 
275  if (buffer.empty() || buffer[0] != '*')
276  {
277  ROS_ERROR("Error setting pan-tilt speed\n");
278  return false;
279  }
280 
281  return true;
282 }
283 
284 
285 // set movement mode (position/velocity)
286 bool PTU::setMode(char type)
287 {
288  if (!initialized()) return false;
289 
290  std::string buffer = sendCommand(std::string("c") + type + " ");
291 
292  if (buffer.empty() || buffer[0] != '*')
293  {
294  ROS_ERROR("Error setting pan-tilt move mode");
295  return false;
296  }
297 
298  return true;
299 }
300 
301 // get ptu mode
303 {
304  if (!initialized()) return -1;
305 
306  // get pan tilt mode
307  std::string buffer = sendCommand("c ");
308 
309  if (buffer.length() < 3 || buffer[0] != '*')
310  {
311  ROS_ERROR("Error getting pan-tilt pos");
312  return -1;
313  }
314 
315  if (buffer[2] == 'p')
316  return PTU_VELOCITY;
317  else if (buffer[2] == 'i')
318  return PTU_POSITION;
319  else
320  return -1;
321 }
322 
323 } // namespace flir_ptu_driver
size_t available()
float getPosition(char type)
Definition: driver.cpp:183
size_t readline(std::string &buffer, size_t size=65536, std::string eol="\n")
bool setPosition(char type, float pos, bool Block=false)
Definition: driver.cpp:200
bool setMode(char type)
Definition: driver.cpp:286
int TMin
Min Tilt in Counts.
Definition: driver.h:185
int PMin
Min Pan in Counts.
Definition: driver.h:187
#define PTU_MAX_SPEED
Definition: driver.h:47
bool Lim
Position Limits enabled.
Definition: driver.h:189
#define PTU_BUFFER_LEN
Definition: driver.h:36
int getLimit(char type, char limType)
Definition: driver.cpp:166
float getResolution(char type)
Definition: driver.h:97
#define ROS_WARN(...)
#define ROS_ERROR_THROTTLE(rate,...)
#define PTU_POSITION
Definition: driver.h:49
#define PTU_PAN
Definition: driver.h:42
serial::Serial * ser_
Definition: driver.h:205
#define ROS_INFO(...)
int PSMin
Min Pan Speed in Counts/second.
Definition: driver.h:194
#define PTU_MIN
Definition: driver.h:44
int TSMax
Max Tilt Speed in Counts/second.
Definition: driver.h:193
bool isOpen() const
float getRes(char type)
Definition: driver.cpp:148
#define ROS_DEBUG_STREAM(args)
int PMax
Max Pan in Counts.
Definition: driver.h:188
TFSIMD_FORCE_INLINE const tfScalar & z() const
T parseResponse(std::string responseBuffer)
Definition: driver.cpp:50
#define PTU_MIN_SPEED
Definition: driver.h:46
float tr
tilt resolution (rads/count)
Definition: driver.h:208
int PSMax
Max Pan Speed in Counts/second.
Definition: driver.h:195
std::string sendCommand(std::string command)
Definition: driver.cpp:111
INLINE Rall1d< T, V, S > abs(const Rall1d< T, V, S > &x)
float getSpeed(char type)
Definition: driver.cpp:239
size_t read(uint8_t *buffer, size_t size)
int TSMin
Min Tilt Speed in Counts/second.
Definition: driver.h:192
#define PTU_MAX
Definition: driver.h:45
float pr
pan resolution (rads/count)
Definition: driver.h:209
bool setSpeed(char type, float speed)
Definition: driver.cpp:257
#define PTU_VELOCITY
Definition: driver.h:48
bool disableLimits()
Definition: driver.cpp:70
int TMax
Max Tilt in Counts.
Definition: driver.h:186
#define ROS_ERROR(...)
size_t write(const uint8_t *data, size_t size)
#define PTU_TILT
Definition: driver.h:43


flir_ptu_driver
Author(s): Erik Karulf , David V. Lu , Nick Hawes
autogenerated on Sun Mar 28 2021 02:27:16