35 #include <boost/array.hpp> 36 #include <boost/bind.hpp> 37 #include <boost/date_time/posix_time/posix_time_types.hpp> 50 joint_effort_(n_dof_, 0.0), joint_position_command_(n_dof_, 0.0), joint_names_(n_dof_), deadline_(ios_),
51 eki_server_socket_(ios_,
boost::asio::ip::udp::endpoint(
boost::asio::ip::udp::v4(), 0))
63 if (
deadline_.expires_at() <= boost::asio::deadline_timer::traits_type::now())
66 deadline_.expires_at(boost::posix_time::pos_infin);
75 boost::system::error_code* out_ec,
size_t* out_length)
83 std::vector<double> &joint_velocity,
84 std::vector<double> &joint_effort,
87 static boost::array<char, 2048> in_buffer;
92 boost::system::error_code ec = boost::asio::error::would_block;
98 while (ec == boost::asio::error::would_block);
107 TiXmlDocument xml_in;
108 in_buffer[len] =
'\0';
109 xml_in.Parse(in_buffer.data());
110 TiXmlElement* robot_state = xml_in.FirstChildElement(
"RobotState");
113 TiXmlElement* pos = robot_state->FirstChildElement(
"Pos");
114 TiXmlElement* vel = robot_state->FirstChildElement(
"Vel");
115 TiXmlElement* eff = robot_state->FirstChildElement(
"Eff");
116 TiXmlElement* robot_command = robot_state->FirstChildElement(
"RobotCommand");
117 if (!pos || !vel || !eff || !robot_command)
124 char axis_name[] =
"A1";
125 for (
int i = 0; i <
n_dof_; ++i)
127 pos->Attribute(axis_name, &joint_pos);
129 vel->Attribute(axis_name, &joint_vel);
130 joint_velocity[i] = joint_vel;
131 eff->Attribute(axis_name, &joint_eff);
132 joint_effort[i] = joint_eff;
137 robot_command->Attribute(
"Size", &cmd_buff_len);
145 TiXmlDocument xml_out;
146 TiXmlElement* robot_command =
new TiXmlElement(
"RobotCommand");
147 TiXmlElement* pos =
new TiXmlElement(
"Pos");
148 TiXmlText* empty_text =
new TiXmlText(
"");
149 robot_command->LinkEndChild(pos);
150 pos->LinkEndChild(empty_text);
151 char axis_name[] =
"A1";
152 for (
int i = 0; i <
n_dof_; ++i)
154 pos->SetAttribute(axis_name, std::to_string(
angles::to_degrees(joint_position_command[i])).c_str());
157 xml_out.LinkEndChild(robot_command);
159 TiXmlPrinter xml_printer;
160 xml_printer.SetStreamPrinting();
161 xml_out.Accept(&xml_printer);
163 size_t len =
eki_server_socket_.send_to(boost::asio::buffer(xml_printer.CStr(), xml_printer.Size()),
175 ROS_ERROR(
"Cannot find required parameter 'controller_joint_names' on the parameter server.");
176 throw std::runtime_error(
"Cannot find required parameter 'controller_joint_names' on the parameter server.");
180 const std::string param_addr =
"eki/robot_address";
181 const std::string param_port =
"eki/robot_port";
182 const std::string param_socket_timeout =
"eki/socket_timeout";
183 const std::string param_max_cmd_buf_len =
"eki/max_cmd_buf_len";
193 std::string msg =
"Failed to get EKI address/port from parameter server (looking for '" + param_addr +
194 "', '" + param_port +
"')";
196 throw std::runtime_error(msg);
201 ROS_INFO_STREAM_NAMED(
"kuka_eki_hw_interface",
"Configuring Kuka EKI hardware interface socket timeout to " 206 ROS_INFO_STREAM_NAMED(
"kuka_eki_hw_interface",
"Failed to get EKI socket timeout from parameter server (looking " 207 "for '" + param_socket_timeout +
"'), defaulting to " +
213 ROS_INFO_STREAM_NAMED(
"kuka_eki_hw_interface",
"Configuring Kuka EKI hardware interface maximum command buffer " 218 ROS_INFO_STREAM_NAMED(
"kuka_eki_hw_interface",
"Failed to get EKI hardware interface maximum command buffer length " 219 "from parameter server (looking for '" + param_max_cmd_buf_len +
"'), defaulting to " +
224 for (std::size_t i = 0; i <
n_dof_; ++i)
247 ROS_INFO_NAMED(
"kuka_eki_hw_interface",
"Starting Kuka EKI hardware interface...");
250 ROS_INFO_NAMED(
"kuka_eki_hw_interface",
"... connecting to robot's EKI server...");
251 boost::asio::ip::udp::resolver resolver(
ios_);
253 boost::array<char, 1> ini_buf = { 0 };
257 deadline_.expires_at(boost::posix_time::pos_infin);
263 std::string msg =
"Failed to read from robot EKI server within alloted time of " 265 "on the robot controller and all configurations are correct.";
267 throw std::runtime_error(msg);
271 ROS_INFO_NAMED(
"kuka_eki_hw_interface",
"... done. EKI hardware interface started!");
279 std::string msg =
"Failed to read from robot EKI server within alloted time of " 281 "on the robot controller and all configurations are correct.";
283 throw std::runtime_error(msg);
void registerInterface(T *iface)
std::vector< std::string > joint_names_
#define ROS_INFO_NAMED(name,...)
int eki_max_cmd_buff_len_
int eki_read_state_timeout_
bool eki_read_state(std::vector< double > &joint_position, std::vector< double > &joint_velocity, std::vector< double > &joint_effort, int &cmd_buff_len)
KukaEkiHardwareInterface()
#define ROS_INFO_STREAM_NAMED(name, args)
boost::asio::deadline_timer deadline_
void read(const ros::Time &time, const ros::Duration &period)
boost::asio::io_service ios_
boost::asio::ip::udp::socket eki_server_socket_
boost::asio::ip::udp::endpoint eki_server_endpoint_
static double from_degrees(double degrees)
std::vector< double > joint_position_command_
~KukaEkiHardwareInterface()
static double to_degrees(double radians)
static void eki_handle_receive(const boost::system::error_code &ec, size_t length, boost::system::error_code *out_ec, size_t *out_length)
void registerHandle(const JointStateHandle &handle)
hardware_interface::JointStateInterface joint_state_interface_
bool eki_write_command(const std::vector< double > &joint_position)
JointStateHandle getHandle(const std::string &name)
void write(const ros::Time &time, const ros::Duration &period)
std::vector< double > joint_effort_
bool getParam(const std::string &key, std::string &s) const
std::string eki_server_address_
#define ROS_ERROR_STREAM(args)
void eki_check_read_state_deadline()
std::vector< double > joint_position_
const unsigned int n_dof_
hardware_interface::PositionJointInterface position_joint_interface_
std::string eki_server_port_
std::vector< double > joint_velocity_