32 #include <std_msgs/Float64MultiArray.h> 33 #include <trajectory_msgs/JointTrajectory.h> 34 #include <sensor_msgs/JointState.h> 35 #include <control_msgs/FollowJointTrajectoryAction.h> 36 #include <control_msgs/JointTrajectoryControllerState.h> 37 #include <schunk_sdh/TemperatureArray.h> 40 #include <std_srvs/Trigger.h> 41 #include <cob_srvs/SetString.h> 44 #include <diagnostic_msgs/DiagnosticArray.h> 47 #include <schunk_sdh/sdh.h> 89 std::vector<SDH::cSDH::eAxisState>
state_;
102 trajectory_msgs::JointTrajectory
traj_;
105 std::vector<int>
axes_;
145 isInitialized_ =
false;
149 topicPub_JointState_ = nh_.
advertise<sensor_msgs::JointState>(
"joint_states", 1);
150 topicPub_ControllerState_ = nh_.
advertise<control_msgs::JointTrajectoryControllerState>(
151 "joint_trajectory_controller/state", 1);
152 topicPub_Diagnostics_ = nh_.
advertise<diagnostic_msgs::DiagnosticArray>(
"/diagnostics", 1);
153 topicPub_Temperature_ = nh_.
advertise<schunk_sdh::TemperatureArray>(
"temperature", 1);
156 sdh_ =
new SDH::cSDH(
false,
false, 0);
171 subSetVelocitiesRaw_ = nh_.
subscribe(
"joint_group_velocity_controller/command", 1,
175 nh_.
param(
"sdhdevicetype", sdhdevicetype_, std::string(
"PCAN"));
176 nh_.
param(
"sdhdevicestring", sdhdevicestring_, std::string(
"/dev/pcan0"));
177 nh_.
param(
"sdhdevicenum", sdhdevicenum_, 0);
179 nh_.
param(
"baudrate", baudrate_, 1000000);
180 nh_.
param(
"timeout", timeout_, static_cast<double>(0.04));
181 nh_.
param(
"id_read", id_read_, 43);
182 nh_.
param(
"id_write", id_write_, 42);
185 ROS_INFO(
"getting joint_names from parameter server");
189 nh_.
getParam(
"joint_names", joint_names_param);
193 ROS_ERROR(
"Parameter 'joint_names' not set, shutting down node...");
197 DOF_ = joint_names_param.
size();
198 joint_names_.resize(DOF_);
199 for (
int i = 0; i <
DOF_; i++)
201 joint_names_[i] = (std::string)joint_names_param[i];
203 std::cout <<
"joint_names = " << joint_names_param << std::endl;
207 velocities_.resize(DOF_);
208 for (
int i = 0; i <
DOF_; i++)
214 state_.resize(axes_.size());
216 nh_.
param(
"OperationMode", operationMode_, std::string(
"position"));
231 if (mode ==
"position")
233 sdh_->SetController(SDH::cSDH::eCT_POSE);
235 else if (mode ==
"velocity")
237 sdh_->SetController(SDH::cSDH::eCT_VELOCITY);
244 sdh_->SetAxisEnable(sdh_->All, 1.0);
246 catch (SDH::cSDHLibraryException* e)
248 ROS_ERROR(
"An exception was caught: %s", e->what());
253 operationMode_ = mode;
263 void executeCB(
const control_msgs::FollowJointTrajectoryGoalConstPtr &goal)
266 if (operationMode_ !=
"position")
268 ROS_ERROR(
"%s: Rejected, sdh not in position mode", action_name_.c_str());
274 ROS_ERROR(
"%s: Rejected, sdh not initialized", action_name_.c_str());
279 if (goal->trajectory.points.empty() || goal->trajectory.points[0].positions.size() != size_t(DOF_))
281 ROS_ERROR(
"%s: Rejected, malformed FollowJointTrajectoryGoal", action_name_.c_str());
285 while (hasNewGoal_ ==
true)
288 std::map<std::string, int> dict;
289 for (
int idx = 0; idx < goal->trajectory.joint_names.size(); idx++)
291 dict[goal->trajectory.joint_names[idx]] = idx;
294 targetAngles_.resize(DOF_);
295 targetAngles_[0] = goal->trajectory.points[0].positions[dict[
"sdh_knuckle_joint"]] * 180.0 /
pi_;
296 targetAngles_[1] = goal->trajectory.points[0].positions[dict[
"sdh_finger_22_joint"]] * 180.0 /
pi_;
297 targetAngles_[2] = goal->trajectory.points[0].positions[dict[
"sdh_finger_23_joint"]] * 180.0 /
pi_;
298 targetAngles_[3] = goal->trajectory.points[0].positions[dict[
"sdh_thumb_2_joint"]] * 180.0 /
pi_;
299 targetAngles_[4] = goal->trajectory.points[0].positions[dict[
"sdh_thumb_3_joint"]] * 180.0 /
pi_;
300 targetAngles_[5] = goal->trajectory.points[0].positions[dict[
"sdh_finger_12_joint"]] * 180.0 /
pi_;
301 targetAngles_[6] = goal->trajectory.points[0].positions[dict[
"sdh_finger_13_joint"]] * 180.0 /
pi_;
303 "received position goal: [['sdh_knuckle_joint', 'sdh_thumb_2_joint', 'sdh_thumb_3_joint', 'sdh_finger_12_joint', 'sdh_finger_13_joint', 'sdh_finger_22_joint', 'sdh_finger_23_joint']] = [%f,%f,%f,%f,%f,%f,%f]",
304 goal->trajectory.points[0].positions[dict[
"sdh_knuckle_joint"]],
305 goal->trajectory.points[0].positions[dict[
"sdh_thumb_2_joint"]],
306 goal->trajectory.points[0].positions[dict[
"sdh_thumb_3_joint"]],
307 goal->trajectory.points[0].positions[dict[
"sdh_finger_12_joint"]],
308 goal->trajectory.points[0].positions[dict[
"sdh_finger_13_joint"]],
309 goal->trajectory.points[0].positions[dict[
"sdh_finger_22_joint"]],
310 goal->trajectory.points[0].positions[dict[
"sdh_finger_23_joint"]]);
316 bool finished =
false;
317 while (finished ==
false)
321 ROS_WARN(
"%s: Aborted", action_name_.c_str());
325 for (
unsigned int i = 0; i < state_.size(); i++)
327 ROS_DEBUG(
"state[%d] = %d", i, state_[i]);
341 ROS_INFO(
"%s: Succeeded", action_name_.c_str());
349 ROS_ERROR(
"%s: Rejected, sdh not initialized", action_name_.c_str());
352 if (velocities->data.size() != velocities_.size())
354 ROS_ERROR(
"Velocity array dimension mismatch");
357 if (operationMode_ !=
"velocity")
359 ROS_ERROR(
"%s: Rejected, sdh not in velocity mode", action_name_.c_str());
364 while (hasNewGoal_ ==
true)
367 velocities_[0] = velocities->data[0] * 180.0 /
pi_;
368 velocities_[1] = velocities->data[5] * 180.0 /
pi_;
369 velocities_[2] = velocities->data[6] * 180.0 /
pi_;
370 velocities_[3] = velocities->data[1] * 180.0 /
pi_;
371 velocities_[4] = velocities->data[2] * 180.0 /
pi_;
372 velocities_[5] = velocities->data[3] * 180.0 /
pi_;
373 velocities_[6] = velocities->data[4] * 180.0 /
pi_;
387 if (isInitialized_ ==
false)
393 if (sdhdevicetype_.compare(
"RS232") == 0)
395 sdh_->OpenRS232(sdhdevicenum_, 115200, 1, sdhdevicestring_.c_str());
396 ROS_INFO(
"Initialized RS232 for SDH");
397 isInitialized_ =
true;
399 if (sdhdevicetype_.compare(
"PCAN") == 0)
401 ROS_INFO(
"Starting initializing PEAKCAN");
402 sdh_->OpenCAN_PEAK(baudrate_, timeout_, id_read_, id_write_, sdhdevicestring_.c_str());
403 ROS_INFO(
"Initialized PEAK CAN for SDH");
404 isInitialized_ =
true;
406 if (sdhdevicetype_.compare(
"ESD") == 0)
408 ROS_INFO(
"Starting initializing ESD");
409 if (strcmp(sdhdevicestring_.c_str(),
"/dev/can0") == 0)
411 ROS_INFO(
"Initializing ESD on device %s", sdhdevicestring_.c_str());
412 sdh_->OpenCAN_ESD(0, baudrate_, timeout_, id_read_, id_write_);
414 else if (strcmp(sdhdevicestring_.c_str(),
"/dev/can1") == 0)
416 ROS_INFO(
"Initializin ESD on device %s", sdhdevicestring_.c_str());
417 sdh_->OpenCAN_ESD(1, baudrate_, timeout_, id_read_, id_write_);
421 ROS_ERROR(
"Currently only support for /dev/can0 and /dev/can1");
423 res.message =
"Currently only support for /dev/can0 and /dev/can1";
426 ROS_INFO(
"Initialized ESDCAN for SDH");
427 isInitialized_ =
true;
430 catch (SDH::cSDHLibraryException* e)
432 ROS_ERROR(
"An exception was caught: %s", e->what());
434 res.message = e->what();
441 res.message =
"Could not set operation mode to '" + operationMode_ +
"'";
447 ROS_WARN(
"...sdh already initialized...");
449 res.message =
"sdh already initialized";
472 catch (SDH::cSDHLibraryException* e)
474 ROS_ERROR(
"An exception was caught: %s", e->what());
478 ROS_INFO(
"Stopping sdh succesfull");
492 ROS_WARN(
"Service recover not implemented yet");
494 res.message =
"Service recover not implemented yet";
510 if (operationMode_ ==
"position")
512 sdh_->SetController(SDH::cSDH::eCT_POSE);
514 else if (operationMode_ ==
"velocity")
518 sdh_->SetController(SDH::cSDH::eCT_VELOCITY);
519 sdh_->SetAxisEnable(sdh_->All, 1.0);
521 catch (SDH::cSDHLibraryException* e)
523 ROS_ERROR(
"An exception was caught: %s", e->what());
543 isInitialized_ =
false;
544 sdh_->EmergencyStop();
545 sdh_->SetAxisEnable(sdh_->All, 0.0);
546 sdh_->SetAxisMotorCurrent(sdh_->All, 0.0);
548 catch(
const SDH::cSDHLibraryException* e) {
549 ROS_ERROR(
"An exception was caught: %s", e->what());
551 res.message = e->what();
556 res.message =
"EMERGENCY stop";
569 isInitialized_ =
false;
571 sdh_->SetAxisEnable(sdh_->All, 0.0);
572 sdh_->SetAxisMotorCurrent(sdh_->All, 0.0);
576 catch(
const SDH::cSDHLibraryException* e) {
577 ROS_ERROR(
"An exception was caught: %s", e->what());
579 res.message = e->what();
585 res.message =
"disconnected from SDH";
596 sdh_->SetAxisEnable(sdh_->All, 1.0);
597 sdh_->SetAxisMotorCurrent(sdh_->All, 0.5);
599 catch (
const SDH::cSDHLibraryException* e) {
600 ROS_ERROR(
"An exception was caught: %s", e->what());
602 res.message = e->what();
607 res.message =
"Motor ON";
618 sdh_->SetAxisEnable(sdh_->All, 0.0);
619 sdh_->SetAxisMotorCurrent(sdh_->All, 0.0);
621 catch (
const SDH::cSDHLibraryException* e) {
622 ROS_ERROR(
"An exception was caught: %s", e->what());
624 res.message = e->what();
629 res.message =
"Motor OFF";
641 if (isInitialized_ ==
true)
643 if (hasNewGoal_ ==
true)
650 catch (SDH::cSDHLibraryException* e)
652 ROS_ERROR(
"An exception was caught: %s", e->what());
656 if (operationMode_ ==
"position")
658 ROS_DEBUG(
"moving sdh in position mode");
662 sdh_->SetAxisTargetAngle(axes_, targetAngles_);
663 sdh_->MoveHand(
false);
665 catch (SDH::cSDHLibraryException* e)
667 ROS_ERROR(
"An exception was caught: %s", e->what());
671 else if (operationMode_ ==
"velocity")
673 ROS_DEBUG(
"moving sdh in velocity mode");
676 sdh_->SetAxisTargetVelocity(axes_, velocities_);
679 catch (SDH::cSDHLibraryException* e)
681 ROS_ERROR(
"An exception was caught: %s", e->what());
685 else if (operationMode_ ==
"effort")
689 ROS_WARN(
"Moving in effort mode currently disabled");
693 ROS_ERROR(
"sdh neither in position nor in velocity nor in effort mode. OperationMode = [%s]",
694 operationMode_.c_str());
701 std::vector<double> actualAngles;
704 actualAngles = sdh_->GetAxisActualAngle(axes_);
706 catch (SDH::cSDHLibraryException* e)
708 ROS_ERROR(
"An exception was caught: %s", e->what());
711 std::vector<double> actualVelocities;
714 actualVelocities = sdh_->GetAxisActualVelocity(axes_);
716 catch (SDH::cSDHLibraryException* e)
718 ROS_ERROR(
"An exception was caught: %s", e->what());
722 ROS_DEBUG(
"received %d angles from sdh", static_cast<int>(actualAngles.size()));
727 sensor_msgs::JointState msg;
728 msg.header.stamp = time;
729 msg.name.resize(DOF_);
730 msg.position.resize(DOF_);
731 msg.velocity.resize(DOF_);
732 msg.effort.resize(DOF_);
737 msg.position[0] = actualAngles[0] * pi_ / 180.0;
738 msg.position[1] = actualAngles[3] * pi_ / 180.0;
739 msg.position[2] = actualAngles[4] * pi_ / 180.0;
740 msg.position[3] = actualAngles[5] * pi_ / 180.0;
741 msg.position[4] = actualAngles[6] * pi_ / 180.0;
742 msg.position[5] = actualAngles[1] * pi_ / 180.0;
743 msg.position[6] = actualAngles[2] * pi_ / 180.0;
745 msg.velocity[0] = actualVelocities[0] * pi_ / 180.0;
746 msg.velocity[1] = actualVelocities[3] * pi_ / 180.0;
747 msg.velocity[2] = actualVelocities[4] * pi_ / 180.0;
748 msg.velocity[3] = actualVelocities[5] * pi_ / 180.0;
749 msg.velocity[4] = actualVelocities[6] * pi_ / 180.0;
750 msg.velocity[5] = actualVelocities[1] * pi_ / 180.0;
751 msg.velocity[6] = actualVelocities[2] * pi_ / 180.0;
753 topicPub_JointState_.
publish(msg);
756 sensor_msgs::JointState mimicjointmsg;
757 mimicjointmsg.header.stamp = time;
758 mimicjointmsg.name.resize(1);
759 mimicjointmsg.position.resize(1);
760 mimicjointmsg.velocity.resize(1);
761 mimicjointmsg.name[0] =
"sdh_finger_21_joint";
762 mimicjointmsg.position[0] = msg.position[0];
763 mimicjointmsg.velocity[0] = msg.velocity[0];
764 topicPub_JointState_.
publish(mimicjointmsg);
767 control_msgs::JointTrajectoryControllerState controllermsg;
768 controllermsg.header.stamp = time;
769 controllermsg.joint_names.resize(DOF_);
770 controllermsg.desired.positions.resize(DOF_);
771 controllermsg.desired.velocities.resize(DOF_);
772 controllermsg.actual.positions.resize(DOF_);
773 controllermsg.actual.velocities.resize(DOF_);
774 controllermsg.error.positions.resize(DOF_);
775 controllermsg.error.velocities.resize(DOF_);
780 if (targetAngles_.size() != 0)
782 controllermsg.desired.positions[0] = targetAngles_[0] * pi_ / 180.0;
783 controllermsg.desired.positions[1] = targetAngles_[3] * pi_ / 180.0;
784 controllermsg.desired.positions[2] = targetAngles_[4] * pi_ / 180.0;
785 controllermsg.desired.positions[3] = targetAngles_[5] * pi_ / 180.0;
786 controllermsg.desired.positions[4] = targetAngles_[6] * pi_ / 180.0;
787 controllermsg.desired.positions[5] = targetAngles_[1] * pi_ / 180.0;
788 controllermsg.desired.positions[6] = targetAngles_[2] * pi_ / 180.0;
793 controllermsg.actual.positions = msg.position;
795 controllermsg.actual.velocities = msg.velocity;
797 for (
int i = 0; i <
DOF_; i++)
799 controllermsg.error.positions[i] = controllermsg.desired.positions[i] - controllermsg.actual.positions[i];
800 controllermsg.error.velocities[i] = controllermsg.desired.velocities[i] - controllermsg.actual.velocities[i];
803 topicPub_ControllerState_.
publish(controllermsg);
806 state_ = sdh_->GetAxisActualState(axes_);
809 schunk_sdh::TemperatureArray temp_array;
810 temp_array.header.stamp = time;
811 const std::vector<double> temp_value = sdh_->GetTemperature(sdh_->all_temperature_sensors);
812 if(temp_value.size()==temperature_names_.size()) {
814 temp_array.temperature = temp_value;
817 ROS_ERROR(
"amount of temperatures mismatch with stored names");
819 topicPub_Temperature_.
publish(temp_array);
826 diagnostic_msgs::DiagnosticArray diagnostics;
827 diagnostics.status.resize(1);
831 diagnostics.status[0].level = 2;
832 diagnostics.status[0].name =
"schunk_powercube_chain";
833 diagnostics.status[0].message =
"one or more drives are in Error mode";
839 diagnostics.status[0].level = 0;
841 diagnostics.status[0].message =
"sdh initialized and running";
845 diagnostics.status[0].level = 1;
847 diagnostics.status[0].message =
"sdh not initialized";
851 topicPub_Diagnostics_.
publish(diagnostics);
857 "proximal_finger_1",
"distal_finger_1",
858 "proximal_finger_2",
"distal_finger_2",
859 "proximal_finger_3",
"distal_finger_3",
869 int main(
int argc,
char** argv)
875 if (!sdh_node.
init())
888 ROS_WARN(
"Parameter frequency not available, setting to default value: %f Hz", frequency);
893 while (sdh_node.
nh_.
ok())
std::string sdhdevicetype_
bool srvCallback_Recover(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
Executes the service callback for recover.
int main(int argc, char **argv)
Main loop of ROS node.
ros::ServiceServer srvServer_Init_
ros::Publisher topicPub_Temperature_
trajectory_msgs::JointTrajectory traj_
std::vector< SDH::cSDH::eAxisState > state_
void publish(const boost::shared_ptr< M > &message) const
bool srvCallback_EmergencyStop(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
Executes the service callback for emergency_stop.
ros::ServiceServer srvServer_MotorOff_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool srvCallback_Disconnect(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
Executes the service callback for disconnect.
bool switchOperationMode(const std::string &mode)
Switches operation mode if possible.
ros::ServiceServer srvServer_EmergencyStop_
ROSCPP_DECL const std::string & getName()
std::string sdhdevicestring_
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
ros::Publisher topicPub_JointState_
void setSucceeded(const Result &result=Result(), const std::string &text=std::string(""))
ros::ServiceServer srvServer_SetOperationMode_
ros::ServiceServer srvServer_Disconnect_
SdhNode(std::string name)
Constructor for SdhNode class.
ros::ServiceServer srvServer_MotorOn_
bool srvCallback_MotorPowerOn(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
Enable motor power.
std::string operationMode_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
ros::ServiceServer srvServer_Recover_
const std::string & getNamespace() const
void executeCB(const control_msgs::FollowJointTrajectoryGoalConstPtr &goal)
Executes the callback from the actionlib.
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
~SdhNode()
Destructor for SdhNode class.
actionlib::SimpleActionServer< control_msgs::FollowJointTrajectoryAction > as_
bool srvCallback_MotorPowerOff(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
Disable motor power.
void topicCallback_setVelocitiesRaw(const std_msgs::Float64MultiArrayPtr &velocities)
void setAborted(const Result &result=Result(), const std::string &text=std::string(""))
bool init()
Initializes node to get parameters, subscribe and publish to topics.
std::vector< double > targetAngles_
std::vector< std::string > joint_names_
Implementation of ROS node for sdh.
bool getParam(const std::string &key, std::string &s) const
void updateSdh()
Main routine to update sdh.
ros::Subscriber subSetVelocitiesRaw_
ros::NodeHandle nh_
create a handle for this node, initialize node
bool srvCallback_Init(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
Executes the service callback for init.
std::vector< double > velocities_
ros::Publisher topicPub_ControllerState_
bool hasParam(const std::string &key) const
#define ROS_ERROR_STREAM(args)
static const std::vector< std::string > temperature_names_
ROSCPP_DECL void spinOnce()
bool srvCallback_Stop(std_srvs::Trigger::Request &req, std_srvs::Trigger::Response &res)
Executes the service callback for stop.
bool isNewGoalAvailable()
bool srvCallback_SetOperationMode(cob_srvs::SetString::Request &req, cob_srvs::SetString::Response &res)
Executes the service callback for set_operation_mode.
ros::Publisher topicPub_Diagnostics_
ros::ServiceServer srvServer_Stop_