5 #include <ceres/ceres.h> 7 #include <sensor_msgs/NavSatFix.h> 13 : tf_listener(tf_buffer),
18 nh.param<
double>(
"translation_y", translation_[1], 0.0);
20 nh.param<
double>(
"orientation",
rotation_, 0.0);
26 ROS_INFO(
"Initial GPS transformation: \n t: %f %f \n r: %f", translation_[0], translation_[1], rotation_);
31 nav_sat_fix_pub_ = nh.advertise<sensor_msgs::NavSatFix>(
"/gps_calibration/gps/fix", 5);
65 Eigen::Matrix<double, 2, 1> pos_gps(msg.pose.pose.position.x,
66 msg.pose.pose.position.y);
68 geometry_msgs::TransformStamped transformStamped;
79 Eigen::Matrix<double, 2, 1> pos_world(transformStamped.transform.translation.x,
80 transformStamped.transform.translation.y);
81 bool redundant_data =
false;
85 double pose_distance = std::sqrt(delta_pose.transpose() * delta_pose);
87 redundant_data =
true;
111 ceres::Problem problem;
115 problem.AddResidualBlock(
124 ceres::LocalParameterization* angle_local_parameterization =
127 problem.SetParameterization(&
rotation_, angle_local_parameterization);
130 ceres::Solver::Options
options;
131 options.linear_solver_type = ceres::DENSE_QR;
133 ceres::Solver::Summary summary;
134 ceres::Solve(options, &problem, &summary);
135 if(summary.termination_type != ceres::TerminationType::CONVERGENCE)
136 ROS_WARN(
"%s", summary.FullReport().c_str());
142 std::ofstream myfile;
143 myfile.open (
"gps_alignment_solution.csv");
145 Eigen::Matrix<double, 3, 1>(
translation_[0], translation_[1], 0.0),
146 Eigen::Quaternion<double>(std::cos(
rotation_/2.0), 0.0, 0.0,
149 myfile <<
"gps_x"<<
","<<
"gps_y"<<
"," 150 <<
"world_x"<<
","<<
"world_y"<<
","<<
"covariance"<<
"\n";
153 const Eigen::Matrix<double, 3, 1> pos_world_gps = transform * Eigen::Matrix<double, 3, 1>(
world_poses_[i][0], world_poses_[i][1], 0.0);
155 <<pos_world_gps[0]<<
","<<pos_world_gps[1]<<
","<<
covariances_[i]<<
"\n";
165 geometry_msgs::TransformStamped utm_world_transform;
166 utm_world_transform.header.stamp = publish_time;
167 utm_world_transform.header.frame_id =
"utm";
168 utm_world_transform.child_frame_id =
"world";
169 utm_world_transform.transform.translation.x =
translation_[0];
170 utm_world_transform.transform.translation.y =
translation_[1];
171 utm_world_transform.transform.translation.z = 0;
172 utm_world_transform.transform.rotation.w = std::cos(
rotation_/2.0);
173 utm_world_transform.transform.rotation.x = 0.0;
174 utm_world_transform.transform.rotation.y = 0.0;
175 utm_world_transform.transform.rotation.z = std::sin(
rotation_/2.0);
179 geometry_msgs::TransformStamped worldenu_world_transform;
180 worldenu_world_transform.header.stamp = publish_time;
181 worldenu_world_transform.header.frame_id =
"world_enu";
182 worldenu_world_transform.child_frame_id =
"world";
183 worldenu_world_transform.transform.translation.x = 0;
184 worldenu_world_transform.transform.translation.y = 0;
185 worldenu_world_transform.transform.translation.z = 0;
186 worldenu_world_transform.transform.rotation.w = std::cos(
rotation_/2.0);
187 worldenu_world_transform.transform.rotation.x = 0.0;
188 worldenu_world_transform.transform.rotation.y = 0.0;
189 worldenu_world_transform.transform.rotation.z = std::sin(
rotation_/2.0);
192 geometry_msgs::TransformStamped world_navsat_transform;
203 geometry_msgs::TransformStamped utm_navsat_transform;
204 tf2::doTransform(world_navsat_transform, utm_navsat_transform, utm_world_transform);
207 utm_point.
band =
'U';
209 utm_point.
easting = utm_navsat_transform.transform.translation.x;
210 utm_point.
northing = utm_navsat_transform.transform.translation.y;
214 sensor_msgs::NavSatFix nav_sat_fix;
215 nav_sat_fix.header.stamp = publish_time;
216 nav_sat_fix.header.frame_id =
"base_link";
217 nav_sat_fix.latitude = geo_point.latitude;
218 nav_sat_fix.longitude = geo_point.longitude;
219 nav_sat_fix.altitude = 0.0;
ros::Publisher nav_sat_fix_pub_
std::vector< double > covariances_
void publish(const boost::shared_ptr< M > &message) const
tf2_ros::TransformBroadcaster tf_broadcaster
virtual geometry_msgs::TransformStamped lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, const ros::Duration timeout) const
double min_pose_distance_
std::vector< ros::WallTimer > wall_timers_
void doTransform(const T &data_in, T &data_out, const geometry_msgs::TransformStamped &transform)
void navSatCallback(nav_msgs::Odometry msg)
static geographic_msgs::GeoPoint toMsg(double lat, double lon)
static ceres::LocalParameterization * Create()
std::vector< Eigen::Matrix< double, 2, 1 > > world_poses_
GPSCalibration(ros::NodeHandle &nh)
ros::Subscriber optimize_sub_
std::vector< Eigen::Matrix< double, 2, 1 > > gps_poses_
ros::Subscriber nav_sat_sub_
void publishTF(const ros::WallTimerEvent &unused_timer_event)
std::array< double, 2 > translation_
void optimizeCallback(std_msgs::Empty msg)
tf2_ros::Buffer tf_buffer