14#include <geometry_msgs/msg/pose.hpp>
15#include <std_msgs/msg/header.hpp>
17#include <perception_msgs/msg/object_state.hpp>
18#include <perception_msgs_utils/object_access.hpp>
20#include <rclcpp/time.hpp>
29 Eigen::Vector2d
center = Eigen::Vector2d::Zero();
30 Eigen::Vector2d
axis_x = Eigen::Vector2d::UnitX();
31 Eigen::Vector2d
axis_y = Eigen::Vector2d::UnitY();
66 double capped_angle_rad = angle_rad;
67 while (capped_angle_rad > M_PI) capped_angle_rad -= 2 * M_PI;
68 while (capped_angle_rad < -M_PI) capped_angle_rad += 2 * M_PI;
69 return capped_angle_rad;
79inline Eigen::Vector2d
rotate(
const Eigen::Vector2d& vec,
double yaw) {
80 const double c = std::cos(yaw);
81 const double s = std::sin(yaw);
82 return Eigen::Vector2d(c * vec.x() - s * vec.y(), s * vec.x() + c * vec.y());
94 const std_msgs::msg::Header& fallback_header,
95 const rclcpp::Time& planning_stamp) {
96 const bool has_state_stamp = state.header.stamp.sec != 0 || state.header.stamp.nanosec != 0;
97 const auto& source_header = has_state_stamp ? state.header : fallback_header;
98 return (rclcpp::Time(source_header.stamp) - planning_stamp).seconds();
129 double longitudinal_safety_distance,
130 double lateral_safety_distance) {
132 const double longitudinal_margin = std::max(longitudinal_safety_distance, -2.0 * box.
half_length);
133 const double lateral_margin = std::max(lateral_safety_distance, -box.
half_width);
134 expanded_box.
center += 0.5 * longitudinal_margin * box.
axis_x;
135 expanded_box.
half_length += 0.5 * longitudinal_margin;
160 geometry_msgs::msg::Pose pose;
161 pose.position.x = box.
center.x();
162 pose.position.y = box.
center.y();
163 pose.position.z = 0.0;
164 const double yaw = std::atan2(box.
axis_x.y(), box.
axis_x.x());
165 pose.orientation.z = std::sin(yaw / 2.0);
166 pose.orientation.w = std::cos(yaw / 2.0);
179 const double duration = rhs.
t - lhs.
t;
180 const double alpha = std::abs(duration) > 1e-6 ? std::clamp((t - lhs.
t) / duration, 0.0, 1.0) : 0.0;
200 const Eigen::Vector2d center_delta = second_box.
center - first_box.
center;
201 const std::array<Eigen::Vector2d, 4> axes = {first_box.
axis_x, first_box.
axis_y, second_box.
axis_x, second_box.
axis_y};
202 for (
const auto& axis : axes) {
203 const double first_extent = first_box.
half_length * std::abs(axis.dot(first_box.
axis_x)) +
205 const double second_extent = second_box.
half_length * std::abs(axis.dot(second_box.
axis_x)) +
207 if (std::abs(axis.dot(center_delta)) > first_extent + second_extent + 1e-6) {
225 const std_msgs::msg::Header& fallback_header,
226 const rclcpp::Time& stamp,
229 const auto center_msg = perception_msgs::object_access::getCenterPosition(state);
231 sample.
yaw = perception_msgs::object_access::getYaw(state);
233 sample.
width = width;
Namespace for simple_planner package.
OrientedBox2D buildOrientedBox(const Eigen::Vector2d ¢er, double yaw, double length, double width)
Builds an oriented 2D bounding box from center pose and dimensions.
TimedBox2D interpolateTimedBox(const TimedBox2D &lhs, const TimedBox2D &rhs, double t)
Interpolates a timed box sample at the requested relative time.
Eigen::Vector2d rotate(const Eigen::Vector2d &vec, double yaw)
Rotates a 2D vector by the given yaw angle.
double wrap_angle_rad(double angle_rad)
Wraps an angle to the range [-pi, pi].
bool overlaps(const OrientedBox2D &first_box, const OrientedBox2D &second_box)
Checks whether two oriented boxes overlap.
TimedBox2D buildObjectSample(const perception_msgs::msg::ObjectState &state, const std_msgs::msg::Header &fallback_header, const rclcpp::Time &stamp, double length, double width)
Builds a timed bounding-box sample for a single object state.
OrientedBox2D expandBoxWithSafetyMargins(const OrientedBox2D &box, double longitudinal_safety_distance, double lateral_safety_distance)
Expands a box by the given safety margins.
double getStateRelativeTime(const perception_msgs::msg::ObjectState &state, const std_msgs::msg::Header &fallback_header, const rclcpp::Time &planning_stamp)
Computes an object state's time relative to the planning stamp.
geometry_msgs::msg::Pose toPose(const OrientedBox2D &box)
Converts an oriented box center and heading to a ROS pose.
std::array< Eigen::Vector2d, 4 > getBoxCorners(const OrientedBox2D &box)
Returns the corners of an oriented box.
std::vector< TimedBox2D > samples