-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ROS2 docking utils #462
ROS2 docking utils #462
Changes from 49 commits
05eb483
c8cfb37
4dab7b1
a582884
0584719
ea582cf
cc093ce
5634f15
7fdd090
0b8c46e
bfb4811
a19a85f
60f460f
2213878
3a87e3d
c5bb087
12a084d
f0b0396
c00010d
e77e0d5
8dcbd36
3bc8f34
b3b4fbb
b993bf3
97d85c2
09a6410
4a77928
758ec7f
638d22c
2bc81af
165cedb
c790c53
863ef77
4189b20
5fc7560
4ee2f68
0327ac4
b9e11a5
0e70171
469e1e6
31ae7ce
7c29b8c
14b3297
66d943f
177de7c
9788164
624d8ad
863c835
39a7f12
9345045
645f833
6eda511
eda1ea1
1c09d65
2bebce6
c3a8732
afe42db
5f4d2ec
0f151e3
f2ec111
dbb95d0
47df893
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure, how we should spawn station. This solutions require duplicating config from docking_parameters.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. moved spawn to husarion_ugv_docking |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,125 @@ | ||||||||||||||||
#!/usr/bin/env python3 | ||||||||||||||||
|
||||||||||||||||
# Copyright 2024 Husarion sp. z o.o. | ||||||||||||||||
# | ||||||||||||||||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||||||||||||||||
# you may not use this file except in compliance with the License. | ||||||||||||||||
# You may obtain a copy of the License at | ||||||||||||||||
# | ||||||||||||||||
# http://www.apache.org/licenses/LICENSE-2.0 | ||||||||||||||||
# | ||||||||||||||||
# Unless required by applicable law or agreed to in writing, software | ||||||||||||||||
# distributed under the License is distributed on an "AS IS" BASIS, | ||||||||||||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||||||||||||
# See the License for the specific language governing permissions and | ||||||||||||||||
# limitations under the License. | ||||||||||||||||
|
||||||||||||||||
import os | ||||||||||||||||
from tempfile import NamedTemporaryFile | ||||||||||||||||
|
||||||||||||||||
import imageio | ||||||||||||||||
import yaml | ||||||||||||||||
from launch import LaunchDescription | ||||||||||||||||
from launch.actions import DeclareLaunchArgument, OpaqueFunction | ||||||||||||||||
from launch.conditions import IfCondition | ||||||||||||||||
from launch.substitutions import LaunchConfiguration, PathJoinSubstitution | ||||||||||||||||
from launch_ros.actions import Node | ||||||||||||||||
from launch_ros.substitutions import FindPackageShare | ||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
def generate_apriltag_and_get_path(tag_id): | ||||||||||||||||
from moms_apriltag import TagGenerator2 | ||||||||||||||||
|
||||||||||||||||
tag_generator = TagGenerator2("tag36h11") | ||||||||||||||||
tag_image = tag_generator.generate(tag_id, scale=1000) | ||||||||||||||||
temp_file = NamedTemporaryFile(suffix=f"_tag_{tag_id}.png", delete=False) | ||||||||||||||||
|
||||||||||||||||
imageio.imwrite(temp_file.name, tag_image) | ||||||||||||||||
return temp_file.name | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Use a context manager when working with temporary files To ensure proper resource management and avoid potential file leaks, use a context manager ( Apply this diff to use a context manager: def generate_apriltag_and_get_path(tag_id):
from moms_apriltag import TagGenerator2
tag_generator = TagGenerator2("tag36h11")
tag_image = tag_generator.generate(tag_id, scale=1000)
- temp_file = NamedTemporaryFile(suffix=f"_tag_{tag_id}.png", delete=False)
-
- imageio.imwrite(temp_file.name, tag_image)
- return temp_file.name
+ with NamedTemporaryFile(suffix=f"_tag_{tag_id}.png", delete=False) as temp_file:
+ imageio.imwrite(temp_file.name, tag_image)
+ return temp_file.name 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Ruff (0.8.0)35-35: Use a context manager for opening files (SIM115) |
||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
def spawn_stations(context, *args, **kwargs): | ||||||||||||||||
docking_server_config_path = LaunchConfiguration("docking_server_config_path").perform(context) | ||||||||||||||||
use_docking = LaunchConfiguration("use_docking").perform(context) | ||||||||||||||||
docking_server_config = None | ||||||||||||||||
|
||||||||||||||||
try: | ||||||||||||||||
with open(os.path.join(docking_server_config_path)) as file: | ||||||||||||||||
docking_server_config = yaml.safe_load(file) | ||||||||||||||||
if not isinstance(docking_server_config, dict) or "/**" not in docking_server_config: | ||||||||||||||||
raise ValueError("Invalid configuration structure") | ||||||||||||||||
except Exception as e: | ||||||||||||||||
print(f"Error loading docking server config: {str(e)}") | ||||||||||||||||
return [] | ||||||||||||||||
rafal-gorecki marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
|
||||||||||||||||
actions = [] | ||||||||||||||||
|
||||||||||||||||
ros_parameters = docking_server_config["/**"]["ros__parameters"] | ||||||||||||||||
docks_names = ros_parameters["docks"] | ||||||||||||||||
for dock_name in docks_names: | ||||||||||||||||
pose = ros_parameters[dock_name]["pose"] | ||||||||||||||||
|
||||||||||||||||
spawn_station = Node( | ||||||||||||||||
package="ros_gz_sim", | ||||||||||||||||
executable="create", | ||||||||||||||||
arguments=[ | ||||||||||||||||
"-name", | ||||||||||||||||
[dock_name, "_station"], | ||||||||||||||||
"-topic", | ||||||||||||||||
[dock_name, "_station_description"], | ||||||||||||||||
"-x", | ||||||||||||||||
str(pose[0]), | ||||||||||||||||
"-y", | ||||||||||||||||
str(pose[1] - 2.0), # -2.0 is the offset between world and map | ||||||||||||||||
rafal-gorecki marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||
"-z", | ||||||||||||||||
"0.5", # station z is not in 0.0 | ||||||||||||||||
"-R", | ||||||||||||||||
"1.57", | ||||||||||||||||
"-P", | ||||||||||||||||
"0.0", | ||||||||||||||||
"-Y", | ||||||||||||||||
str(pose[2] - 1.57), | ||||||||||||||||
], | ||||||||||||||||
emulate_tty=True, | ||||||||||||||||
condition=IfCondition(use_docking), | ||||||||||||||||
) | ||||||||||||||||
|
||||||||||||||||
actions.append(spawn_station) | ||||||||||||||||
|
||||||||||||||||
return actions | ||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
def generate_launch_description(): | ||||||||||||||||
declare_device_namespace = DeclareLaunchArgument( | ||||||||||||||||
"device_namespace", | ||||||||||||||||
default_value="", | ||||||||||||||||
description="Device namespace that will appear before all non absolute topics and TF frames, used for distinguishing multiple cameras on the same robot.", | ||||||||||||||||
) | ||||||||||||||||
|
||||||||||||||||
declare_docking_server_config_path_arg = DeclareLaunchArgument( | ||||||||||||||||
"docking_server_config_path", | ||||||||||||||||
default_value=PathJoinSubstitution( | ||||||||||||||||
[ | ||||||||||||||||
FindPackageShare("husarion_ugv_docking"), | ||||||||||||||||
"config", | ||||||||||||||||
"docking_server.yaml", | ||||||||||||||||
] | ||||||||||||||||
), | ||||||||||||||||
description=("Path to docking server configuration file."), | ||||||||||||||||
) | ||||||||||||||||
|
||||||||||||||||
declare_use_docking_arg = DeclareLaunchArgument( | ||||||||||||||||
"use_docking", | ||||||||||||||||
default_value="True", | ||||||||||||||||
description="Enable docking server and spawn docking stations in a simulation.", | ||||||||||||||||
choices=["True", "False", "true", "false"], | ||||||||||||||||
) | ||||||||||||||||
|
||||||||||||||||
return LaunchDescription( | ||||||||||||||||
[ | ||||||||||||||||
declare_docking_server_config_path_arg, | ||||||||||||||||
declare_device_namespace, | ||||||||||||||||
declare_use_docking_arg, | ||||||||||||||||
OpaqueFunction(function=spawn_stations), | ||||||||||||||||
] | ||||||||||||||||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Incorrect package reference in launch file path
The launch file
spawn_charging_docks.launch.py
exists but is located in thehusarion_ugv_gazebo
package, not inpanther_gazebo
. The launch file path insimulation.launch.py
needs to be updated to reference the correct package.simulation.launch.py
:should be:
🔗 Analysis chain
Verify charging dock launch file availability
The launch action is correctly implemented, but we should verify the existence of the referenced launch file.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
Length of output: 98
Script:
Length of output: 4332