Skip to content

Commit dc4240e

Browse files
authored
feat: #389 set initial pose directly (#399)
1 parent 5bff20b commit dc4240e

File tree

5 files changed

+93
-33
lines changed

5 files changed

+93
-33
lines changed

.vscode/settings.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@
3535
"${env:HOME}/ros_ws/awf/install/driving_log_replayer_msgs/local/lib/python3.10/dist-packages",
3636
"${env:HOME}/ros_ws/awf/install/tier4_debug_msgs/local/lib/python3.10/dist-packages",
3737
"${env:HOME}/ros_ws/awf/install/driving_log_replayer_analyzer/local/lib/python3.10/dist-packages",
38-
"${env:HOME}/ros_ws/awf/install/autoware_adapi_v1_msgs/local/lib/python3.10/dist-packages",
3938
"${env:HOME}/ros_ws/awf/install/tier4_localization_msgs/local/lib/python3.10/dist-packages",
4039
"${env:HOME}/ros_ws/awf/install/tier4_api_msgs/local/lib/python3.10/dist-packages",
4140
"${env:HOME}/ros_ws/awf/install/tier4_perception_msgs/local/lib/python3.10/dist-packages",
42-
"${env:HOME}/ros_ws/awf/install/autoware_perception_msgs/local/lib/python3.10/dist-packages",
43-
"${env:HOME}/ros_ws/awf/install/lanelet2_extension_python/local/lib/python3.10/dist-packages"
41+
"${env:HOME}/ros_ws/awf/install/lanelet2_extension_python/local/lib/python3.10/dist-packages",
42+
"${env:HOME}/ros_ws/awf/install/autoware_common_msgs/local/lib/python3.10/dist-packages",
43+
"${env:HOME}/ros_ws/awf/install/autoware_perception_msgs/local/lib/python3.10/dist-packages"
4444
],
4545
"python.analysis.extraPaths": [
4646
"/opt/ros/humble/lib/python3.10/site-packages",
@@ -53,12 +53,12 @@
5353
"${env:HOME}/ros_ws/awf/install/driving_log_replayer_msgs/local/lib/python3.10/dist-packages",
5454
"${env:HOME}/ros_ws/awf/install/tier4_debug_msgs/local/lib/python3.10/dist-packages",
5555
"${env:HOME}/ros_ws/awf/install/driving_log_replayer_analyzer/local/lib/python3.10/dist-packages",
56-
"${env:HOME}/ros_ws/awf/install/autoware_adapi_v1_msgs/local/lib/python3.10/dist-packages",
5756
"${env:HOME}/ros_ws/awf/install/tier4_localization_msgs/local/lib/python3.10/dist-packages",
5857
"${env:HOME}/ros_ws/awf/install/tier4_api_msgs/local/lib/python3.10/dist-packages",
5958
"${env:HOME}/ros_ws/awf/install/tier4_perception_msgs/local/lib/python3.10/dist-packages",
60-
"${env:HOME}/ros_ws/awf/install/autoware_perception_msgs/local/lib/python3.10/dist-packages",
61-
"${env:HOME}/ros_ws/awf/install/lanelet2_extension_python/local/lib/python3.10/dist-packages"
59+
"${env:HOME}/ros_ws/awf/install/lanelet2_extension_python/local/lib/python3.10/dist-packages",
60+
"${env:HOME}/ros_ws/awf/install/autoware_common_msgs/local/lib/python3.10/dist-packages",
61+
"${env:HOME}/ros_ws/awf/install/autoware_perception_msgs/local/lib/python3.10/dist-packages"
6262
],
6363
"files.associations": {
6464
"cctype": "cpp",

driving_log_replayer/driving_log_replayer/evaluator.py

+44-23
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from typing import Any
1919
from typing import TYPE_CHECKING
2020

21-
from autoware_adapi_v1_msgs.srv import InitializeLocalization
2221
from autoware_auto_perception_msgs.msg import ObjectClassification
2322
from builtin_interfaces.msg import Time as Stamp
2423
from geometry_msgs.msg import Point
@@ -44,6 +43,7 @@
4443
from tf2_ros import TransformException
4544
from tf2_ros import TransformListener
4645
from tf_transformations import euler_from_quaternion
46+
from tier4_localization_msgs.srv import InitializeLocalization
4747
from tier4_localization_msgs.srv import PoseWithCovarianceStamped as PoseWithCovarianceStampedSrv
4848
import yaml
4949

@@ -53,7 +53,7 @@
5353
from driving_log_replayer.scenario import load_scenario
5454

5555
if TYPE_CHECKING:
56-
from autoware_adapi_v1_msgs.msg import ResponseStatus
56+
from autoware_common_msgs.msg import ResponseStatus
5757

5858

5959
class DLREvaluator(Node):
@@ -107,9 +107,10 @@ def __init__(self, name: str, scenario_class: Callable, result_class: Callable)
107107
self._tf_buffer = Buffer()
108108
self._tf_listener = TransformListener(self._tf_buffer, self, spin_thread=True)
109109

110+
# initial pose estimation
110111
self._initial_pose_running: bool = False
111112
self._initial_pose_success: bool = False
112-
self._initial_pose = self.set_initial_pose()
113+
self._initial_pose, self._initial_pose_method = self.set_initial_pose()
113114
self.start_initialpose_service()
114115

115116
self._current_time = Time().to_msg()
@@ -174,17 +175,20 @@ def start_initialpose_service(self) -> None:
174175
return
175176
self._initial_pose_client = self.create_client(
176177
InitializeLocalization,
177-
"/api/localization/initialize",
178+
"/localization/initialize",
178179
)
179-
self._map_fit_client = self.create_client(
180-
PoseWithCovarianceStampedSrv,
181-
"/map/map_height_fitter/service",
182-
)
183-
184180
while not self._initial_pose_client.wait_for_service(timeout_sec=1.0):
185181
self.get_logger().warning("initial pose service not available, waiting again...")
186-
while not self._map_fit_client.wait_for_service(timeout_sec=1.0):
187-
self.get_logger().warning("map height fitter service not available, waiting again...")
182+
183+
if self._initial_pose_method == InitializeLocalization.Request.AUTO:
184+
self._map_fit_client = self.create_client(
185+
PoseWithCovarianceStampedSrv,
186+
"/map/map_height_fitter/service",
187+
)
188+
while not self._map_fit_client.wait_for_service(timeout_sec=1.0):
189+
self.get_logger().warning(
190+
"map height fitter service not available, waiting again...",
191+
)
188192

189193
def call_initialpose_service(self) -> None:
190194
if self._initial_pose is None or self._initial_pose_success or self._initial_pose_running:
@@ -194,17 +198,29 @@ def call_initialpose_service(self) -> None:
194198
)
195199
self._initial_pose_running = True
196200
self._initial_pose.header.stamp = self._current_time
197-
future_map_fit = self._map_fit_client.call_async(
198-
PoseWithCovarianceStampedSrv.Request(pose_with_covariance=self._initial_pose),
199-
)
200-
future_map_fit.add_done_callback(self.map_fit_cb)
201+
if self._initial_pose_method == InitializeLocalization.Request.AUTO:
202+
future_map_fit = self._map_fit_client.call_async(
203+
PoseWithCovarianceStampedSrv.Request(pose_with_covariance=self._initial_pose),
204+
)
205+
future_map_fit.add_done_callback(self.map_fit_cb)
206+
else:
207+
future_direct_init_pose = self._initial_pose_client.call_async(
208+
InitializeLocalization.Request(
209+
method=self._initial_pose_method,
210+
pose_with_covariance=[self._initial_pose],
211+
),
212+
)
213+
future_direct_init_pose.add_done_callback(self.initial_pose_cb)
201214

202215
def map_fit_cb(self, future: Future) -> None:
203216
result = future.result()
204217
if result is not None:
205218
if result.success:
206219
future_init_pose = self._initial_pose_client.call_async(
207-
InitializeLocalization.Request(pose=[result.pose_with_covariance]),
220+
InitializeLocalization.Request(
221+
method=self._initial_pose_method,
222+
pose_with_covariance=[result.pose_with_covariance],
223+
),
208224
)
209225
future_init_pose.add_done_callback(self.initial_pose_cb)
210226
else:
@@ -267,12 +283,17 @@ def transform_stamped_with_euler_angle(cls, transform_stamped: TransformStamped)
267283
}
268284
return tf_euler
269285

270-
def set_initial_pose(self) -> PoseWithCovarianceStamped | None:
271-
if not hasattr(self._scenario.Evaluation, "InitialPose"):
272-
return None
273-
if self._scenario.Evaluation.InitialPose is None:
274-
return None
275-
initial_pose: InitialPose = self._scenario.Evaluation.InitialPose
286+
def set_initial_pose(self) -> tuple[PoseWithCovarianceStamped | None, int | None]:
287+
auto_pose = getattr(self._scenario.Evaluation, "InitialPose", None)
288+
direct_pose = getattr(self._scenario.Evaluation, "DirectInitialPose", None)
289+
if auto_pose is None and direct_pose is None:
290+
return None, None
291+
if auto_pose is not None:
292+
initial_pose: InitialPose = auto_pose
293+
pose_method: int = InitializeLocalization.Request.AUTO
294+
if direct_pose is not None:
295+
initial_pose: InitialPose = direct_pose
296+
pose_method: int = InitializeLocalization.Request.DIRECT
276297
covariance = np.array(
277298
[
278299
0.25,
@@ -320,7 +341,7 @@ def set_initial_pose(self) -> PoseWithCovarianceStamped | None:
320341
),
321342
covariance=covariance,
322343
)
323-
return PoseWithCovarianceStamped(header=Header(frame_id="map"), pose=pose)
344+
return PoseWithCovarianceStamped(header=Header(frame_id="map"), pose=pose), pose_method
324345

325346
@classmethod
326347
def get_perception_label_str(cls, classification: ObjectClassification) -> str:

driving_log_replayer/driving_log_replayer/localization.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@
2424
from geometry_msgs.msg import PoseStamped
2525
import numpy as np
2626
from pydantic import BaseModel
27+
from pydantic import model_validator
2728
from rosidl_runtime_py import message_to_ordereddict
2829
from tier4_debug_msgs.msg import Float32Stamped
2930
from tier4_debug_msgs.msg import Int32Stamped
3031

3132
from driving_log_replayer.result import EvaluationItem
3233
from driving_log_replayer.result import ResultBase
33-
from driving_log_replayer.scenario import InitialPose
34+
from driving_log_replayer.scenario import InitialPose as InitialPoseModel
3435
from driving_log_replayer.scenario import number
3536
from driving_log_replayer.scenario import Scenario
3637

@@ -65,9 +66,17 @@ class Conditions(BaseModel):
6566

6667
class Evaluation(BaseModel):
6768
UseCaseName: Literal["localization"]
68-
UseCaseFormatVersion: Literal["1.2.0"]
69+
UseCaseFormatVersion: Literal["1.2.0", "1.3.0"]
6970
Conditions: Conditions
70-
InitialPose: InitialPose | None
71+
InitialPose: InitialPoseModel | None = None
72+
DirectInitialPose: InitialPoseModel | None = None
73+
74+
@model_validator(mode="after")
75+
def mutually_exclusive(self) -> "Evaluation":
76+
if self.InitialPose is not None and self.DirectInitialPose is not None:
77+
err_msg = "Expected only one, either `InitialPose` or `DirectInitialPose`, not together"
78+
raise ValueError(err_msg)
79+
return self
7180

7281

7382
class LocalizationScenario(Scenario):

driving_log_replayer/package.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616

1717
<build_depend>autoware_cmake</build_depend>
1818

19-
<depend>autoware_adapi_v1_msgs</depend>
2019
<depend>autoware_auto_mapping_msgs</depend>
2120
<depend>autoware_auto_perception_msgs</depend>
21+
<depend>autoware_common_msgs</depend>
2222
<depend>autoware_perception_msgs</depend>
2323
<depend>diagnostic_msgs</depend>
2424
<depend>driving_log_replayer_msgs</depend>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
ScenarioFormatVersion: 2.2.0
2+
ScenarioName: sample_localization
3+
ScenarioDescription: sample_localization
4+
SensorModel: sample_sensor_kit
5+
VehicleModel: sample_vehicle
6+
VehicleId: default
7+
LocalMapPath: $HOME/autoware_map/sample-map-planning
8+
Evaluation:
9+
UseCaseName: localization
10+
UseCaseFormatVersion: 1.3.0
11+
Conditions:
12+
Convergence:
13+
AllowableDistance: 0.2 # Lateral distance to be considered convergence
14+
AllowableExeTimeMs: 100.0 # If the NDT computation time is less than or equal to this value, it is considered successful.
15+
AllowableIterationNum: 30 # If the number of NDT calculations is less than or equal to this value, it is considered a success.
16+
PassRate: 95.0 # How much (%) of the evaluation attempts are considered successful.
17+
Reliability:
18+
Method: NVTL # NVTL or TP which method to use for evaluation
19+
AllowableLikelihood: 2.3 # If above this value, the localization reliability value is considered normal.
20+
NGCount: 10 # If the reliability value is lower than the threshold value for more than this number in the sequence. the evaluation is considered to have failed.
21+
DirectInitialPose:
22+
position:
23+
x: 3839.340576171875
24+
y: 73731.3359375
25+
z: 19.639482498168945
26+
orientation:
27+
x: -0.023971009814459248
28+
y: 0.005891999600528019
29+
z: -0.9709848597542231
30+
w: 0.237863568369043

0 commit comments

Comments
 (0)