high_speed_encoder_ros_i.cpp
Go to the documentation of this file.
1 #include <numeric>
2 #include <string>
3 #include <vector>
4 
5 #include <sensor_msgs/JointState.h>
6 
8 #include "phidgets_msgs/EncoderDecimatedSpeed.h"
9 
10 namespace phidgets {
11 
13  ros::NodeHandle nh_private)
14  : nh_(nh), nh_private_(nh_private)
15 {
16  joint_names_ = {"joint0", "joint1", "joint2", "joint3"};
17  joint_tick2rad_ = {1.0, 1.0, 1.0, 1.0};
18  for (unsigned int i = 0; i < joint_names_.size(); i++)
19  {
20  char str[100];
21  sprintf(str, "joint%u_name", i);
23 
24  sprintf(str, "joint%u_tick2rad", i);
26 
27  ROS_INFO("Channel %u Name: '%s', Tick2rad: '%f'", i,
28  joint_names_[i].c_str(), joint_tick2rad_[i]);
29  }
30 
31  int serial_number = -1;
32  if (serial_number == -1)
33  {
34  nh_private_.getParam("serial_number", serial_number);
35  }
36 
37  nh_private_.getParam("frame_id", frame_id_);
38  ROS_INFO("frame_id = '%s'", frame_id_.c_str());
39  int publish_rate;
40  nh_private_.param("PUBLISH_RATE", publish_rate, 20);
41  nh_private_.param("SPEED_FILTER_SAMPLES_LEN", speed_filter_samples_len_,
42  10);
43  nh_private_.param("SPEED_FILTER_IDLE_ITER_LOOPS_BEFORE_RESET",
45 
46  // First time: create publishers:
47  const std::string topic_path = "joint_states";
48  ROS_INFO("Publishing state to topic: %s", topic_path.c_str());
49 
50  encoder_pub_ = nh_.advertise<sensor_msgs::JointState>(topic_path, 100);
51 
52  // get the program to wait for an encoder device to be attached
53  if (serial_number == -1)
54  {
55  ROS_INFO("Waiting for any High Speed Encoder Phidget to be attached.");
56  } else
57  {
58  ROS_INFO("Waiting for High Speed Encoder Phidget %d to be attached....",
59  serial_number);
60  }
61 
62  // open the device:
63  const int result = openAndWaitForAttachment(serial_number, 10000);
64 
65  if (result != 0)
66  {
67  std::string sError = Phidget::getErrorDescription(result);
68  ROS_FATAL("Problem waiting for attachment: %s", sError.c_str());
69  ros::shutdown();
70  return;
71  }
72 
74 
75  timer_ = nh_.createTimer(ros::Duration(1.0 / publish_rate),
77 }
78 
80 {
81  size_t N;
82  {
83  std::lock_guard<std::mutex> lock(encoder_states_mutex_);
84  N = encoder_states_.size();
85  if (N == 0)
86  {
87  return;
88  }
89  }
90 
91  sensor_msgs::JointState js_msg;
92  static uint32_t seq_cnt = 0;
93  js_msg.header.seq = (seq_cnt++);
94  js_msg.header.stamp = ros::Time::now();
95  js_msg.header.frame_id = frame_id_;
96 
97  js_msg.name.resize(N);
98  for (unsigned int i = 0; i < std::min<size_t>(joint_names_.size(), N); i++)
99  {
100  js_msg.name[i] = joint_names_[i];
101  }
102 
103  js_msg.position.resize(N);
104  js_msg.velocity.resize(N);
105  js_msg.effort.clear();
106 
107  for (unsigned int i = 0; i < N; i++)
108  {
110 
111  js_msg.position[i] = spc.tickPos * joint_tick2rad_[i];
112  js_msg.velocity[i] = spc.instantaneousSpeed * joint_tick2rad_[i];
113 
114  spc.instantaneousSpeed = 0; // Reset speed
115 
117  {
118  if (!spc.speed_buffer_updated)
119  {
122  {
123  phidgets_msgs::EncoderDecimatedSpeed e;
124  e.header.stamp = ros::Time::now();
125  e.header.frame_id = frame_id_;
126  e.avr_speed = .0;
127  encoder_decimspeed_pubs_[i].publish(e);
128  }
129  } else
130  {
132 
133  if (spc.speeds_buffer.size() >=
134  static_cast<size_t>(speed_filter_samples_len_))
135  {
136  const double avrg =
137  std::accumulate(spc.speeds_buffer.begin(),
138  spc.speeds_buffer.end(), 0.0) /
139  spc.speeds_buffer.size();
140  spc.speeds_buffer.clear();
141 
142  phidgets_msgs::EncoderDecimatedSpeed e;
143  e.header.stamp = ros::Time::now();
144  e.header.frame_id = frame_id_;
145  e.avr_speed = avrg * joint_tick2rad_[i];
146  encoder_decimspeed_pubs_[i].publish(e);
147  }
148  }
149  }
150  }
151 
152  encoder_pub_.publish(js_msg);
153 }
154 
156 {
157  const int serial_number = Phidget::getDeviceSerialNumber();
158  const int version = Phidget::getDeviceVersion();
159  const int num_encoders = Encoder::getEncoderCount();
160  const std::string dev_type = Phidget::getDeviceType();
161  const int num_inputs = Encoder::getInputCount();
162 
163  ROS_INFO("Device type : %s", dev_type.c_str());
164  ROS_INFO("Device serial : %d", serial_number);
165  ROS_INFO("Device version : %d", version);
166  ROS_INFO("Number of encoders: %d", num_encoders);
167  ROS_INFO("Number of inputs : %d", num_inputs);
168 }
169 
171 {
172  const int serial_number = Phidget::getDeviceSerialNumber();
173  const std::string name = Phidget::getDeviceName();
174  const int inputcount = Encoder::getEncoderCount();
175  const std::string topic_path = "joint_states";
176 
177  {
178  std::lock_guard<std::mutex> lock(encoder_states_mutex_);
179  encoder_states_.resize(inputcount);
180  encoder_decimspeed_pubs_.resize(inputcount);
181  for (int i = 0; i < inputcount; i++)
182  {
183  std::string s = topic_path;
184  char buf[100];
185  sprintf(buf, "_ch%u_decim_speed", i);
186  s += buf;
187  ROS_INFO("Publishing decimated speed of channel %u to topic: %s", i,
188  s.c_str());
190  nh_.advertise<phidgets_msgs::EncoderDecimatedSpeed>(s, 10);
191  }
192  }
193  ROS_INFO("%s Serial number %d attached with %d encoders!", name.c_str(),
194  serial_number, inputcount);
195 
196  // the 1047 requires enabling of the encoder inputs, so enable them if this
197  // is a 1047
198  for (int i = 0; i < inputcount; i++)
199  {
200  Encoder::setEnabled(i, true);
201  }
202 }
203 
205 {
206  const int serial_number = Phidget::getDeviceSerialNumber();
207  const std::string name = Phidget::getDeviceName();
208  ROS_INFO("%s Serial number %d detached!", name.c_str(), serial_number);
209 
210  std::lock_guard<std::mutex> lock(encoder_states_mutex_);
211  encoder_states_.resize(0);
212  encoder_decimspeed_pubs_.resize(0);
213 }
214 
216 {
217  ROS_ERROR("Error handled. %d - %s", errorCode,
218  Phidget::getErrorDescription(errorCode).c_str());
219 }
220 
222  int positionChange)
223 {
224  const int Position = Encoder::getPosition(index);
225  ROS_DEBUG("Encoder %d Count %d", index, Position);
226 
227  std::lock_guard<std::mutex> lock(encoder_states_mutex_);
228  if (index < (int)encoder_states_.size())
229  {
230  TStatePerChannel &spc = encoder_states_[index];
231  spc.tickPos = Position;
232  spc.instantaneousSpeed = positionChange / (time * 1e-6);
233  spc.speeds_buffer.push_back(spc.instantaneousSpeed);
234  spc.speed_buffer_updated = true;
236  }
237 }
238 
239 } // namespace phidgets
int openAndWaitForAttachment(int serial_number, int timeout)
#define ROS_FATAL(...)
void publish(const boost::shared_ptr< M > &message) const
XmlRpcServer s
HighSpeedEncoderRosI(ros::NodeHandle nh, ros::NodeHandle nh_private)
int getDeviceSerialNumber()
void timerCallback(const ros::TimerEvent &event)
std::vector< ros::Publisher > encoder_decimspeed_pubs_
void setEnabled(int index, bool enabled)
static std::string getErrorDescription(int errorCode)
#define ROS_INFO(...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
void positionChangeHandler(int index, int time, int positionChange) override
std::string getDeviceType()
std::vector< TStatePerChannel > encoder_states_
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
int getPosition(int index)
void errorHandler(int errorCode) override
bool getParam(const std::string &key, std::string &s) const
static Time now()
ROSCPP_DECL void shutdown()
std::vector< std::string > joint_names_
#define ROS_ERROR(...)
std::string getDeviceName()
#define ROS_DEBUG(...)


phidgets_high_speed_encoder
Author(s): Geoff Viola , José-Luis Blanco Claraco
autogenerated on Fri Apr 9 2021 02:56:06