29 "sensor to novatel frame id");
31 "novatel to world frame id");
33 "novatel to world child frame id");
34DEFINE_double(obs_tf2_buff_size, 0.01,
"query Cyber TF buffer size in second");
35DEFINE_double(obs_transform_cache_size, 1.0,
"transform cache size in second");
37 "max local pose extrapolation period in second");
39 "use local pose extrapolation");
49 AINFO <<
"ERROR: add earlier transform to transform cache";
64Eigen::Quaterniond
Slerp(
const Eigen::Quaterniond& source,
const double& t,
65 const Eigen::Quaterniond& other) {
66 const double one = 1.0 - std::numeric_limits<double>::epsilon();
67 double d = source.x() * other.x() + source.y() * other.y() +
68 source.z() * other.z() + source.w() * other.w();
69 double abs_d = std::abs(d);
79 double theta = std::acos(abs_d);
80 double sin_theta = std::sin(theta);
82 scale0 = std::sin((1.0 - t) * theta) / sin_theta;
83 scale1 = std::sin((t * theta)) / sin_theta;
85 if (d < 0) scale1 = -scale1;
87 return Eigen::Quaterniond(scale0 * source.w() + scale1 * other.w(),
88 scale0 * source.x() + scale1 * other.x(),
89 scale0 * source.y() + scale1 * other.y(),
90 scale0 * source.z() + scale1 * other.z());
95 double max_duration) {
100 double delt = timestamp -
transforms_.back().timestamp;
101 if (delt > max_duration) {
102 AINFO <<
"ERROR: query timestamp is " << delt
103 <<
"s later than cached timestamp";
105 }
else if (delt < 0.0) {
106 AINFO <<
"ERROR: query earlier timestamp than transform cache";
125 transforms_[size - 2].translation.x() * (1 - ratio) +
128 transforms_[size - 2].translation.y() * (1 - ratio) +
131 transforms_[size - 2].translation.z() * (1 - ratio) +
134 AINFO <<
"estimate pose at " << timestamp <<
" from poses at "
142 const std::string& sensor2novatel_tf2_child_frame_id) {
143 sensor2novatel_tf2_frame_id_ = FLAGS_obs_sensor2novatel_tf2_frame_id;
144 sensor2novatel_tf2_child_frame_id_ = sensor2novatel_tf2_child_frame_id;
145 novatel2world_tf2_frame_id_ = FLAGS_obs_novatel2world_tf2_frame_id;
146 novatel2world_tf2_child_frame_id_ =
147 FLAGS_obs_novatel2world_tf2_child_frame_id;
153 const std::string& sensor2novatel_tf2_frame_id,
154 const std::string& sensor2novatel_tf2_child_frame_id,
155 const std::string& novatel2world_tf2_frame_id,
156 const std::string& novatel2world_tf2_child_frame_id) {
157 sensor2novatel_tf2_frame_id_ = sensor2novatel_tf2_frame_id;
158 sensor2novatel_tf2_child_frame_id_ = sensor2novatel_tf2_child_frame_id;
159 novatel2world_tf2_frame_id_ = novatel2world_tf2_frame_id;
160 novatel2world_tf2_child_frame_id_ = novatel2world_tf2_child_frame_id;
166 double timestamp, Eigen::Affine3d* sensor2world_trans,
167 Eigen::Affine3d* novatel2world_trans) {
169 AERROR <<
"TransformWrapper not Initialized,"
170 <<
" unable to call GetSensor2worldTrans.";
174 if (sensor2novatel_extrinsics_ ==
nullptr) {
176 if (!
QueryTrans(timestamp, &trans_sensor2novatel,
177 sensor2novatel_tf2_frame_id_,
178 sensor2novatel_tf2_child_frame_id_)) {
181 sensor2novatel_extrinsics_.reset(
new Eigen::Affine3d);
182 *sensor2novatel_extrinsics_ =
184 AINFO <<
"Get sensor2novatel extrinsics successfully.";
188 trans_novatel2world.
timestamp = timestamp;
189 Eigen::Affine3d novatel2world;
191 if (!
QueryTrans(timestamp, &trans_novatel2world, novatel2world_tf2_frame_id_,
192 novatel2world_tf2_child_frame_id_)) {
193 if (FLAGS_obs_enable_local_pose_extrapolation) {
195 timestamp, &trans_novatel2world,
196 FLAGS_obs_max_local_pose_extrapolation_latency)) {
202 }
else if (FLAGS_obs_enable_local_pose_extrapolation) {
208 *sensor2world_trans = novatel2world * (*sensor2novatel_extrinsics_);
209 if (novatel2world_trans !=
nullptr) {
210 *novatel2world_trans = novatel2world;
212 AINFO <<
"Get pose timestamp: " << timestamp <<
", pose: \n"
213 << (*sensor2world_trans).matrix();
218 if (!inited_ || trans ==
nullptr || sensor2novatel_extrinsics_ ==
nullptr) {
219 AERROR <<
"TransformWrapper get extrinsics failed";
222 *trans = *sensor2novatel_extrinsics_;
227 if (sensor2novatel_extrinsics_ ==
nullptr) {
229 if (!
QueryTrans(timestamp, &trans_sensor2novatel,
230 sensor2novatel_tf2_frame_id_,
231 sensor2novatel_tf2_child_frame_id_)) {
234 sensor2novatel_extrinsics_.reset(
new Eigen::Affine3d);
235 *sensor2novatel_extrinsics_ =
237 AINFO <<
"Get sensor2novatel extrinsics successfully.";
239 if (!inited_ || trans ==
nullptr || sensor2novatel_extrinsics_ ==
nullptr) {
240 AERROR <<
"TransformWrapper get extrinsics failed";
243 *trans = *sensor2novatel_extrinsics_;
248 const std::string& frame_id,
249 const std::string& child_frame_id) {
251 if (!
QueryTrans(timestamp, &transform, frame_id, child_frame_id)) {
252 if (!FLAGS_obs_enable_local_pose_extrapolation ||
254 timestamp, &transform,
255 FLAGS_obs_max_local_pose_extrapolation_latency)) {
260 if (FLAGS_obs_enable_local_pose_extrapolation) {
269 const std::string& frame_id,
270 const std::string& child_frame_id) {
272 std::string err_string;
273 if (!tf2_buffer_->
canTransform(frame_id, child_frame_id, query_time,
274 static_cast<float>(FLAGS_obs_tf2_buff_size),
277 double latest_buffer_time;
278 if (!FLAGS_hardware_trigger) {
283 }
catch (tf2::TransformException& ex) {
289 if (!cyber::common::GlobalData::Instance()->IsRealityMode()) {
291 }
else if (!FLAGS_hardware_trigger &&
292 (timestamp - latest_buffer_time < 0.015) &&
293 (timestamp - latest_buffer_time > 0)) {
298 <<
" frame_id: " << frame_id
299 <<
" child_frame_id: " << child_frame_id
300 <<
" Error info: " << err_string;
319 }
catch (tf2::TransformException& ex) {
327 const std::string& from_sensor_id,
const std::string& to_sensor_id,
328 Eigen::Affine3d* trans) {
329 if (trans ==
nullptr) {
330 AERROR <<
"TransformWrapper get extrinsics failed";
335 algorithm::SensorManager::Instance();
336 std::string frame_id = sensor_manager->
GetFrameId(to_sensor_id);
337 std::string child_frame_id = sensor_manager->
GetFrameId(from_sensor_id);
340 bool status =
QueryTrans(0.0, &transform, frame_id, child_frame_id);
Cyber has builtin time type Time.
std::string GetFrameId(const std::string &name) const
DEFINE_double(obs_buffer_match_precision, 0.01, "match_precision for odometry_subscriber")
Eigen::Quaterniond Slerp(const Eigen::Quaterniond &source, const double &t, const Eigen::Quaterniond &other)
DEFINE_string(obs_screen_output_dir, "./", "output dir. for saving visualization screenshots")
DEFINE_bool(obs_enable_hdmap_input, true, "enable hdmap input for roi filter")
Some string util functions.
#define FORMAT_TIMESTAMP(timestamp)