hardware.cpp
Go to the documentation of this file.
1 #include <signal.h>
2 #include <ros/ros.h>
3 #include <ros/console.h>
6 #include <std_msgs/Int32.h>
7 #include <std_msgs/Int16.h>
8 #include <std_msgs/UInt16.h>
9 #include <std_msgs/Int8.h>
10 #include <std_msgs/String.h>
11 #include <std_msgs/Float64.h>
12 #include <sstream>
13 #include <queue>
14 #include <unistd.h>
15 
16 /* ROS rate setting */
17 #define REACTIVE_RATE_FUNCTION //指示姿勢に変化がない場合に制御周期を落としてCPU負荷を下げる機能
18 #ifdef REACTIVE_RATE_FUNCTION
19 #define CONTROL_WAIT_HZ (50)
20 #define CONTROL_ACTIVE_HZ (200)
21 #else
22 #define CONTROL_HZ (200)
23 #endif
24 
25 static std_msgs::String lasterror_out;
26 static std::vector<ros::Publisher> current_pub;
27 static std::vector<ros::Publisher> dxl_position_pub;
28 static std::vector<ros::Publisher> temp_pub;
29 static std::vector<ros::Subscriber> gain_sub;
30 typedef dynamic_reconfigure::Server<sciurus17_msgs::ServoParameterConfig> RECONFIG_TYPE;
31 static std::vector<std::unique_ptr<RECONFIG_TYPE>> reconfig_srv;
33 
34 typedef struct SET_GAIN_QUEUE
35 {
37  {
38  dxl_id = 0;
39  gain = 0;
40  }
42  {
43  dxl_id = src.dxl_id;
44  gain = src.gain;
45  }
46  uint8_t dxl_id;
47  uint16_t gain;
49 static std::queue<ST_SET_GAIN_QUEUE> set_gain_request;
50 
51 static std::queue<ST_JOINT_PARAM> set_joint_param_request;
52 
53 std::vector<std::string> split(const std::string& input, char delimiter)
54 {
55  std::istringstream stream(input);
56 
57  std::string field;
58  std::vector<std::string> result;
59  while (std::getline(stream, field, delimiter)) {
60  result.push_back(field);
61  }
62  return result;
63 }
64 
66 {
67  const ros::M_string& header = event.getConnectionHeader();
68  std::string topic = header.at("topic");
69  const std_msgs::UInt16ConstPtr& msg = event.getMessage();
70  uint16_t set_gain_data = msg->data;
71  if( set_gain_data >= DXL_PGAIN_MAX ){
72  set_gain_data = DXL_PGAIN_MAX;
73  }
74 
75  std::vector<std::string> topic_list = split(topic,'/');
76  std::string joint_name = topic_list[ topic_list.size()-2 ];// Parent topic name
77 
78  for( std::vector<JOINT_CONTROL>::iterator it=driver_addr->joints.begin() ; it!=driver_addr->joints.end() ; ++it ){
79  if( it->get_joint_name() == joint_name ){
80  ST_SET_GAIN_QUEUE set_req_data;
81  set_req_data.dxl_id = it->get_dxl_id();
82  set_req_data.gain = set_gain_data;
83  set_gain_request.push( set_req_data );
84  break;
85  }
86  }
87 }
88 void reconfigureCallback(sciurus17_msgs::ServoParameterConfig &config, uint32_t level, uint8_t id )
89 {
90  ST_JOINT_PARAM set_req_data;
91  set_req_data.dxl_id = id;
92  set_req_data.return_delay_time = config.return_delay_time;
93  set_req_data.drive_mode = config.drive_mode;
94  set_req_data.operation_mode = config.operation_mode;
95  set_req_data.moving_threshold = config.moving_threshold;
96  set_req_data.homing_offset = config.homing_offset;
97  set_req_data.temprature_limit = config.temprature_limit;
98  set_req_data.max_vol_limit = config.max_vol_limit;
99  set_req_data.min_vol_limit = config.min_vol_limit;
100  set_req_data.current_limit = config.current_limit;
101  set_req_data.torque_enable = config.torque_enable?1:0;
102  set_req_data.velocity_i_gain = config.velocity_i_gain;
103  set_req_data.velocity_p_gain = config.velocity_p_gain;
104  set_req_data.position_d_gain = config.position_d_gain;
105  set_req_data.position_i_gain = config.position_i_gain;
106  set_req_data.position_p_gain = config.position_p_gain;
107  if( level != 0 ){
108  for( std::vector<JOINT_CONTROL>::iterator it=driver_addr->joints.begin() ; it!=driver_addr->joints.end() ; ++it ){
109  if( it->get_dxl_id() == id ){
110  ST_JOINT_PARAM load_data = it->get_joint_param();
111  config.return_delay_time = load_data.return_delay_time;
112  config.drive_mode = load_data.drive_mode;
113  config.operation_mode = load_data.operation_mode;
114  config.moving_threshold = load_data.moving_threshold;
115  config.homing_offset = load_data.homing_offset;
116  config.temprature_limit = load_data.temprature_limit;
117  config.max_vol_limit = load_data.max_vol_limit;
118  config.min_vol_limit = load_data.min_vol_limit;
119  config.current_limit = load_data.current_limit;
120  config.torque_enable = true;
121  config.velocity_i_gain = load_data.velocity_i_gain;
122  config.velocity_p_gain = load_data.velocity_p_gain;
123  config.position_d_gain = load_data.position_d_gain;
124  config.position_i_gain = load_data.position_i_gain;
125  config.position_p_gain = DXL_DEFAULT_PGAIN;
126  }
127  }
128  }else{
129  set_joint_param_request.push( set_req_data );
130  }
131 }
132 
134 {
135  std::string current_name;
136  std::string dxl_pos_name;
137  std::string temp_name;
138  std::string gain_name;
139  std::string joint_name;
140 
141  for( std::vector<JOINT_CONTROL>::iterator it=driver->joints.begin() ; it!=driver->joints.end() ; ++it ){
142  joint_name = it->get_joint_name();
143  current_name = ( joint_name + "/current");
144  current_pub.push_back( nh.advertise<std_msgs::Float64>(current_name, 10) );
145  dxl_pos_name = ( joint_name + "/dxl_position");
146  dxl_position_pub.push_back( nh.advertise<std_msgs::Int16>(dxl_pos_name, 10) );
147  temp_name = ( joint_name + "/temp");
148  temp_pub.push_back( nh.advertise<std_msgs::Float64>(temp_name, 10) );
149  gain_name = ( joint_name + "/gain");
150  gain_sub.push_back( nh.subscribe(gain_name, 100, gainCallback) );
151  }
152 }
153 
155 {
156  for( std::vector<JOINT_CONTROL>::iterator it=driver->joints.begin() ; it!=driver->joints.end() ; ++it ){
157  RECONFIG_TYPE* server = new RECONFIG_TYPE( "~/"+it->get_joint_name() );
158  dynamic_reconfigure::Server<sciurus17_msgs::ServoParameterConfig>::CallbackType f;
159  f = boost::bind(reconfigureCallback, _1, _2, it->get_dxl_id());
160  server->setCallback(f);
161  reconfig_srv.push_back( std::unique_ptr<RECONFIG_TYPE>(server) );
162  }
163 }
164 
165 void publish_topic_data( DXLPORT_CONTROL *driver, bool temp_flg )
166 {
167  int joint_index;
168  std::vector<ros::Publisher>::iterator current_it;
169  std::vector<ros::Publisher>::iterator dxl_pos_it;
170  std::vector<ros::Publisher>::iterator temp_it;
171 
172  std_msgs::Float64 current_out;
173  std_msgs::Int16 dxl_pos_out;
174  std_msgs::Float64 temp_out;
175 
176  current_it = current_pub.begin();
177  dxl_pos_it = dxl_position_pub.begin();
178  temp_it = temp_pub.begin();
179 
180  for( std::vector<JOINT_CONTROL>::iterator it=driver->joints.begin() ; it!=driver->joints.end() ; ++it ){
181  current_out.data = it->get_current();
182  current_it->publish( current_out );
183  ++current_it;
184  dxl_pos_out.data = it->get_dxl_pos();
185  dxl_pos_it->publish( dxl_pos_out );
186  ++dxl_pos_it;
187  if( temp_flg ){
188  temp_out.data = it->get_temprature();
189  temp_it->publish( temp_out );
190  ++temp_it;
191  }
192  }
193 }
194 
196 {
197  uint8_t dxl_id = set_param.dxl_id;
198 
199  driver.set_param_delay_time( dxl_id, set_param.return_delay_time );
200  driver.set_param_drive_mode( dxl_id, set_param.drive_mode );
201  driver.set_param_ope_mode( dxl_id, set_param.operation_mode );
202  driver.set_param_home_offset( dxl_id, set_param.homing_offset );
203  driver.set_param_moving_threshold( dxl_id, set_param.moving_threshold );
204  driver.set_param_temp_limit( dxl_id, set_param.temprature_limit );
205  driver.set_param_vol_limit( dxl_id, set_param.max_vol_limit, set_param.min_vol_limit );
206  driver.set_param_current_limit( dxl_id, set_param.current_limit );
207  driver.set_param_vel_gain( dxl_id, set_param.velocity_p_gain, set_param.velocity_i_gain );
208  driver.set_param_pos_gain( dxl_id, set_param.position_p_gain, set_param.position_i_gain, set_param.position_d_gain );
209  driver.set_torque( dxl_id, (set_param.torque_enable?true:false) );
210 }
211 
212 void SigintHandler( int sig )
213 {
214  ros::shutdown();
215 }
216 
217 int main( int argc, char* argv[] )
218 {
220  ros::NodeHandle nh;
221  ros::NodeHandle nhPrivate("~");
222  signal(SIGINT, SigintHandler);
223 
224  CONTROL_SETTING setting( nhPrivate );
225  if( !setting.load() ){
226  return -1;
227  }
228 
229  DXLPORT_CONTROL sciurus17( nhPrivate, setting );
230  if( !sciurus17.get_init_stat() ){
231  std::string errorlog;
232  if( sciurus17.get_error( errorlog ) > 0 ){
233  ROS_INFO("Initialize error (%s)",errorlog.c_str());
234  }
235  return -1;
236  }
237  controller_manager::ControllerManager cm( &sciurus17, nh );
238  driver_addr = &sciurus17;
239 
240  ros::Publisher lasterror_pub = nhPrivate.advertise<std_msgs::String>("lasterror", 10);
241  init_topics( &sciurus17, nhPrivate );
242 
243 #ifdef REACTIVE_RATE_FUNCTION
244  ros::Rate rate_wait( CONTROL_WAIT_HZ );
245  ros::Rate rate_active( CONTROL_ACTIVE_HZ );
246 #else
247  ros::Rate rate( CONTROL_HZ );
248 #endif
250  spinner.start();
251 
252  ros::Time t = sciurus17.getTime();
253  ros::Duration d = sciurus17.getDuration(t);
254  uint32_t prev_tempCount = 0;
255  bool read_temp_flg = false;
256 
257  ROS_INFO( "%s", sciurus17.self_check().c_str() );
258  init_reconfigure( &sciurus17 );
259 
260 // sciurus17.set_watchdog_all( DXL_WATCHDOG_RESET_VALUE );//Currentモードで使用する
261  sciurus17.startup_motion();
262 // sciurus17.set_watchdog_all( MSEC2DXL_WATCHDOG(1000) ); //1秒の間,無通信で停止
263 
264  while( ros::ok() ){
265  d = sciurus17.getDuration(t);
266  t = sciurus17.getTime();
267 
268  if( sciurus17.tempCount != prev_tempCount ){
269  read_temp_flg = true;
270  prev_tempCount = sciurus17.tempCount;
271  }else{
272  read_temp_flg = false;
273  }
274  publish_topic_data( &sciurus17, read_temp_flg );
275 
276  sciurus17.lock_port();
277  if( sciurus17.read( t, d ) ){
278  cm.update( t, d );
279  sciurus17.write( t, d );
280  }
281  sciurus17.unlock_port();
282 
283  while( set_gain_request.size() > 0 ){
284  ST_SET_GAIN_QUEUE gain_data = set_gain_request.front();
285  sciurus17.set_gain( gain_data.dxl_id, gain_data.gain );//手間がかかるだけなのでparamとは連動しない
286  set_gain_request.pop();
287  }
288  // Dynamixelとの通信タイムアウトを防ぐため、
289  // write_joint_param()は1制御ループで1回のみ実行する
290  if( set_joint_param_request.size() > 0 ){
291  write_joint_param( sciurus17, set_joint_param_request.front() );
293  }
294 
295  std::string errorlog;
296  while( sciurus17.get_error( errorlog ) > 0 ){ // error log check
297  lasterror_out.data = errorlog;
298  lasterror_pub.publish( lasterror_out );
299  }
300 
301 #ifdef REACTIVE_RATE_FUNCTION
302  if( sciurus17.is_change_positions() ){
303  rate_active.sleep();
304  }else{
305  rate_wait.sleep();
306  }
307 #else
308  rate.sleep();
309 #endif
310  }
311 
313  sciurus17.set_goal_current_all( 0 );
314  spinner.stop();
315 
316  return 0;
317 }
d
void set_param_home_offset(uint8_t dxl_id, int val)
void set_param_pos_gain_all(int p, int i, int d)
static std::vector< ros::Publisher > dxl_position_pub
Definition: hardware.cpp:27
uint16_t current_limit
Definition: joint_control.h:99
int main(int argc, char *argv[])
Definition: hardware.cpp:217
void init_reconfigure(DXLPORT_CONTROL *driver)
Definition: hardware.cpp:154
std::string::size_type get_error(std::string &errorlog)
f
static std::vector< std::unique_ptr< RECONFIG_TYPE > > reconfig_srv
Definition: hardware.cpp:31
bool set_torque(uint8_t dxl_id, bool torque)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
int32_t homing_offset
Definition: joint_control.h:95
static std::vector< ros::Publisher > temp_pub
Definition: hardware.cpp:28
uint8_t temprature_limit
Definition: joint_control.h:96
void set_param_drive_mode(uint8_t dxl_id, int val)
#define DXL_DEFAULT_PGAIN
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void set_param_vol_limit(uint8_t dxl_id, int max, int min)
uint8_t torque_enable
ROSCPP_DECL const std::string & getName()
static std::vector< ros::Publisher > current_pub
Definition: hardware.cpp:26
void startup_motion(void)
#define CONTROL_ACTIVE_HZ
Definition: hardware.cpp:20
uint16_t moving_threshold
Definition: joint_control.h:94
void write(ros::Time, ros::Duration)
void spinner()
std::map< std::string, std::string > M_string
bool is_change_positions(void)
uint16_t position_p_gain
#define DXL_FREE_DGAIN
void publish(const boost::shared_ptr< M > &message) const
void publish_topic_data(DXLPORT_CONTROL *driver, bool temp_flg)
Definition: hardware.cpp:165
static std_msgs::String lasterror_out
Definition: hardware.cpp:25
void gainCallback(const ros::MessageEvent< std_msgs::UInt16 const > &event)
Definition: hardware.cpp:65
void init_topics(DXLPORT_CONTROL *driver, ros::NodeHandle nh)
Definition: hardware.cpp:133
#define ROS_INFO(...)
void lock_port(void)
struct SET_GAIN_QUEUE ST_SET_GAIN_QUEUE
void set_goal_current_all(uint16_t current)
uint16_t gain
Definition: hardware.cpp:47
#define DXL_FREE_PGAIN
ros::Duration getDuration(ros::Time t) const
ROSCPP_DECL bool ok()
static std::vector< ros::Subscriber > gain_sub
Definition: hardware.cpp:29
bool get_init_stat(void)
ros::Time getTime() const
static std::queue< ST_SET_GAIN_QUEUE > set_gain_request
Definition: hardware.cpp:49
void set_gain(uint8_t dxl_id, uint16_t gain)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void set_param_current_limit(uint8_t dxl_id, int val)
static DXLPORT_CONTROL * driver_addr
Definition: hardware.cpp:32
#define DXL_PGAIN_MAX
uint16_t position_i_gain
uint8_t max_vol_limit
Definition: joint_control.h:97
bool sleep()
uint16_t velocity_p_gain
void set_param_delay_time(uint8_t dxl_id, int val)
uint8_t min_vol_limit
Definition: joint_control.h:98
uint8_t return_delay_time
Definition: joint_control.h:91
void set_param_moving_threshold(uint8_t dxl_id, int val)
uint16_t velocity_i_gain
std::vector< std::string > split(const std::string &input, char delimiter)
Definition: hardware.cpp:53
bool read(ros::Time, ros::Duration)
void write_joint_param(DXLPORT_CONTROL &driver, ST_JOINT_PARAM set_param)
Definition: hardware.cpp:195
uint16_t position_d_gain
void unlock_port(void)
void set_param_vel_gain(uint8_t dxl_id, int p, int i)
uint8_t drive_mode
Definition: joint_control.h:92
ROSCPP_DECL void shutdown()
const std::string header
#define CONTROL_WAIT_HZ
Definition: hardware.cpp:19
uint8_t dxl_id
Definition: hardware.cpp:46
uint8_t operation_mode
Definition: joint_control.h:93
void update(const ros::Time &time, const ros::Duration &period, bool reset_controllers=false)
std::string self_check(void)
#define DXL_FREE_IGAIN
static std::queue< ST_JOINT_PARAM > set_joint_param_request
Definition: hardware.cpp:51
std::vector< JOINT_CONTROL > joints
void set_param_ope_mode(uint8_t dxl_id, int val)
dynamic_reconfigure::Server< sciurus17_msgs::ServoParameterConfig > RECONFIG_TYPE
Definition: hardware.cpp:30
void set_param_temp_limit(uint8_t dxl_id, int val)
void set_param_pos_gain(uint8_t dxl_id, int p, int i, int d)
SET_GAIN_QUEUE(const SET_GAIN_QUEUE &src)
Definition: hardware.cpp:41
void reconfigureCallback(sciurus17_msgs::ServoParameterConfig &config, uint32_t level, uint8_t id)
Definition: hardware.cpp:88
void SigintHandler(int sig)
Definition: hardware.cpp:212


sciurus17_control
Author(s): Hiroyuki Nomura
autogenerated on Sun Oct 2 2022 02:21:42