From 6acbd7ca6f53074a7f6678f3828b19389b62f754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=93=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=B0=D1=80=D1=8C?= Date: Tue, 23 Dec 2025 21:48:18 +1000 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=B1=D0=B0=D0=B3=D0=B8,=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BA=D0=BE=D0=B4=20`Ob?= =?UTF-8?q?ject.proto`,=20=D0=B2=20=D0=BA=D0=BE=D1=82=D0=BE=D1=80=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=B1=D1=83=D0=B4=D1=83=D1=82=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D1=8F=D1=82=D1=8F=D1=8C=203?= =?UTF-8?q?=D0=B4=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D1=8B=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E?= =?UTF-8?q?=D1=89=D0=B5=D0=B3=D0=BE=20=D1=81=D0=BF=D0=B0=D0=B2=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +---- src/iiwa_bringup/config/iiwa_controller.yaml | 2 +- .../launch/digital_twin.launch.py | 8 +--- .../launch/supported/webots_spawn.launch.py | 2 +- src/iiwa_bringup/utils/converter.py | 2 +- .../resource/protos/Object.proto | 39 +++++++++++++++++++ src/iiwa_description/worlds/iiwa.wbt | 20 +++++++--- .../iiwa_object_spawner/object_spawner.py | 13 +++++++ 8 files changed, 74 insertions(+), 21 deletions(-) create mode 100644 src/iiwa_description/resource/protos/Object.proto diff --git a/README.md b/README.md index 3151952..6320bca 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ sudo apt install -y ros-${ROS_DISTRO}-webots-ros2 \ ros-${ROS_DISTRO}-ros2-control \ ros-${ROS_DISTRO}-ros2-controllers \ - ros-${ROS_DISTRO}-moveit-* \ + ros-${ROS_DISTRO}-moveit \ ``` Установка moveit2 (внимательно проверяй) @@ -23,12 +23,7 @@ sudo apt install -y build-essential \ wget # Not Using -git clone https://github.com/moveit/moveit2.git -vcs import --recursive < moveit2/moveit2.repos -sudo apt remove ros-$ROS_DISTRO-moveit* -rosdep install -r --from-paths ./src/ --ignore-src --rosdistro $ROS_DISTRO --os=ubuntu:noble -y - -colcon build --mixin release +LC_ALL=C ros2 launch iiwa_moveit demo... sudo pip3 install transforms3d --break-system-packages ``` diff --git a/src/iiwa_bringup/config/iiwa_controller.yaml b/src/iiwa_bringup/config/iiwa_controller.yaml index 66dc021..bb55e8d 100644 --- a/src/iiwa_bringup/config/iiwa_controller.yaml +++ b/src/iiwa_bringup/config/iiwa_controller.yaml @@ -1,6 +1,6 @@ controller_manager: ros__parameters: - update_rate: 31 + update_rate: 100 joint_state_broadcaster: type: "joint_state_broadcaster/JointStateBroadcaster" diff --git a/src/iiwa_bringup/launch/digital_twin.launch.py b/src/iiwa_bringup/launch/digital_twin.launch.py index 8f1ed80..6a035df 100644 --- a/src/iiwa_bringup/launch/digital_twin.launch.py +++ b/src/iiwa_bringup/launch/digital_twin.launch.py @@ -21,11 +21,7 @@ def _runtime_setup(context, *args, **kwatgs): model_path = LaunchConfiguration("model").perform(context) robot_name = LaunchConfiguration("robot_name").perform(context) world_path = LaunchConfiguration("world").perform(context) - rviz_status = LaunchConfiguration("rviz").perform(context).lower() in [ - "true", - "1", - "yes", - ] + rviz_status = LaunchConfiguration("rviz").perform(context).lower() in ["true", "1", "yes",] transform = LaunchConfiguration("transform").perform(context) rotation = LaunchConfiguration("rotation").perform(context) @@ -40,7 +36,7 @@ def _runtime_setup(context, *args, **kwatgs): executable="robot_state_publisher", name="robot_state_publisher", output="screen", - parameters=[{"robot_description": robot_description, "use_sim_time": False}], + parameters=[{"robot_description": robot_description, "use_sim_time": True}], ) webots_launch = IncludeLaunchDescription( diff --git a/src/iiwa_bringup/launch/supported/webots_spawn.launch.py b/src/iiwa_bringup/launch/supported/webots_spawn.launch.py index 4299a7c..9b1d69c 100644 --- a/src/iiwa_bringup/launch/supported/webots_spawn.launch.py +++ b/src/iiwa_bringup/launch/supported/webots_spawn.launch.py @@ -35,7 +35,7 @@ def _spawn_setup(context, *args, **kwargs): }, LaunchConfiguration("controller").perform(context), ], - respawn=True, + respawn=False, ) controllers_launch = IncludeLaunchDescription( diff --git a/src/iiwa_bringup/utils/converter.py b/src/iiwa_bringup/utils/converter.py index 4ccc3e2..eb8e5a5 100644 --- a/src/iiwa_bringup/utils/converter.py +++ b/src/iiwa_bringup/utils/converter.py @@ -9,4 +9,4 @@ def load_robot_description(model_path: Path, robot_name: str) -> str: elif suffix == ".urdf": return Path(model_path).read_text(encoding="utf-8") else: - raise FileNotFoundError(f"Supported file formats: xacro/urdf") \ No newline at end of file + raise FileNotFoundError("Supported file formats: xacro/urdf") \ No newline at end of file diff --git a/src/iiwa_description/resource/protos/Object.proto b/src/iiwa_description/resource/protos/Object.proto new file mode 100644 index 0000000..b5fd5ac --- /dev/null +++ b/src/iiwa_description/resource/protos/Object.proto @@ -0,0 +1,39 @@ +#VRML_SIM R2025a utf8 +# Describe the functionality of your PROTO here. +# template language: javascript + + +PROTO Object [ + field SFVec3f translation 0 0 0 + field SFRotation rotation 0 0 1 0 + field SFString name "my_object" + field MFString object_path [] + field SFNode physics Physics{ } +] +{ + Solid { + translation IS translation + rotation IS rotation + name IS name + contactMaterial "tool" + + children [ + Shape { + appearance PBRAppearance { + roughness 1 + metalness 0 + } + geometry Mesh { + url IS object_path + } + } + ] + + boundingObject Mesh { + url IS object_path + } + + physics IS physics + + } +} diff --git a/src/iiwa_description/worlds/iiwa.wbt b/src/iiwa_description/worlds/iiwa.wbt index 6f9e95c..aaf6c95 100644 --- a/src/iiwa_description/worlds/iiwa.wbt +++ b/src/iiwa_description/worlds/iiwa.wbt @@ -5,9 +5,13 @@ EXTERNPROTO "https://raw.githubusercontent.com/cyberbotics/webots/R2025a/project EXTERNPROTO "https://raw.githubusercontent.com/cyberbotics/webots/R2025a/projects/objects/floors/protos/RectangleArena.proto" EXTERNPROTO "../resource/protos/CollaborativeRobotTable.proto" EXTERNPROTO "../resource/protos/WorkspaceLimiter.proto" +EXTERNPROTO "../resource/protos/Object.proto" + WorldInfo { title "iiwa robotics" + basicTimeStep 10 + optimalThreadCount 4 contactProperties [ ContactProperties { material1 "TableMaterial" @@ -19,11 +23,18 @@ WorldInfo { softERP 1 softCFM 0.0001 } + ContactProperties { + material1 "tool" + material2 "TableMaterial" + bounce 0 + softCFM 0.002 + maxContactJoints 100 + } ] } Viewpoint { - orientation 0.19675345789351045 -0.08356742903703787 -0.976885132249993 3.928186370440618 - position 5.324715157515194 -4.7927780008585446 4.166958679133935 + orientation 0.19663259328507318 -0.09057124279298501 -0.9762850368805829 3.9867817928674034 + position 5.0239232195737245 -5.039192619765231 4.166958679133935 followType "Mounted Shot" ambientOcclusionRadius 3 } @@ -34,7 +45,7 @@ TexturedBackgroundLight { luminosity 2 } RectangleArena { - name "Room" + name "Arena" floorSize 12 12 wallHeight 2 } @@ -43,8 +54,7 @@ CollaborativeRobotTable { locked TRUE showCabinet TRUE } - -Group { +DEF limiter Group { children [ WorkspaceLimiter { translation -1.56 -0.219999 1.01 diff --git a/src/iiwa_object_spawner/iiwa_object_spawner/object_spawner.py b/src/iiwa_object_spawner/iiwa_object_spawner/object_spawner.py index 5e6c27f..7be7805 100644 --- a/src/iiwa_object_spawner/iiwa_object_spawner/object_spawner.py +++ b/src/iiwa_object_spawner/iiwa_object_spawner/object_spawner.py @@ -14,10 +14,16 @@ from webots_ros2_msgs.srv import SpawnNodeFromString class ObjectSpawner(Node): def __init__(self): super().__init__("object_spawner") + + # параметры передаваемые + self.declare_parameter('objects_path', '') + + # переменные self._object_count: int = randint(1, 5) self._spawned_count: int = 0 self._call_in_progress: bool = False + # Реализация self.cli = self.create_client( SpawnNodeFromString, "/Ros2Supervisor/spawn_node_from_string" ) @@ -29,7 +35,9 @@ class ObjectSpawner(Node): self._timer = self.create_timer(0.1, self.timer_callback) + # TODO: переделать процесс спавна, должен сформировать все proto файлы, после чего заспавнить все объекты def timer_callback(self): + # TODO: здесь должен получать объекты if self._spawned_count >= self._object_count: self.get_logger().info(f"All {self._object_count} objects spawned") self._timer.cancel() @@ -39,6 +47,7 @@ class ObjectSpawner(Node): return data = 'Solid { name "test_box2" translation 0 1 0.5 children [ Shape { appearance PBRAppearance { baseColor 0.901961 0.380392 0 } geometry Box { size 0.1 0.1 0.1 } } ] boundingObject Box { size 0.1 0.1 0.1 } physics Physics { } }' + data = self._create_group(children=[data]) req = SpawnNodeFromString.Request(data=data, check_fields=True) self.get_logger().info( @@ -58,6 +67,10 @@ class ObjectSpawner(Node): self._call_in_progress = False self._spawned_count += 1 + # Вспомогательные методы формирования кода для спавна объектов + def _create_group(self, children: list[str]) -> str: + return f"DEF OBJECTS Group {{children [{" ".join(children)}]}}" + def main(args=None): try: