23 #include <sensor_msgs/JointState.h> 24 #include <control_msgs/FollowJointTrajectoryAction.h> 32 #include <boost/thread/mutex.hpp> 33 #include <boost/shared_ptr.hpp> 34 #include <boost/scoped_ptr.hpp> 44 sensor_msgs::JointState
g_js;
53 boost::scoped_ptr<FollowJointTrajectoryActionServer>
g_as;
54 control_msgs::FollowJointTrajectoryGoalConstPtr
g_goal;
72 control_msgs::FollowJointTrajectoryResult result;
74 bool goal_reached =
false;
77 for(
size_t i = 0; i <
g_status->joints.position_cdeg.size(); ++i){
80 result.error_code = result.GOAL_TOLERANCE_VIOLATED;
86 g_deadline_timer.
stop();
89 g_deadline_timer.
stop();
90 g_as->setSucceeded(result);
91 }
else if (deadline_exceeded) {
92 g_deadline_timer.
stop();
93 result.error_code = result.GOAL_TOLERANCE_VIOLATED;
94 g_as->setAborted(result,
"goal not reached in time");
103 boost::mutex::scoped_lock lock(
g_mutex);
108 res.
message =
"hand is not yet connected";
112 srv.request.port = nh_priv.
param<std::string>(
"sdhx/port",
"/dev/ttyACM0");
113 srv.request.min_pwm0 = nh_priv.
param(
"sdhx/min_pwm0", 0);
114 srv.request.min_pwm1 = nh_priv.
param(
"sdhx/min_pwm1", 0);
115 srv.request.max_pwm0 = nh_priv.
param(
"sdhx/max_pwm0", 0);
116 srv.request.max_pwm1 = nh_priv.
param(
"sdhx/max_pwm1", 0);
119 if(!g_init_finger_client.
call(srv))
return false;
120 res.
success = srv.response.success;
123 res.
message =
"init_finger service does not exist";
130 res.
message =
"finger already initialized, restarting the controller";
134 res.
message =
"already initialized";
141 boost::mutex::scoped_lock lock(
g_mutex);
142 double dt =
g_js.header.stamp.toSec() - msg->stamp.toSec();
144 bool calc_vel = !first && dt != 0 ;
146 g_topic_status->tick(msg->stamp);
151 if(msg->status & msg->MASK_FINGER_READY){
152 for(
size_t i=0; i < msg->joints.position_cdeg.size(); ++i){
155 g_js.velocity[i] = (new_pos -
g_js.position[i]) / dt;
164 g_js.position[i] = new_pos;
166 g_js.header.stamp = msg->stamp;
175 boost::mutex::scoped_lock lock(
g_mutex);
178 stat.
summary(stat.ERROR,
"not connected");
183 stat.
summary(stat.WARN,
"not initialized");
185 stat.
summary(stat.ERROR,
"Bridge has error");
187 stat.
summary(stat.OK,
"Connected and running");
200 if(g_halt_client.
exists()){
202 if(!g_halt_client.
call(srv) || !srv.response.success){
203 ROS_ERROR(
"Halt service did not succeed");
206 ROS_ERROR(
"Halt service is not available");
211 boost::mutex::scoped_lock lock(
g_mutex);
212 if(
g_as->isActive()){
224 control_msgs::FollowJointTrajectoryGoalConstPtr goal =
g_as->acceptNewGoal();
226 g_deadline_timer.
stop();
229 control_msgs::FollowJointTrajectoryResult result;
230 result.error_code = result.INVALID_GOAL;
231 if(goal->trajectory.points.size()!=1 && (goal->trajectory.points.size()!=2 || !goal->trajectory.points[0].time_from_start.isZero() ) ){
232 g_as->setAborted(result,
"goal is not valid");
239 for(
size_t i=0; i <
g_js.name.size(); ++i){
240 for(
size_t j=0; j < goal->trajectory.joint_names.size(); ++j){
241 if(
g_js.name[i] == goal->trajectory.joint_names[j]){
244 if(goal->trajectory.points.back().effort.size() > 0){
245 if(goal->trajectory.points.back().effort.size() == new_command.
current_100uA.size()){
246 new_command.
current_100uA[i] = goal->trajectory.points.back().effort[j] * 1000.0;
248 g_as->setAborted(result,
"Number of effort values mismatch");
259 if(found !=
g_js.name.size()){
260 g_as->setAborted(result,
"Joint names mismatch");
265 for(
size_t i = 0; i < goal->goal_tolerance.size(); ++i){
267 for(
size_t j=0; j <
g_js.name.size(); ++j){
268 if(goal->goal_tolerance[i].name ==
g_js.name[j]){
270 if(goal->goal_tolerance[i].position > 0.0){
271 goal_tolerance[j] = goal->goal_tolerance[i].position;
277 g_as->setAborted(result,
"Goal tolerance invalid");
283 ros::Time trajectory_deadline = (goal->trajectory.header.stamp.isZero() ? now : goal->trajectory.header.stamp)
284 + goal->trajectory.points.back().time_from_start +
ros::Duration(goal->goal_time_tolerance);
285 if(trajectory_deadline <= now){
286 result.error_code = result.OLD_HEADER_TIMESTAMP;
287 g_as->setAborted(result,
"goal is not valid");
291 boost::mutex::scoped_lock lock(
g_mutex);
294 g_as->setAborted(result,
"SDHx is not ready for commands");
298 g_command = new_command;
302 g_command_timer.
stop();
303 g_command_pub.
publish(g_command);
305 g_deadline_timer.
start();
306 g_command_timer.
start();
310 boost::mutex::scoped_lock lock(
g_mutex);
312 g_deadline_timer.
stop();
316 g_as->setPreempted();
320 boost::mutex::scoped_lock lock(
g_mutex);
324 g_command_timer.
stop();
327 ROS_WARN(
"finger is not ready, stopped resend timer");
331 int main(
int argc,
char* argv[])
333 ros::init(argc, argv,
"cob_hand_bridge_node");
341 ROS_ERROR(
"Please provide joint names for SDHx");
357 double stopped_current= nh_priv.
param(
"sdhx/stopped_current", 0.1);
358 if(stopped_current <= 0.0){
364 std::vector<double> default_currents;
365 if(nh_priv.
getParam(
"sdhx/default_currents", default_currents)){
366 if(default_currents.size() != g_default_command.
current_100uA.size()){
367 ROS_ERROR_STREAM(
"Number of current values does not match number of joints");
370 for(
size_t i=0; i< g_default_command.
current_100uA.size(); ++i){
371 g_default_command.
current_100uA[i] = default_currents[i] * 1000.0;
389 nh_priv.
param(
"status/min_duration", -1.0),
390 nh_priv.
param(
"status/max_duration", 0.1)
397 double resend_period = nh_priv.
param(
"sdhx/resend_period", 0.1);
402 g_js_pub = nh.
advertise<sensor_msgs::JointState>(
"joint_states", 1);
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
control_msgs::FollowJointTrajectoryGoalConstPtr g_goal
boost::scoped_ptr< FollowJointTrajectoryActionServer > g_as
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val)
void publish(const boost::shared_ptr< M > &message) const
ros::ServiceClient g_init_finger_client
ros::Timer g_command_timer
void summary(unsigned char lvl, const std::string s)
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
actionlib::SimpleActionServer< control_msgs::FollowJointTrajectoryAction > FollowJointTrajectoryActionServer
ros::ServiceServer g_init_srv
void setHardwareID(const std::string &hwid)
sensor_msgs::JointState g_js
void setPeriod(const Duration &period, bool reset=true)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool call(MReq &req, MRes &res)
boost::shared_ptr< diagnostic_updater::TimeStampStatus > g_topic_status
int main(int argc, char *argv[])
void add(const std::string &name, TaskFunction f)
cob_hand_bridge::JointValues g_default_command
NodeHandle_< EmbeddedLinuxHardware > NodeHandle
virtual void run(diagnostic_updater::DiagnosticStatusWrapper &stat)
double g_stopped_velocity
ros::Publisher g_command_pub
ros::ServiceClient g_halt_client
std::vector< double > g_goal_tolerance
bool waitForExistence(ros::Duration timeout=ros::Duration(-1))
static double from_degrees(double degrees)
int16_t velocity_cdeg_s[2]
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
static double to_degrees(double radians)
ros::Timer g_deadline_timer
cob_hand_bridge::JointValues g_command
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool initCallback(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
bool isFingerReady_nolock()
void handleDeadline(const ros::TimerEvent &)
void statusCallback(const cob_hand_bridge::Status::ConstPtr &msg)
void mergeSummary(unsigned char lvl, const std::string s)
void reportDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &stat)
bool getParam(const std::string &key, std::string &s) const
void add(const std::string &key, const T &val)
bool advertiseService(ServiceServer< MReq, MRes > &srv)
#define ROS_ERROR_STREAM(args)
bool checkAction_nolock(bool deadline_exceeded)
cob_hand_bridge::Status::ConstPtr g_status
void resendCommand(const ros::TimerEvent &e)