Skip to content

Commit 85240e1

Browse files
authored
feat(rviz): add new plugin to visualize planning factor (#9999)
* feat(rviz): add new plugin to visualize planning factor Signed-off-by: satoshi-ota <satoshi.ota928@gmail.com> * feat(rviz): show safety factors Signed-off-by: satoshi-ota <satoshi.ota928@gmail.com> * chore: add maintainer Signed-off-by: satoshi-ota <satoshi.ota928@gmail.com> * feat: show detail Signed-off-by: satoshi-ota <satoshi.ota928@gmail.com> --------- Signed-off-by: satoshi-ota <satoshi.ota928@gmail.com>
1 parent b132a88 commit 85240e1

File tree

7 files changed

+360
-0
lines changed

7 files changed

+360
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
cmake_minimum_required(VERSION 3.14)
2+
project(tier4_planning_factor_rviz_plugin)
3+
4+
find_package(autoware_cmake REQUIRED)
5+
autoware_package()
6+
7+
find_package(Qt5 REQUIRED Core Widgets)
8+
set(QT_LIBRARIES Qt5::Widgets)
9+
set(CMAKE_AUTOMOC ON)
10+
set(CMAKE_INCLUDE_CURRENT_DIR ON)
11+
add_definitions(-DQT_NO_KEYWORDS)
12+
13+
ament_auto_add_library(tier4_planning_factor_rviz_plugin SHARED
14+
src/planning_factor_rviz_plugin.cpp
15+
)
16+
17+
target_link_libraries(tier4_planning_factor_rviz_plugin
18+
${QT_LIBRARIES}
19+
)
20+
21+
pluginlib_export_plugin_description_file(rviz_common plugins.xml)
22+
23+
ament_auto_package(
24+
INSTALL_TO_SHARE
25+
icons
26+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# tier4_planning_factor_rviz_plugin
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0"?>
2+
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
3+
<package format="3">
4+
<name>tier4_planning_factor_rviz_plugin</name>
5+
<version>0.40.0</version>
6+
<description>The tier4_planning_factor_rviz_plugin package</description>
7+
<maintainer email="satoshi.ota@tier4.jp">Satoshi Ota</maintainer>
8+
<maintainer email="mamoru.sobue@tier4.jp">Mamoru Sobue</maintainer>
9+
<maintainer email="shumpei.wakabayashi@tier4.jp">Shumpei Wakabayashi</maintainer>
10+
<license>Apache 2.0</license>
11+
12+
<buildtool_depend>ament_cmake</buildtool_depend>
13+
<buildtool_depend>autoware_cmake</buildtool_depend>
14+
15+
<build_depend>qtbase5-dev</build_depend>
16+
17+
<depend>autoware_motion_utils</depend>
18+
<depend>autoware_universe_utils</depend>
19+
<depend>autoware_vehicle_info_utils</depend>
20+
<depend>rviz_common</depend>
21+
<depend>rviz_default_plugins</depend>
22+
<depend>tier4_planning_msgs</depend>
23+
24+
<exec_depend>libqt5-widgets</exec_depend>
25+
<exec_depend>rviz2</exec_depend>
26+
27+
<test_depend>ament_lint_auto</test_depend>
28+
<test_depend>autoware_lint_common</test_depend>
29+
30+
<export>
31+
<build_type>ament_cmake</build_type>
32+
</export>
33+
</package>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<library path="tier4_planning_factor_rviz_plugin">
2+
3+
<class name="tier4_planning_factor_rviz_plugin/PlanningFactorRvizPlugin" type="autoware::rviz_plugins::PlanningFactorRvizPlugin" base_class_type="rviz_common::Display">
4+
<description>tier4_planning_factor_rviz_plugin</description>
5+
<message_type>tier4_planning_msgs/msg/PlanningFactorArray</message_type>
6+
</class>
7+
8+
</library>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
// Copyright 2024 TIER IV, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "planning_factor_rviz_plugin.hpp"
16+
17+
#include <autoware/motion_utils/marker/marker_helper.hpp>
18+
#include <autoware/universe_utils/math/constants.hpp>
19+
#include <autoware/universe_utils/math/trigonometry.hpp>
20+
#include <autoware/universe_utils/ros/marker_helper.hpp>
21+
22+
#include <string>
23+
24+
namespace autoware::rviz_plugins
25+
{
26+
27+
using autoware::motion_utils::createDeadLineVirtualWallMarker;
28+
using autoware::motion_utils::createSlowDownVirtualWallMarker;
29+
using autoware::motion_utils::createStopVirtualWallMarker;
30+
using autoware::universe_utils::createDefaultMarker;
31+
using autoware::universe_utils::createMarkerScale;
32+
33+
namespace
34+
{
35+
36+
std_msgs::msg::ColorRGBA convertFromColorCode(const uint64_t code, const float alpha)
37+
{
38+
const float r = static_cast<int>(code >> 16) / 255.0;
39+
const float g = static_cast<int>((code << 48) >> 56) / 255.0;
40+
const float b = static_cast<int>((code << 56) >> 56) / 255.0;
41+
42+
return autoware::universe_utils::createMarkerColor(r, g, b, alpha);
43+
}
44+
45+
std_msgs::msg::ColorRGBA getGreen(const float alpha)
46+
{
47+
constexpr uint64_t code = 0x00e676;
48+
return convertFromColorCode(code, alpha);
49+
}
50+
51+
std_msgs::msg::ColorRGBA getRed(const float alpha)
52+
{
53+
constexpr uint64_t code = 0xff3d00;
54+
return convertFromColorCode(code, alpha);
55+
}
56+
57+
std_msgs::msg::ColorRGBA getGray(const float alpha)
58+
{
59+
constexpr uint64_t code = 0xbdbdbd;
60+
return convertFromColorCode(code, alpha);
61+
}
62+
63+
visualization_msgs::msg::Marker createArrowMarker(
64+
const size_t id, const geometry_msgs::msg::Point & position,
65+
const std_msgs::msg::ColorRGBA & color, const std::string & name, const double height_offset,
66+
const double arrow_length = 1.0)
67+
{
68+
const double line_width = 0.25 * arrow_length;
69+
const double head_width = 0.5 * arrow_length;
70+
const double head_height = 0.5 * arrow_length;
71+
72+
auto marker = createDefaultMarker(
73+
"map", rclcpp::Clock{RCL_ROS_TIME}.now(), name + "_arrow", id,
74+
visualization_msgs::msg::Marker::ARROW, createMarkerScale(line_width, head_width, head_height),
75+
color);
76+
77+
geometry_msgs::msg::Point src, dst;
78+
src = position;
79+
src.z += height_offset + arrow_length;
80+
dst = position;
81+
dst.z += height_offset;
82+
83+
marker.points.push_back(src);
84+
marker.points.push_back(dst);
85+
86+
return marker;
87+
}
88+
89+
visualization_msgs::msg::Marker createCircleMarker(
90+
const size_t id, const geometry_msgs::msg::Point & position,
91+
const std_msgs::msg::ColorRGBA & color, const std::string & name, const double radius,
92+
const double height_offset, const double line_width = 0.1)
93+
{
94+
auto marker = createDefaultMarker(
95+
"map", rclcpp::Clock{RCL_ROS_TIME}.now(), name, id, visualization_msgs::msg::Marker::LINE_STRIP,
96+
createMarkerScale(line_width, 0.0, 0.0), color);
97+
98+
constexpr size_t num_points = 20;
99+
for (size_t i = 0; i < num_points; ++i) {
100+
geometry_msgs::msg::Point point;
101+
const double ratio = static_cast<double>(i) / static_cast<double>(num_points);
102+
const double theta = 2 * autoware::universe_utils::pi * ratio;
103+
point.x = position.x + radius * autoware::universe_utils::cos(theta);
104+
point.y = position.y + radius * autoware::universe_utils::sin(theta);
105+
point.z = position.z + height_offset;
106+
marker.points.push_back(point);
107+
}
108+
marker.points.push_back(marker.points.front());
109+
110+
return marker;
111+
}
112+
113+
visualization_msgs::msg::Marker createNameTextMarker(
114+
const size_t id, const geometry_msgs::msg::Point & position, const std::string & name,
115+
const double height_offset, const double text_size = 0.5)
116+
{
117+
auto marker = createDefaultMarker(
118+
"map", rclcpp::Clock{RCL_ROS_TIME}.now(), name + "_name_text", id,
119+
visualization_msgs::msg::Marker::TEXT_VIEW_FACING, createMarkerScale(0.0, 0.0, text_size),
120+
getGray(0.999));
121+
122+
marker.text = name;
123+
124+
marker.pose.position = position;
125+
marker.pose.position.z += height_offset;
126+
127+
return marker;
128+
}
129+
130+
visualization_msgs::msg::MarkerArray createTargetMarker(
131+
const size_t id, const geometry_msgs::msg::Point & position,
132+
const std_msgs::msg::ColorRGBA & color, const std::string & name,
133+
const double height_offset = 2.0, const double arrow_length = 1.0, const double line_width = 0.1)
134+
{
135+
visualization_msgs::msg::MarkerArray marker_array;
136+
marker_array.markers.push_back(
137+
createArrowMarker(id, position, color, name, height_offset, arrow_length));
138+
marker_array.markers.push_back(createCircleMarker(
139+
id, position, color, name + "_circle1", 0.5 * arrow_length, height_offset + 0.75 * arrow_length,
140+
line_width));
141+
marker_array.markers.push_back(createCircleMarker(
142+
id, position, color, name + "_circle2", 0.75 * arrow_length,
143+
height_offset + 0.75 * arrow_length, line_width));
144+
marker_array.markers.push_back(createNameTextMarker(
145+
id, position, name, height_offset + 1.5 * arrow_length, 0.5 * arrow_length));
146+
147+
return marker_array;
148+
}
149+
} // namespace
150+
151+
void PlanningFactorRvizPlugin::processMessage(
152+
const tier4_planning_msgs::msg::PlanningFactorArray::ConstSharedPtr msg)
153+
{
154+
size_t i = 0L;
155+
for (const auto & factor : msg->factors) {
156+
const auto text = factor.module + (factor.detail.empty() ? "" : " (" + factor.detail + ")");
157+
158+
switch (factor.behavior) {
159+
case tier4_planning_msgs::msg::PlanningFactor::STOP:
160+
for (const auto & control_point : factor.control_points) {
161+
const auto virtual_wall = createStopVirtualWallMarker(
162+
control_point.pose, text, msg->header.stamp, i++, baselink2front_.getFloat());
163+
add_marker(std::make_shared<visualization_msgs::msg::MarkerArray>(virtual_wall));
164+
}
165+
break;
166+
167+
case tier4_planning_msgs::msg::PlanningFactor::SLOW_DOWN:
168+
for (const auto & control_point : factor.control_points) {
169+
const auto virtual_wall = createSlowDownVirtualWallMarker(
170+
control_point.pose, text, msg->header.stamp, i++, baselink2front_.getFloat());
171+
add_marker(std::make_shared<visualization_msgs::msg::MarkerArray>(virtual_wall));
172+
}
173+
break;
174+
}
175+
176+
for (const auto & safety_factor : factor.safety_factors.factors) {
177+
const auto color = safety_factor.is_safe ? getGreen(0.999) : getRed(0.999);
178+
for (const auto & point : safety_factor.points) {
179+
const auto safety_factor_marker = createTargetMarker(i++, point, color, factor.module);
180+
add_marker(std::make_shared<visualization_msgs::msg::MarkerArray>(safety_factor_marker));
181+
}
182+
}
183+
}
184+
}
185+
} // namespace autoware::rviz_plugins
186+
187+
// Export the plugin
188+
#include <pluginlib/class_list_macros.hpp> // NOLINT
189+
PLUGINLIB_EXPORT_CLASS(autoware::rviz_plugins::PlanningFactorRvizPlugin, rviz_common::Display)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright 2024 TIER IV, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef PLANNING_FACTOR_RVIZ_PLUGIN_HPP_
16+
#define PLANNING_FACTOR_RVIZ_PLUGIN_HPP_
17+
18+
#include <autoware_vehicle_info_utils/vehicle_info_utils.hpp>
19+
#include <rviz_common/display.hpp>
20+
#include <rviz_common/properties/float_property.hpp>
21+
#include <rviz_default_plugins/displays/marker/marker_common.hpp>
22+
#include <rviz_default_plugins/displays/marker_array/marker_array_display.hpp>
23+
24+
#include <tier4_planning_msgs/msg/planning_factor_array.hpp>
25+
26+
#include <string>
27+
28+
namespace autoware::rviz_plugins
29+
{
30+
31+
using RosTopicDisplay = rviz_common::RosTopicDisplay<tier4_planning_msgs::msg::PlanningFactorArray>;
32+
33+
class PlanningFactorRvizPlugin
34+
: public rviz_common::RosTopicDisplay<tier4_planning_msgs::msg::PlanningFactorArray>
35+
{
36+
public:
37+
PlanningFactorRvizPlugin()
38+
: marker_common_{this},
39+
baselink2front_{"Baselink To Front", 0.0, "Length between base link to front.", this},
40+
topic_name_{"planning_factors"}
41+
{
42+
}
43+
44+
void onInitialize() override
45+
{
46+
RosTopicDisplay::RTDClass::onInitialize();
47+
marker_common_.initialize(this->context_, this->scene_node_);
48+
QString message_type = QString::fromStdString(
49+
rosidl_generator_traits::name<tier4_planning_msgs::msg::PlanningFactorArray>());
50+
this->topic_property_->setMessageType(message_type);
51+
this->topic_property_->setValue(topic_name_.c_str());
52+
this->topic_property_->setDescription("Topic to subscribe to.");
53+
54+
const auto vehicle_info =
55+
autoware::vehicle_info_utils::VehicleInfoUtils(*rviz_ros_node_.lock()->get_raw_node())
56+
.getVehicleInfo();
57+
baselink2front_.setValue(vehicle_info.max_longitudinal_offset_m);
58+
}
59+
60+
void load(const rviz_common::Config & config) override
61+
{
62+
RosTopicDisplay::Display::load(config);
63+
marker_common_.load(config);
64+
}
65+
66+
void update(float wall_dt, float ros_dt) override { marker_common_.update(wall_dt, ros_dt); }
67+
68+
void reset() override
69+
{
70+
RosTopicDisplay::reset();
71+
marker_common_.clearMarkers();
72+
}
73+
74+
void clear_markers() { marker_common_.clearMarkers(); }
75+
76+
void add_marker(visualization_msgs::msg::Marker::ConstSharedPtr marker_ptr)
77+
{
78+
marker_common_.addMessage(marker_ptr);
79+
}
80+
81+
void add_marker(visualization_msgs::msg::MarkerArray::ConstSharedPtr markers_ptr)
82+
{
83+
marker_common_.addMessage(markers_ptr);
84+
}
85+
86+
void delete_marker(rviz_default_plugins::displays::MarkerID marker_id)
87+
{
88+
marker_common_.deleteMarker(marker_id);
89+
}
90+
91+
private:
92+
void processMessage(
93+
const tier4_planning_msgs::msg::PlanningFactorArray::ConstSharedPtr msg) override;
94+
95+
rviz_default_plugins::displays::MarkerCommon marker_common_;
96+
97+
rviz_common::properties::FloatProperty baselink2front_;
98+
99+
std::string topic_name_;
100+
};
101+
} // namespace autoware::rviz_plugins
102+
103+
#endif // PLANNING_FACTOR_RVIZ_PLUGIN_HPP_

0 commit comments

Comments
 (0)