Skip to content

Commit 8c02272

Browse files
feat(pose_initilizer): set intial pose directly (#6692)
* feat(pose_initilizer): set intial pose directly Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> * style(pre-commit): autofix * fix arg order Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> * minor change Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> * style(pre-commit): autofix * remove blank lines Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> * change types Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> * add wait_for_service Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> * style(pre-commit): autofix * fix default quaternion Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> * rename params Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> * input quaternion validation Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> * fix message Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> * style(pre-commit): autofix * add std::abs Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> * style(pre-commit): autofix --------- Signed-off-by: Yamato Ando <yamato.ando@tier4.jp> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 46e3ad4 commit 8c02272

10 files changed

+143
-28
lines changed

launch/tier4_localization_launch/launch/localization.launch.xml

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<launch>
33
<arg name="pose_source" description="A string consisting of ndt, yabloc, artag and eagleye joined by underscores no matter the order. e.g. ndt_yabloc"/>
44
<arg name="twist_source"/>
5+
<arg name="initial_pose"/>
56
<arg name="system_run_mode"/>
67

78
<!-- parameter paths for ndt -->

launch/tier4_localization_launch/launch/pose_twist_estimator/pose_twist_estimator.launch.xml

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121
<let name="use_eagleye_twist" value="$(eval &quot;'eagleye' == '$(var twist_source)'&quot;)"/>
2222
<let name="use_gyro_odom_twist" value="$(eval &quot;'gyro_odom' == '$(var twist_source)'&quot;)"/>
2323

24+
<!-- set initial pose -->
25+
<let name="user_defined_initial_pose/enable" value="$(eval &quot;len($(var initial_pose)) == 7&quot;)"/>
26+
<let name="user_defined_initial_pose/pose" value="$(var initial_pose)" if="$(var user_defined_initial_pose/enable)"/>
27+
<let name="user_defined_initial_pose/pose" value="[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]" unless="$(var user_defined_initial_pose/enable)"/>
28+
2429
<!-- NDT Scan Matcher Launch (as pose estimator) -->
2530
<group if="$(var use_ndt_pose)">
2631
<push-ros-namespace namespace="pose_estimator"/>
@@ -91,6 +96,8 @@
9196
</group>
9297

9398
<include file="$(find-pkg-share pose_initializer)/launch/pose_initializer.launch.xml">
99+
<arg name="user_defined_initial_pose/enable" value="$(var user_defined_initial_pose/enable)"/>
100+
<arg name="user_defined_initial_pose/pose" value="$(var user_defined_initial_pose/pose)"/>
94101
<arg name="ndt_enabled" value="$(var use_ndt_pose)"/>
95102
<arg name="yabloc_enabled" value="$(var use_yabloc_pose)"/>
96103
<arg name="gnss_enabled" value="$(var gnss_enabled)"/>

localization/pose_initializer/config/pose_initializer.param.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
/**:
22
ros__parameters:
3+
user_defined_initial_pose:
4+
enable: $(var user_defined_initial_pose/enable)
5+
pose: $(var user_defined_initial_pose/pose)
6+
37
gnss_pose_timeout: 3.0 # [sec]
48
stop_check_duration: 3.0 # [sec]
59
ekf_enabled: $(var ekf_enabled)

localization/pose_initializer/schema/pose_initializer.schema.json

+18
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@
66
"pose_initializer": {
77
"type": "object",
88
"properties": {
9+
"user_defined_initial_pose": {
10+
"type": "object",
11+
"properties": {
12+
"enable": {
13+
"type": "string",
14+
"description": "If true, user_defined_initial_pose.pose is set as the initial position. [boolean]",
15+
"default": "false"
16+
},
17+
"pose": {
18+
"type": "string",
19+
"description": "initial pose (x, y, z, quat_x, quat_y, quat_z, quat_w). [array]",
20+
"default": "[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0]"
21+
}
22+
},
23+
"required": ["enable", "pose"],
24+
"additionalProperties": false
25+
},
926
"gnss_pose_timeout": {
1027
"type": "number",
1128
"description": "The duration that the GNSS pose is valid. [sec]",
@@ -55,6 +72,7 @@
5572
}
5673
},
5774
"required": [
75+
"user_defined_initial_pose",
5876
"gnss_pose_timeout",
5977
"stop_check_duration",
6078
"ekf_enabled",

localization/pose_initializer/src/pose_initializer/ekf_localization_trigger_module.cpp

+17-6
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,20 @@
2323
using ServiceException = component_interface_utils::ServiceException;
2424
using Initialize = localization_interface::Initialize;
2525

26-
EkfLocalizationTriggerModule::EkfLocalizationTriggerModule(rclcpp::Node * node)
27-
: logger_(node->get_logger())
26+
EkfLocalizationTriggerModule::EkfLocalizationTriggerModule(rclcpp::Node * node) : node_(node)
2827
{
29-
client_ekf_trigger_ = node->create_client<SetBool>("ekf_trigger_node");
28+
client_ekf_trigger_ = node_->create_client<SetBool>("ekf_trigger_node");
3029
}
3130

32-
void EkfLocalizationTriggerModule::send_request(bool flag) const
31+
void EkfLocalizationTriggerModule::wait_for_service()
32+
{
33+
while (!client_ekf_trigger_->wait_for_service(std::chrono::seconds(1))) {
34+
RCLCPP_INFO(node_->get_logger(), "EKF triggering service is not available, waiting...");
35+
}
36+
RCLCPP_INFO(node_->get_logger(), "EKF triggering service is available!");
37+
}
38+
39+
void EkfLocalizationTriggerModule::send_request(bool flag, bool need_spin) const
3340
{
3441
const auto req = std::make_shared<SetBool::Request>();
3542
std::string command_name;
@@ -46,10 +53,14 @@ void EkfLocalizationTriggerModule::send_request(bool flag) const
4653

4754
auto future_ekf = client_ekf_trigger_->async_send_request(req);
4855

56+
if (need_spin) {
57+
rclcpp::spin_until_future_complete(node_->get_node_base_interface(), future_ekf);
58+
}
59+
4960
if (future_ekf.get()->success) {
50-
RCLCPP_INFO(logger_, "EKF %s succeeded", command_name.c_str());
61+
RCLCPP_INFO(node_->get_logger(), "EKF %s succeeded", command_name.c_str());
5162
} else {
52-
RCLCPP_INFO(logger_, "EKF %s failed", command_name.c_str());
63+
RCLCPP_INFO(node_->get_logger(), "EKF %s failed", command_name.c_str());
5364
throw ServiceException(
5465
Initialize::Service::Response::ERROR_ESTIMATION, "EKF " + command_name + " failed");
5566
}

localization/pose_initializer/src/pose_initializer/ekf_localization_trigger_module.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ class EkfLocalizationTriggerModule
2626

2727
public:
2828
explicit EkfLocalizationTriggerModule(rclcpp::Node * node);
29-
void send_request(bool flag) const;
29+
void wait_for_service();
30+
void send_request(bool flag, bool need_spin = false) const;
3031

3132
private:
32-
rclcpp::Logger logger_;
33+
rclcpp::Node * node_;
3334
rclcpp::Client<SetBool>::SharedPtr client_ekf_trigger_;
3435
};
3536

localization/pose_initializer/src/pose_initializer/ndt_localization_trigger_module.cpp

+17-6
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,20 @@
2323
using ServiceException = component_interface_utils::ServiceException;
2424
using Initialize = localization_interface::Initialize;
2525

26-
NdtLocalizationTriggerModule::NdtLocalizationTriggerModule(rclcpp::Node * node)
27-
: logger_(node->get_logger())
26+
NdtLocalizationTriggerModule::NdtLocalizationTriggerModule(rclcpp::Node * node) : node_(node)
2827
{
29-
client_ndt_trigger_ = node->create_client<SetBool>("ndt_trigger_node");
28+
client_ndt_trigger_ = node_->create_client<SetBool>("ndt_trigger_node");
3029
}
3130

32-
void NdtLocalizationTriggerModule::send_request(bool flag) const
31+
void NdtLocalizationTriggerModule::wait_for_service()
32+
{
33+
while (!client_ndt_trigger_->wait_for_service(std::chrono::seconds(1))) {
34+
RCLCPP_INFO(node_->get_logger(), "NDT triggering service is not available, waiting...");
35+
}
36+
RCLCPP_INFO(node_->get_logger(), "NDT triggering service is available!");
37+
}
38+
39+
void NdtLocalizationTriggerModule::send_request(bool flag, bool need_spin) const
3340
{
3441
const auto req = std::make_shared<SetBool::Request>();
3542
std::string command_name;
@@ -46,10 +53,14 @@ void NdtLocalizationTriggerModule::send_request(bool flag) const
4653

4754
auto future_ndt = client_ndt_trigger_->async_send_request(req);
4855

56+
if (need_spin) {
57+
rclcpp::spin_until_future_complete(node_->get_node_base_interface(), future_ndt);
58+
}
59+
4960
if (future_ndt.get()->success) {
50-
RCLCPP_INFO(logger_, "NDT %s succeeded", command_name.c_str());
61+
RCLCPP_INFO(node_->get_logger(), "NDT %s succeeded", command_name.c_str());
5162
} else {
52-
RCLCPP_INFO(logger_, "NDT %s failed", command_name.c_str());
63+
RCLCPP_INFO(node_->get_logger(), "NDT %s failed", command_name.c_str());
5364
throw ServiceException(
5465
Initialize::Service::Response::ERROR_ESTIMATION, "NDT " + command_name + " failed");
5566
}

localization/pose_initializer/src/pose_initializer/ndt_localization_trigger_module.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ class NdtLocalizationTriggerModule
2626

2727
public:
2828
explicit NdtLocalizationTriggerModule(rclcpp::Node * node);
29-
void send_request(bool flag) const;
29+
void wait_for_service();
30+
void send_request(bool flag, bool need_spin = false) const;
3031

3132
private:
32-
rclcpp::Logger logger_;
33+
rclcpp::Node * node_;
3334
rclcpp::Client<SetBool>::SharedPtr client_ndt_trigger_;
3435
};
3536

localization/pose_initializer/src/pose_initializer/pose_initializer_core.cpp

+70-12
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,31 @@ PoseInitializer::PoseInitializer() : Node("pose_initializer")
5757
logger_configure_ = std::make_unique<tier4_autoware_utils::LoggerLevelConfigure>(this);
5858

5959
change_state(State::Message::UNINITIALIZED);
60+
61+
if (declare_parameter<bool>("user_defined_initial_pose.enable")) {
62+
const auto initial_pose_array =
63+
declare_parameter<std::vector<double>>("user_defined_initial_pose.pose");
64+
if (initial_pose_array.size() != 7) {
65+
throw std::invalid_argument(
66+
"Could not set user defined initial pose. The size of initial_pose is " +
67+
std::to_string(initial_pose_array.size()) + ". It must be 7.");
68+
} else if (
69+
std::abs(initial_pose_array[3]) < 1e-6 && std::abs(initial_pose_array[4]) < 1e-6 &&
70+
std::abs(initial_pose_array[5]) < 1e-6 && std::abs(initial_pose_array[6]) < 1e-6) {
71+
throw std::invalid_argument("Input quaternion is invalid. All elements are close to zero.");
72+
} else {
73+
geometry_msgs::msg::Pose initial_pose;
74+
initial_pose.position.x = initial_pose_array[0];
75+
initial_pose.position.y = initial_pose_array[1];
76+
initial_pose.position.z = initial_pose_array[2];
77+
initial_pose.orientation.x = initial_pose_array[3];
78+
initial_pose.orientation.y = initial_pose_array[4];
79+
initial_pose.orientation.z = initial_pose_array[5];
80+
initial_pose.orientation.w = initial_pose_array[6];
81+
82+
set_user_defined_initial_pose(initial_pose);
83+
}
84+
}
6085
}
6186

6287
PoseInitializer::~PoseInitializer()
@@ -71,6 +96,47 @@ void PoseInitializer::change_state(State::Message::_state_type state)
7196
pub_state_->publish(state_);
7297
}
7398

99+
// To execute in the constructor, you need to call ros spin.
100+
// Conversely, ros spin should not be called elsewhere
101+
void PoseInitializer::change_node_trigger(bool flag, bool need_spin)
102+
{
103+
try {
104+
if (ekf_localization_trigger_) {
105+
ekf_localization_trigger_->wait_for_service();
106+
ekf_localization_trigger_->send_request(flag, need_spin);
107+
}
108+
if (ndt_localization_trigger_) {
109+
ndt_localization_trigger_->wait_for_service();
110+
ndt_localization_trigger_->send_request(flag, need_spin);
111+
}
112+
} catch (const ServiceException & error) {
113+
throw;
114+
}
115+
}
116+
117+
void PoseInitializer::set_user_defined_initial_pose(const geometry_msgs::msg::Pose initial_pose)
118+
{
119+
try {
120+
change_state(State::Message::INITIALIZING);
121+
change_node_trigger(false, true);
122+
123+
PoseWithCovarianceStamped pose;
124+
pose.header.frame_id = "map";
125+
pose.header.stamp = now();
126+
pose.pose.pose = initial_pose;
127+
pose.pose.covariance = output_pose_covariance_;
128+
pub_reset_->publish(pose);
129+
130+
change_node_trigger(true, true);
131+
change_state(State::Message::INITIALIZED);
132+
133+
RCLCPP_INFO(get_logger(), "Set user defined initial pose");
134+
} catch (const ServiceException & error) {
135+
change_state(State::Message::UNINITIALIZED);
136+
RCLCPP_WARN(get_logger(), "Could not set user defined initial pose");
137+
}
138+
}
139+
74140
void PoseInitializer::on_initialize(
75141
const Initialize::Service::Request::SharedPtr req,
76142
const Initialize::Service::Response::SharedPtr res)
@@ -82,12 +148,8 @@ void PoseInitializer::on_initialize(
82148
}
83149
try {
84150
change_state(State::Message::INITIALIZING);
85-
if (ekf_localization_trigger_) {
86-
ekf_localization_trigger_->send_request(false);
87-
}
88-
if (ndt_localization_trigger_) {
89-
ndt_localization_trigger_->send_request(false);
90-
}
151+
change_node_trigger(false, false);
152+
91153
auto pose = req->pose.empty() ? get_gnss_pose() : req->pose.front();
92154
if (ndt_) {
93155
pose = ndt_->align_pose(pose);
@@ -98,12 +160,8 @@ void PoseInitializer::on_initialize(
98160
}
99161
pose.pose.covariance = output_pose_covariance_;
100162
pub_reset_->publish(pose);
101-
if (ekf_localization_trigger_) {
102-
ekf_localization_trigger_->send_request(true);
103-
}
104-
if (ndt_localization_trigger_) {
105-
ndt_localization_trigger_->send_request(true);
106-
}
163+
164+
change_node_trigger(true, false);
107165
res->status.success = true;
108166
change_state(State::Message::INITIALIZED);
109167
} catch (const ServiceException & error) {

localization/pose_initializer/src/pose_initializer/pose_initializer_core.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ class PoseInitializer : public rclcpp::Node
5858
std::unique_ptr<NdtLocalizationTriggerModule> ndt_localization_trigger_;
5959
std::unique_ptr<tier4_autoware_utils::LoggerLevelConfigure> logger_configure_;
6060
double stop_check_duration_;
61+
62+
void change_node_trigger(bool flag, bool need_spin = false);
63+
void set_user_defined_initial_pose(const geometry_msgs::msg::Pose initial_pose);
6164
void change_state(State::Message::_state_type state);
6265
void on_initialize(
6366
const Initialize::Service::Request::SharedPtr req,

0 commit comments

Comments
 (0)