bridge.cpp
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 #include <ros/node_handle.h>
19 
22 #include <cob_hand_bridge/SetPWM.h>
24 #include <cob_hand_bridge/Status.h>
25 #include <std_msgs/UInt8.h>
26 #include <std_srvs/Trigger.h>
27 
28 #include <boost/thread/thread.hpp>
29 #include <boost/scoped_ptr.hpp>
30 
31 #include "hardware.h"
32 #include "gpio.h"
33 #include "sdhx.h"
34 
37 
38 
39 // SDHX
40 boost::scoped_ptr<SDHX> g_sdhx;
41 
43 
44 InitFinger::Request g_init_req;
45 std::string g_port;
46 
47 bool initFinger(const InitFinger::Request & req){
48  if(!g_sdhx){
49  g_sdhx.reset(new SDHX);
50  if(g_sdhx->init(req.port, req.min_pwm0, req.min_pwm1, req.max_pwm0, req.max_pwm1)){
51  g_port = req.port;
52  g_init_req = req;
53  g_init_req.port = g_port.c_str();
54  return true;
55  }
56  }
57  return false;
58 }
59 
60 void handleInitFinger(const InitFinger::Request & req, InitFinger::Response & res){
61  res.success = initFinger(req);
62 }
64 
65 using std_srvs::Trigger;
66 void handleHaltFinger(const Trigger::Request & req, Trigger::Response & res){
67  res.success = g_sdhx && g_sdhx->halt();
68 }
70 
71 void handleRecover(const Trigger::Request & req, Trigger::Response & res){
72  if(g_sdhx) {
73  if((g_status_msg.status & g_status_msg.MASK_ERROR) == 0 && g_status_msg.rc == 0) {
74  res.success = true;
75  }else if(g_sdhx->isInitialized()) {
76  g_sdhx.reset();
77  res.success = initFinger(g_init_req);
78  if(res.success) g_status_msg.status &= ~g_status_msg.MASK_ERROR;
79  g_status_msg.rc = 0;
80  }else{
81  res.message = "Not initialized";
82  }
83  }
84 }
86 
89 }
91 
92 // GPIO
94 
96 
97 void handleInitPins(const InitPins::Request & req, InitPins::Response & res){
98  res.success = g_gpio.init();
99 
100  for(size_t i = 0; i < req.input_pins_length; ++i)
101  if(!g_gpio.setInput(req.input_pins[i]))
102  res.success = false;
103 
104  for(size_t i = 0; i < req.output_pins_length; ++i)
105  if(!g_gpio.setOutput(req.output_pins[i]))
106  res.success = false;
107 }
109 
111 void handleUpdatePins(const UpdatePins::Request & req, UpdatePins::Response & res){
112  res.success = g_gpio.setPins(req.set_pins) | g_gpio.clearPins(req.clear_pins);
113  uint32_t state = g_gpio.getState();
114  res.success = res.success && (state & req.set_pins) == req.set_pins && (state & req.clear_pins) == 0;
115 }
117 
119  g_gpio.writePin(mgs.data, 0);
120 }
122 
123 void handleSetPin(const std_msgs::UInt8& mgs){
124  g_gpio.writePin(mgs.data, 1);
125 }
127 
128 ros::Publisher g_pub("status", &g_status_msg);
129 
131 
132 void handleSetPWM(const SetPWM::Request & req, SetPWM::Response & res){
133 
134  if(req.pins_length != req.levels_length){
135  res.success = false;
136  return;
137  }
138  res.success = true;
139 
140  for(size_t i = 0; i < req.pins_length; ++i)
141  if(!g_gpio.pwmPin(req.pins[i],req.levels[i]))
142  res.success = false;
143 }
145 
146 void step(){
147  g_status_msg.stamp = g_nh.now();
148 
149  g_status_msg.status = g_status_msg.NOT_INITIALIZED;
150  if(g_gpio.isInitialized()) g_status_msg.status |= g_status_msg.MASK_GPIO_READY;
151 
152  cob_hand_bridge::JointValues &j= g_status_msg.joints;
153 
154  if(g_sdhx && g_sdhx->isInitialized()){
155  if(g_sdhx->getData(j.position_cdeg, j.velocity_cdeg_s, j.current_100uA, boost::chrono::seconds(1))) g_status_msg.status |= g_status_msg.MASK_FINGER_READY;
156  else g_status_msg.status |= g_status_msg.MASK_ERROR;
157  g_status_msg.rc = g_sdhx->getRC();
158  }
159 
160  g_status_msg.pins = g_gpio.getState();
161 
162  g_pub.publish( &g_status_msg );
163  g_nh.spinOnce();
164 
165  if(g_sdhx) g_sdhx->poll();
166 
167  ++g_status_msg.seq;
168 }
169 
170 int main(int argc, char** argv){
171 
172  double rate = 20;
173 
174  if(argc != 2 && argc != 3){
175  std::cerr << "Usage: " << argv[0] << " port@baud [looprate]" << std::endl;
176  exit(1);
177  }
178  if(argc == 3){
179  rate = boost::lexical_cast<double>(argv[2]);
180  if(rate <= 0.0){
181  std::cerr << "Rate must be postive" << std::endl;
182  exit(1);
183  }
184  }
185 
186  std::string dev(argv[1]);
187  g_nh.initNode(&dev[0]);
188 
189  g_nh.advertiseService(g_srv_init_finger);
190  g_nh.advertiseService(g_srv_halt_finger);
191  g_nh.advertiseService(g_srv_recover);
192  g_nh.subscribe(g_sub_command);
193 
195  g_nh.advertiseService(g_srv_set_pwm);
196  g_nh.advertiseService(g_srv_update_pins);
197  g_nh.subscribe(g_sub_clear_pin);
198  g_nh.subscribe(g_sub_set_pin);
199 
200  g_nh.advertise(g_pub);
201 
202  boost::chrono::duration<double> double_interval(1.0/rate);
203  boost::chrono::milliseconds interval = boost::chrono::duration_cast<boost::chrono::milliseconds>(double_interval);
204  boost::chrono::steady_clock::time_point next = boost::chrono::steady_clock::now();
205 
206  while(true) {
207  step();
208  next += interval;
209  boost::this_thread::sleep_until(next);
210  }
211 
212  return 0;
213 }
cob_hand_bridge::Status g_status_msg
Definition: bridge.cpp:36
ros::ServiceServer< UpdatePins::Request, UpdatePins::Response > g_srv_update_pins("update_pins",&handleUpdatePins)
ros::Subscriber< cob_hand_bridge::JointValues > g_sub_command("command", handleJointCommand)
uint8_t data
Definition: UInt8.h:32
std::string g_port
Definition: bridge.cpp:45
ros::Subscriber< std_msgs::UInt8 > g_sub_clear_pin("clear_pin", handleClearPin)
void publish(const boost::shared_ptr< M > &message) const
bool setInput(uint32_t pin)
Definition: gpio.h:32
ros::Subscriber< std_msgs::UInt8 > g_sub_set_pin("set_pin", handleSetPin)
void handleInitFinger(const InitFinger::Request &req, InitFinger::Response &res)
Definition: bridge.cpp:60
void handleUpdatePins(const UpdatePins::Request &req, UpdatePins::Response &res)
Definition: bridge.cpp:111
bool subscribe(Subscriber< MsgT > &s)
Definition: node_handle.h:335
uint32_t getState()
Definition: gpio.h:68
boost::scoped_ptr< SDHX > g_sdhx
Definition: bridge.cpp:40
GPIO g_gpio
Definition: bridge.cpp:93
bool setOutput(uint32_t pin)
Definition: gpio.h:35
bool init()
Definition: gpio.h:42
Definition: sdhx.h:25
bool pwmPin(uint32_t pin, float level)
Definition: gpio.h:57
void handleJointCommand(const cob_hand_bridge::JointValues &j)
Definition: bridge.cpp:87
ros::ServiceServer< SetPWM::Request, SetPWM::Response > g_srv_set_pwm("set_pwm",&handleSetPWM)
void handleRecover(const Trigger::Request &req, Trigger::Response &res)
Definition: bridge.cpp:71
ros::Publisher g_pub("status",&g_status_msg)
ros::NodeHandle_< HandBridgeHardware > g_nh
Definition: bridge.cpp:35
void step()
Definition: bridge.cpp:146
int main(int argc, char **argv)
Definition: bridge.cpp:170
ros::ServiceServer< InitFinger::Request, InitFinger::Response > g_srv_init_finger("init_finger",&handleInitFinger)
void handleSetPin(const std_msgs::UInt8 &mgs)
Definition: bridge.cpp:123
void handleHaltFinger(const Trigger::Request &req, Trigger::Response &res)
Definition: bridge.cpp:66
cob_hand_bridge::JointValues joints
Definition: Status.h:39
ros::ServiceServer< InitPins::Request, InitPins::Response > g_srv_init_pins("init_pins",&handleInitPins)
void handleInitPins(const InitPins::Request &req, InitPins::Response &res)
Definition: bridge.cpp:97
bool setPins(uint32_t pins)
Definition: gpio.h:48
bool initFinger(const InitFinger::Request &req)
Definition: bridge.cpp:47
InitFinger::Request g_init_req
Definition: bridge.cpp:44
bool advertise(Publisher &p)
Definition: node_handle.h:320
bool clearPins(uint32_t pins)
Definition: gpio.h:45
Definition: gpio.h:23
void handleClearPin(const std_msgs::UInt8 &mgs)
Definition: bridge.cpp:118
ros::ServiceServer< Trigger::Request, Trigger::Response > g_srv_halt_finger("halt",&handleHaltFinger)
bool advertiseService(ServiceServer< MReq, MRes > &srv)
Definition: node_handle.h:348
void handleSetPWM(const SetPWM::Request &req, SetPWM::Response &res)
Definition: bridge.cpp:132
ros::ServiceServer< Trigger::Request, Trigger::Response > g_srv_recover("recover",&handleRecover)
bool writePin(uint32_t pin, uint32_t level)
Definition: gpio.h:51
virtual int spinOnce()
Definition: node_handle.h:167
bool isInitialized() const
Definition: gpio.h:31


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