proxy.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2017 rerobots, Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <iostream>
17 #include <vector>
18 #include <string>
19 #include <cstdlib>
20 
21 #include <boost/thread/thread.hpp>
22 
23 #include "ros/ros.h"
24 #include "serial/serial.h"
25 
26 #include "brunel_hand_ros/FingerPose.h"
27 #include "brunel_hand_ros/RawCommand.h"
28 #include "brunel_hand_ros/HandPrimitive.h"
29 
30 
32 {
33 public:
35  : connected( false )
36  {}
37 
38  BrunelHand( std::string devfile );
39 
40  std::vector<int> readFingersPose();
41 
42  /* Attempt (blocking) to get current firmware diagnostics.
43  This method is atomic with respect to diagnostics data, i.e., either all
44  known parameters are updated, or none at all. */
45  void updateDiagnostics();
46 
47  /* Apply string directly as input to firmware connection.
48  A newline character is appended to the given string. Of course, injection
49  of multiple commands is feasible here, but the input is assumed to be
50  trusted. Future versions may provide guards. */
51  void rawCommand( std::string cmd );
52 
53  void callbackRawCommand( const brunel_hand_ros::RawCommand &rc );
54 
55  void callbackMotionPrimitive( const brunel_hand_ros::HandPrimitive &hp );
56 
57  /* Enable CSV mode.
58  Diagnostics data are updated to verify whether CSV mode is enabled. */
59  void useCSVmode();
60 
61  /* Enable motors if they are not already. */
62  void enableMotors();
63 
64  bool getCSVmode() const;
65  bool getMotorsEnabled() const;
66  bool isConnected() const;
67 
68 private:
69  bool csvMode;
71  bool connected;
73  boost::mutex mtx_;
74 };
75 
76 void BrunelHand::rawCommand( std::string cmd )
77 {
78  mtx_.lock();
79  bhandcom.flush();
80  ROS_INFO( "SENDING: %s ", cmd.c_str() );
81  bhandcom.write( cmd + "\n" );
82  mtx_.unlock();
83 }
84 
85 void BrunelHand::callbackRawCommand( const brunel_hand_ros::RawCommand &rc )
86 {
87  rawCommand( rc.command );
88 }
89 
90 void BrunelHand::callbackMotionPrimitive( const brunel_hand_ros::HandPrimitive &hp )
91 {
92  switch (hp.primitive) {
93  case 0: // Fist
94  rawCommand( "G0" );
95  break;
96 
97  case 1: // Palm
98  rawCommand( "G1" );
99  break;
100 
101  case 2: // Thumbs Up
102  rawCommand( "G2" );
103  break;
104 
105  case 3: // Point
106  rawCommand( "G3" );
107  break;
108 
109  case 4: // Pinch
110  rawCommand( "G4" );
111  break;
112 
113  case 5: // Tripod
114  rawCommand( "G5" );
115  break;
116 
117  case 6: // Finger Roll
118  rawCommand( "G6" );
119  break;
120 
121  case 7: // Thumb Roll
122  rawCommand( "G7" );
123  break;
124  }
125 }
126 
127 BrunelHand::BrunelHand( std::string devfile )
128  : bhandcom( devfile, 115200,
129  serial::Timeout::simpleTimeout(1000) ),
130  connected( false )
131 {
132  if (!bhandcom.isOpen()) {
133  ROS_ERROR( "Failed to connect using %s", devfile.c_str() );
134  return;
135  }
136 
137  connected = true;
138  ROS_INFO( "Connected via %s", devfile.c_str() );
139 
141 }
142 
143 std::vector<int> BrunelHand::readFingersPose()
144 {
145  std::vector<int> fpose;
146 
147  std::string line;
148  mtx_.lock();
149  // If first item is not digit, then assume that this messages is not the CSV
150  // finger data message type.
151  do {
152  line = bhandcom.readline();
153  } while (line[0] != '0' && line[0] != '1' && line[0] != '2'
154  && line[0] != '3' && line[0] != '4' && line[0] != '5'
155  && line[0] != '6' && line[0] != '7' && line[0] != '8'
156  && line[0] != '9');
157  mtx_.unlock();
158 
159  int thispos = -1; // -1 => first search is with respect to position 0
160  int nextpos = 0;
161  std::string numstring;
162  while ((nextpos = line.find( "," , thispos+1))
163  != std::string::npos) {
164  numstring = line.substr( thispos+1, nextpos-thispos-1 );
165  thispos = nextpos;
166  fpose.push_back( std::atoi( numstring.c_str() ) );
167  }
168  numstring = line.substr( thispos+1 );
169  if (numstring[0] != ' '
170  && numstring[0] != '\r'
171  && numstring[0] != '\n')
172  fpose.push_back( std::atoi( numstring.c_str() ) );
173  return fpose;
174 }
175 
177 {
178  return csvMode;
179 }
180 
182 {
183  return motorsEnabled;
184 }
185 
187 {
188  this->updateDiagnostics();
189  if (csvMode)
190  return;
191 
192  mtx_.lock();
193  bhandcom.flush();
194  bhandcom.write( "A4\n" );
195  std::string line;
196  do {
197  line = bhandcom.readline();
198  } while (line.substr( 0, 8 ) != "CSV mode");
199  mtx_.unlock();
200 }
201 
203 {
204  this->updateDiagnostics();
205  if (motorsEnabled)
206  return;
207 
208  mtx_.lock();
209  bhandcom.flush();
210  bhandcom.write( "A3\n" );
211  std::string line;
212  do {
213  line = bhandcom.readline();
214  } while (line.substr( 0, 14 ) != "Motors ENABLED");
215  mtx_.unlock();
216 }
217 
219 {
220  return connected;
221 }
222 
224 {
225  int incoming_csvMode = -1;
226  int incoming_motorsEnabled = -1;
227 
228  mtx_.lock();
229  bhandcom.write( "#\n" );
230  while (incoming_csvMode < 0 || incoming_motorsEnabled < 0) {
231  std::string line = bhandcom.readline();
232  if (line.substr( 0, 5 ) == "Mode:") {
233  if (line.find( "CSV" ) != std::string::npos) {
234  incoming_csvMode = 1;
235  } else {
236  incoming_csvMode = 0;
237  }
238  } else if (line.substr( 0, 7 ) == "Motors:") {
239  if (line.find( "ENABLED" ) != std::string::npos) {
240  incoming_motorsEnabled = 1;
241  } else {
242  incoming_motorsEnabled = 0;
243  }
244  }
245  }
246  mtx_.unlock();
247  csvMode = incoming_csvMode ? true : false;
248  motorsEnabled = incoming_motorsEnabled ? true : false;
249 }
250 
251 
252 int main( int argc, char **argv )
253 {
254  ros::init( argc, argv, "brunel_hand_proxy" );
255  ros::NodeHandle nh;
256  ros::Publisher posep;
257  ros::Subscriber subraw;
258  ros::Subscriber submotprimitive;
259 
260  std::string devfile;
261  nh.param( "hand_dev_file", devfile, std::string( "/dev/ttyACM0" ) );
262 
263  BrunelHand bhand( devfile );
264  bhand.useCSVmode();
265  bhand.enableMotors();
266 
267  posep = nh.advertise<brunel_hand_ros::FingerPose>( "fpose", 10, true );
268  subraw = nh.subscribe( "/raw_input", 1,
270  submotprimitive = nh.subscribe( "/motion_primitive",
271  1,
273  &bhand );
274 
275  ros::Rate rate( 100 );
276  while (ros::ok()) {
277  brunel_hand_ros::FingerPose currentpose;
278  currentpose.header.stamp = ros::Time::now();
279  currentpose.f = bhand.readFingersPose();
280  posep.publish( currentpose );
281 
282  ros::spinOnce();
283  rate.sleep();
284  }
285 
286  return 0;
287 }
size_t readline(std::string &buffer, size_t size=65536, std::string eol="\n")
void publish(const boost::shared_ptr< M > &message) const
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void callbackRawCommand(const brunel_hand_ros::RawCommand &rc)
Definition: proxy.cpp:85
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void rawCommand(std::string cmd)
Definition: proxy.cpp:76
int main(int argc, char **argv)
Definition: proxy.cpp:252
std::vector< int > readFingersPose()
Definition: proxy.cpp:143
bool isConnected() const
Definition: proxy.cpp:218
bool getCSVmode() const
Definition: proxy.cpp:176
bool connected
Definition: proxy.cpp:71
boost::mutex mtx_
Definition: proxy.cpp:73
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void useCSVmode()
Definition: proxy.cpp:186
ROSCPP_DECL bool ok()
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool isOpen() const
bool getMotorsEnabled() const
Definition: proxy.cpp:181
serial::Serial bhandcom
Definition: proxy.cpp:72
bool sleep()
void updateDiagnostics()
Definition: proxy.cpp:223
BrunelHand()
Definition: proxy.cpp:34
static Time now()
void callbackMotionPrimitive(const brunel_hand_ros::HandPrimitive &hp)
Definition: proxy.cpp:90
bool csvMode
Definition: proxy.cpp:69
ROSCPP_DECL void spinOnce()
void enableMotors()
Definition: proxy.cpp:202
#define ROS_ERROR(...)
bool motorsEnabled
Definition: proxy.cpp:70
size_t write(const uint8_t *data, size_t size)


brunel_hand_ros
Author(s): Scott C. Livingston
autogenerated on Mon Jun 10 2019 12:49:18