sdhx.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #ifndef HAND_BRIDGE_SDHX_H_
19 #define HAND_BRIDGE_SDHX_H_
20 
21 #include "serial_port.h"
22 #include "boost/format.hpp"
23 #include "boost/thread.hpp"
24 
25 class SDHX {
27  uint8_t rc;
28  volatile bool initialized, reading;
29  boost::mutex send_mutex;
30  boost::mutex data_mutex;
31  boost::thread read_thread;
32  boost::chrono::steady_clock::time_point last_time;
33 
34  void doRead(){
35  const size_t MAX_LINE = 1024;
36 
37  char buffer[MAX_LINE+1] = {0}; // extra byte for termination
38 
39  int a = 0, r = 1, offset = 0;
40  while(a >= 0 && r > 0){
41  if((a = serial.waitData(boost::chrono::milliseconds(1))) > 0 && (r = serial.read(buffer+offset, MAX_LINE-offset)) > 0){
42  char * line = buffer;
43  while(char * extra = strchr(line, '\n')){
44  *extra=0;
45  switch(line[0]){
46  case 'r': tryParseRC(line); break;
47  case 'P': tryReadValues(line, pos, "P=%hd,%hd", true); break;
48  case 'V': tryReadValues(line, vel, "V=%hd,%hd"); break;
49  case 'C': tryReadValues(line, cur, "C=%hd,%hd"); break;
50  }
51  line = extra+1;
52  }
53  offset = (buffer + offset + r - line);
54  strncpy(buffer, line, offset);
55  }
56  }
57  std::cerr << "stopped reading" << std::endl;
58  boost::mutex::scoped_lock lock(data_mutex);
59  reading = false;
60  }
61 
62  bool tryParseRC(const char *line){
63  uint8_t res;
64  if(sscanf(line, "rc=%hhx", &res) == 1){
65  if(res != 0){
66  boost::mutex::scoped_lock lock(data_mutex);
67  rc = res;
68  }
69  return true;
70  }
71  return false;
72  }
73  template<typename T> bool tryReadValues(const char *line, T (&val)[2], const char *format, bool track_time = false) {
74  T val1,val2;
75  if(sscanf(line, format, &val1, &val2) == 2){
76  boost::mutex::scoped_lock lock(data_mutex);
77  val[0] = val1;
78  val[1] = val2;
79  if(track_time){
80  //std::cout << "rate: " << 1.0/boost::chrono::duration_cast<boost::chrono::duration<double> >(boost::chrono::steady_clock::now() - last_time).count() << std::endl;
81  last_time = boost::chrono::steady_clock::now();
82  }
83  return true;
84  }
85  return false;
86  }
87 
88  bool send(const std::string &command){
89  boost::mutex::scoped_lock lock(send_mutex);
90  return serial.write(command);
91  }
92 
93  bool setPWM(const int16_t &val, const char *format) {
94  return val == 0 || send(boost::str(boost::format(format) % val));
95  }
96 
97  int16_t pos[2], vel[2], cur[2];
98 public:
99  SDHX() : rc(0), initialized(false), reading(false) {
100  }
101  ~SDHX(){
102  if(initialized && read_thread.joinable()){
103  read_thread.interrupt();
104  read_thread.join();
105  }
106  }
107  bool init(const char* port, int16_t min_pwm0, int16_t min_pwm1, int16_t max_pwm0, int16_t max_pwm1){
108  std::string dev(port);
109  if(!serial.isOpen() && !serial.init(&dev[0])) return false;
110 
111  boost::mutex::scoped_lock lock(data_mutex);
112  if(!reading){
113  reading = true;
114  read_thread = boost::thread(boost::bind(&SDHX::doRead, this));
115  }
116 
117  lock.unlock();
118  if(setPWM(min_pwm0, "set min_pwm0 %1%\r\n") &&
119  setPWM(min_pwm1, "set min_pwm1 %1%\r\n") &&
120  setPWM(max_pwm0, "set max_pwm0 %1%\r\n") &&
121  setPWM(max_pwm1, "set max_pwm1 %1%\r\n")){
122  lock.lock();
123  rc = 0;
124  initialized = true;
125  return true;
126  }
127  return false;
128  }
129  bool isInitialized() {
130  return initialized;
131  }
132 
133  template <typename Dur> bool getData(int16_t (&p)[2], int16_t (&v)[2], int16_t (&c)[2], const Dur &max_age){
134  boost::mutex::scoped_lock lock(data_mutex);
135  if((boost::chrono::steady_clock::now() - last_time) > max_age) return false;
136  if(!reading) return false;
137 
138  p[0] = pos[0];
139  p[1] = pos[1];
140  v[0] = vel[0];
141  v[1] = vel[1];
142  c[0] = cur[0];
143  c[1] = cur[1];
144 
145  return true;
146  }
147  bool poll(){
148  return initialized && send("p;v;c\r\n");
149  }
150  bool halt(){
151  return initialized && send("s\r\n");
152  }
153  bool move(const int16_t (&p)[2], const int16_t (&v)[2], const int16_t (&c)[2]){
154  static boost::format command("m %hd,%hd %hd,%hd %hd,%hd\r\n");
155  return initialized && send(boost::str(command % p[0] % p[1] % v[0] % v[1] % c[0] % c[1]));
156  }
157 /* bool move(const int16_t (&p)[2], const int16_t (&v)[2], const int16_t (&c)[2]){
158  static boost::format command("m %hd,%hd\r\n");
159  return initialized && send(boost::str(command % p[0] % p[1]));
160  }
161 */
162  uint8_t getRC(){
163  boost::mutex::scoped_lock lock(data_mutex);
164  return rc;
165  };
166 };
167 #endif // HAND_BRIDGE_SDHX_H_
bool write(uint8_t *data, int length)
Definition: serial_port.h:59
bool setPWM(const int16_t &val, const char *format)
Definition: sdhx.h:93
int read(char *buf, unsigned count)
Definition: serial_port.h:56
bool move(const int16_t(&p)[2], const int16_t(&v)[2], const int16_t(&c)[2])
Definition: sdhx.h:153
bool init(char *param)
Definition: serial_port.h:33
bool init(const char *port, int16_t min_pwm0, int16_t min_pwm1, int16_t max_pwm0, int16_t max_pwm1)
Definition: sdhx.h:107
volatile bool initialized
Definition: sdhx.h:28
int16_t cur[2]
Definition: sdhx.h:97
uint8_t rc
Definition: sdhx.h:27
bool isInitialized()
Definition: sdhx.h:129
int waitData(const Duration &duration)
Definition: serial_port.h:45
bool poll()
Definition: sdhx.h:147
bool getData(int16_t(&p)[2], int16_t(&v)[2], int16_t(&c)[2], const Dur &max_age)
Definition: sdhx.h:133
int16_t pos[2]
Definition: sdhx.h:97
Definition: sdhx.h:25
bool tryReadValues(const char *line, T(&val)[2], const char *format, bool track_time=false)
Definition: sdhx.h:73
boost::mutex send_mutex
Definition: sdhx.h:29
boost::chrono::steady_clock::time_point last_time
Definition: sdhx.h:32
bool halt()
Definition: sdhx.h:150
SDHX()
Definition: sdhx.h:99
ROSLIB_DECL std::string command(const std::string &cmd)
int r
Definition: DHT22.py:259
~SDHX()
Definition: sdhx.h:101
volatile bool reading
Definition: sdhx.h:28
bool tryParseRC(const char *line)
Definition: sdhx.h:62
boost::mutex data_mutex
Definition: sdhx.h:30
int16_t vel[2]
Definition: sdhx.h:97
bool send(const std::string &command)
Definition: sdhx.h:88
void doRead()
Definition: sdhx.h:34
bool isOpen() const
Definition: serial_port.h:30
uint8_t getRC()
Definition: sdhx.h:162
boost::thread read_thread
Definition: sdhx.h:31
SerialPort serial
Definition: sdhx.h:26


cob_hand_bridge
Author(s): Mathias Lüdtke
autogenerated on Tue Oct 20 2020 03:35:57