45 #include <geometry_msgs/Pose.h> 46 #include <geometry_msgs/WrenchStamped.h> 47 #include <sensor_msgs/Imu.h> 79 m_received_ft =
false;
80 m_received_imu =
false;
102 if(n_.
hasParam(
"moveit_group_name"))
104 n_.
getParam(
"moveit_group_name", m_moveit_group_name);
109 ROS_ERROR(
"No moveit_group_name parameter, shutting down node...");
117 n_.
getParam(
"calib_file_name", m_calib_file_name);
122 ROS_WARN(
"No calib_file_name parameter, setting to default 'ft_calib.yaml'");
123 m_calib_file_name = std::string(
"ft_calib_data.yaml");
129 n_.
getParam(
"calib_file_dir", m_calib_file_dir);
134 ROS_WARN(
"No calib_file_dir parameter, setting to default '~/.ros/ft_calib' ");
135 m_calib_file_dir = std::string(
"~/.ros/ft_calib");
142 n_.
getParam(
"meas_file_name", m_meas_file_name);
147 ROS_WARN(
"No meas_file_name parameter, setting to default 'ft_calib_meas.txt'");
148 m_meas_file_name = std::string(
"ft_calib_meas.txt");
154 n_.
getParam(
"meas_file_dir", m_meas_file_dir);
159 ROS_WARN(
"No meas_file_dir parameter, setting to default '~/.ros/ft_calib' ");
160 m_meas_file_dir = std::string(
"~/.ros/ft_calib");
165 n_.
getParam(
"poses_frame_id", m_poses_frame_id);
170 ROS_ERROR(
"No poses_frame_id parameter, shutting down node ...");
177 n_.
param(
"random_poses", m_random_poses,
false);
180 n_.
param(
"number_random_poses", m_number_random_poses, 30);
186 if (!m_meas_file_dir.empty() && m_meas_file_dir[0] ==
'~') {
187 assert(m_meas_file_dir.size() == 1 or m_meas_file_dir[1] ==
'/');
188 char const* home = getenv(
"HOME");
189 if (home or (home = getenv(
"USERPROFILE"))) {
190 m_meas_file_dir.replace(0, 1, home);
193 char const *hdrive = getenv(
"HOMEDRIVE"),
194 *hm_meas_file_dir = getenv(
"HOMEPATH");
196 assert(hm_meas_file_dir);
197 m_meas_file_dir.replace(0, 1, std::string(hdrive) + hm_meas_file_dir);
201 std::ofstream meas_file;
202 meas_file.open((m_meas_file_dir +
"/" + m_meas_file_name).c_str(), std::ios::out);
204 std::stringstream meas_file_header;
206 meas_file_header <<
"\% gravity , f/t measurements all expressed in F/T sensor frame\n";
207 meas_file_header <<
"\% [gx, gy, gz, fx, fy, fz, tx, ty, tz]\n";
209 meas_file << meas_file_header.str();
219 m_group->setPlannerId(
"RRTConnectkConfigDefault");
227 std::stringstream ss;
228 ss << m_pose_counter;
229 Eigen::Matrix<double, 6, 1> pose;
236 if(!getPose(
"pose"+ss.str(), pose))
238 ROS_INFO(
"Finished group %s poses", m_group->getName().c_str());
243 geometry_msgs::Pose
pose_;
244 pose_.position.x = pose(0);
245 pose_.position.y = pose(1);
246 pose_.position.z = pose(2);
249 q.
setRPY((
double)pose(3), (
double)pose(4), (
double)pose(5));
253 geometry_msgs::PoseStamped pose_stamped;
254 pose_stamped.pose = pose_;
255 pose_stamped.header.frame_id = m_poses_frame_id;
258 m_group->setPoseTarget(pose_stamped);
263 if(m_pose_counter<m_number_random_poses)
265 m_group->setRandomTarget();
266 ROS_INFO(
"Executing pose %d",m_pose_counter);
271 ROS_INFO(
"Finished group %s random poses", m_group->getName().c_str());
280 ROS_INFO(
"Finished executing pose %d", m_pose_counter-1);
286 bool getPose(
const std::string &pose_param_name, Eigen::Matrix<double, 6, 1> &pose)
291 n_.
getParam(pose_param_name, PoseXmlRpc);
296 ROS_WARN(
"Pose parameter %s not found", pose_param_name.c_str());
300 if(PoseXmlRpc.
size()!=6)
302 ROS_ERROR(
"Pose parameter %s wrong size (must be 6)", pose_param_name.c_str());
306 for(
unsigned int i=0; i<6; i++)
307 pose(i) = (double)PoseXmlRpc[i];
317 Eigen::Vector3d COM_pos;
318 Eigen::Vector3d f_bias;
319 Eigen::Vector3d t_bias;
321 getCalib(mass, COM_pos, f_bias, t_bias);
325 for(
unsigned int i=0; i<3; i++)
326 bias[i] = (
double)f_bias(i);
328 for(
unsigned int i=0; i<3; i++)
329 bias[i+3] = (
double)t_bias(i);
333 for(
unsigned int i=0; i<3; i++)
334 COM_pose[i] = (
double)COM_pos(i);
336 for(
unsigned int i=0; i<3; i++)
340 n_.
setParam(
"/ft_calib/bias", bias);
341 n_.
setParam(
"/ft_calib/gripper_mass", mass);
342 n_.
setParam(
"/ft_calib/gripper_com_frame_id", m_ft_raw.header.frame_id.c_str());
343 n_.
setParam(
"/ft_calib/gripper_com_pose", COM_pose);
346 std::string file = m_calib_file_dir + std::string(
"/") + m_calib_file_name;
349 std::string
command = std::string(
"mkdir -p ") + m_calib_file_dir;
350 std::system(command.c_str());
354 command = std::string(
"rosparam dump ") + file + std::string(
" /ft_calib");
355 std::system(command.c_str());
359 void saveMeasurements(geometry_msgs::Vector3Stamped gravity, geometry_msgs::WrenchStamped ft_meas)
361 std::ofstream meas_file;
362 meas_file.open((m_meas_file_dir +
"/" + m_meas_file_name).c_str(), std::ios::out | std::ios::app);
364 std::stringstream meas_file_text;
366 meas_file_text << gravity.vector.x <<
" " << gravity.vector.y <<
" " << gravity.vector.z <<
" ";
367 meas_file_text << ft_meas.wrench.force.x <<
" " << ft_meas.wrench.force.y <<
" " << ft_meas.wrench.force.z <<
" ";
368 meas_file_text << ft_meas.wrench.torque.x <<
" " << ft_meas.wrench.torque.y <<
" " << ft_meas.wrench.torque.z <<
"\n";
370 meas_file << meas_file_text.str();
385 m_received_ft =
true;
392 ROS_DEBUG(
"In accelerometer read callback");
395 m_received_imu =
true;
401 m_ft_avg.wrench.force.x = -m_ft_avg.wrench.force.x/(double)m_ft_counter;
402 m_ft_avg.wrench.force.y = -m_ft_avg.wrench.force.y/(double)m_ft_counter;
403 m_ft_avg.wrench.force.z = -m_ft_avg.wrench.force.z/(double)m_ft_counter;
405 m_ft_avg.wrench.torque.x = -m_ft_avg.wrench.torque.x/(double)m_ft_counter;
406 m_ft_avg.wrench.torque.y = -m_ft_avg.wrench.torque.y/(double)m_ft_counter;
407 m_ft_avg.wrench.torque.z = -m_ft_avg.wrench.torque.z/(double)m_ft_counter;
414 ROS_ERROR(
"Haven't received F/T sensor measurements");
420 ROS_ERROR(
"Haven't received accelerometer readings");
425 geometry_msgs::Vector3Stamped gravity;
427 gravity.header.frame_id = m_imu.header.frame_id;
428 gravity.vector.x = -m_imu.linear_acceleration.x;
429 gravity.vector.y = -m_imu.linear_acceleration.y;
430 gravity.vector.z = -m_imu.linear_acceleration.z;
432 geometry_msgs::Vector3Stamped gravity_ft_frame;
436 m_tf_listener->transformVector(m_ft_raw.header.frame_id, gravity, gravity_ft_frame);
441 ROS_ERROR(
"Error transforming accelerometer reading to the F/T sensor frame");
446 m_ft_calib->addMeasurement(gravity_ft_frame, m_ft_avg);
447 saveMeasurements(gravity_ft_frame, m_ft_avg);
450 void getCalib(
double &mass, Eigen::Vector3d &COM_pos, Eigen::Vector3d &f_bias, Eigen::Vector3d &t_bias)
453 Eigen::VectorXd ft_calib = m_ft_calib->getCalib();
458 ROS_ERROR(
"Error in estimated mass (<= 0)");
462 Eigen::Vector3d center_mass_position(ft_calib(1)/mass,
466 COM_pos = center_mass_position;
468 f_bias(0) = -ft_calib(4);
469 f_bias(1) = -ft_calib(5);
470 f_bias(2) = -ft_calib(6);
471 t_bias(0) = -ft_calib(7);
472 t_bias(1) = -ft_calib(8);
473 t_bias(2) = -ft_calib(9);
490 m_ft_avg.wrench.force.x = m_ft_avg.wrench.force.x + m_ft_raw.wrench.force.x;
491 m_ft_avg.wrench.force.y = m_ft_avg.wrench.force.y + m_ft_raw.wrench.force.y;
492 m_ft_avg.wrench.force.z = m_ft_avg.wrench.force.z + m_ft_raw.wrench.force.z;
494 m_ft_avg.wrench.torque.x = m_ft_avg.wrench.torque.x + m_ft_raw.wrench.torque.x;
495 m_ft_avg.wrench.torque.y = m_ft_avg.wrench.torque.y + m_ft_raw.wrench.torque.y;
496 m_ft_avg.wrench.torque.z = m_ft_avg.wrench.torque.z + m_ft_raw.wrench.torque.z;
558 int main(
int argc,
char **argv)
567 ROS_ERROR(
"Error getting ROS parameters");
570 ft_calib_node.
init();
574 ft_calib_node.
n_.
param(
"loop_rate", loop_rate_, 650.0);
579 ft_calib_node.
n_.
param(
"wait_time", wait_time, 4.0);
582 unsigned int n_measurements = 0;
586 while (ft_calib_node.
n_.
ok() && !ft_calib_node.
finished())
602 if(n_measurements==100)
609 Eigen::Vector3d COM_pos;
610 Eigen::Vector3d f_bias;
611 Eigen::Vector3d t_bias;
613 ft_calib_node.
getCalib(mass, COM_pos, f_bias, t_bias);
614 std::cout <<
"-------------------------------------------------------------" << std::endl;
615 std::cout <<
"Current calibration estimate:" << std::endl;
616 std::cout << std::endl << std::endl;
618 std::cout <<
"Mass: " << mass << std::endl << std::endl;
620 std::cout <<
"Center of mass position (relative to FT sensor frame):" << std::endl;
621 std::cout <<
"[" << COM_pos(0) <<
", " << COM_pos(1) <<
", " << COM_pos(2) <<
"]";
622 std::cout << std::endl << std::endl;
625 std::cout <<
"FT bias: " << std::endl;
626 std::cout <<
"[" << f_bias(0) <<
", " << f_bias(1) <<
", " << f_bias(2) <<
", ";
627 std::cout << t_bias(0) <<
", " << t_bias(1) <<
", " << t_bias(2) <<
"]";
628 std::cout << std::endl << std::endl;
631 std::cout <<
"-------------------------------------------------------------" << std::endl << std::endl << std::endl;
ros::Subscriber topicSub_ft_raw_
void getCalib(double &mass, Eigen::Vector3d &COM_pos, Eigen::Vector3d &f_bias, Eigen::Vector3d &t_bias)
void topicCallback_imu(const sensor_msgs::Imu::ConstPtr &msg)
std::string m_meas_file_name
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
std::string m_calib_file_name
unsigned int m_ft_counter
tf::TransformListener * m_tf_listener
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::string m_meas_file_dir
void topicCallback_ft_raw(const geometry_msgs::WrenchStamped::ConstPtr &msg)
ros::Subscriber topicSub_Accelerometer_
int main(int argc, char **argv)
ROSLIB_DECL std::string command(const std::string &cmd)
void setRPY(const tfScalar &roll, const tfScalar &pitch, const tfScalar &yaw)
geometry_msgs::WrenchStamped m_ft_avg
ros::AsyncSpinner * spinner
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
moveit::planning_interface::MoveGroupInterface * m_group
std::string m_moveit_group_name
static void quaternionTFToMsg(const Quaternion &bt, geometry_msgs::Quaternion &msg)
std::string m_calib_file_dir
geometry_msgs::WrenchStamped m_ft_raw
int m_number_random_poses
std::string m_poses_frame_id
void saveMeasurements(geometry_msgs::Vector3Stamped gravity, geometry_msgs::WrenchStamped ft_meas)
const geometry_msgs::Pose * pose_
bool getPose(const std::string &pose_param_name, Eigen::Matrix< double, 6, 1 > &pose)
bool getParam(const std::string &key, std::string &s) const
ROSCPP_DECL void shutdown()
bool hasParam(const std::string &key) const
ROSCPP_DECL void spinOnce()
unsigned int m_pose_counter
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const