diff --git a/src/vehicle_pkg/config/platforms/platform_mkmini.yaml b/src/vehicle_pkg/config/platforms/platform_mkmini.yaml index 5a65343..9e6c0af 100755 --- a/src/vehicle_pkg/config/platforms/platform_mkmini.yaml +++ b/src/vehicle_pkg/config/platforms/platform_mkmini.yaml @@ -26,6 +26,12 @@ platform: sim_sensor_driver: carla_lidar # sim_mode=true sim_lidar: vanjee # CARLA 스폰 blueprint 정체성 (차량↔라이다 고정 페어링) + # Gazebo is an opt-in simulation backend (simulator:=gazebo). Keep the + # existing CARLA selections above as the default so existing runs are not + # changed. + gazebo_vehicle_driver: gazebo_mkmini_passthrough + gazebo_sensor_driver: gazebo_mkmini_lidar + # cross-workspace 규칙 키 (기존 {robot} 컨벤션 보존 — 다운스트림 무수정) perception_profile: mkmini # → perception_{...}.yaml, tf_{...}.yaml, control_*_{...}.yaml scan_topic: /scan diff --git a/src/vehicle_pkg/config/sensor_drivers/sensor_driver_gazebo_mkmini_lidar.yaml b/src/vehicle_pkg/config/sensor_drivers/sensor_driver_gazebo_mkmini_lidar.yaml new file mode 100644 index 0000000..6672cdf --- /dev/null +++ b/src/vehicle_pkg/config/sensor_drivers/sensor_driver_gazebo_mkmini_lidar.yaml @@ -0,0 +1,14 @@ +# Gazebo publishes the simulated 3D point cloud directly to the topic used by +# the current MK-mini perception and control configurations. +sensor_driver: + name: gazebo_mkmini_lidar + display_name: Gazebo MK-mini 3D LiDAR + dimension: 3d + modes: [sim] + compatible_platforms: [mkmini] + scan_adapter: pointcloud_passthrough + driver_launch: + package: "" + launch: "" + speed_msg: none + bridge: {} diff --git a/src/vehicle_pkg/config/vehicle_drivers/vehicle_driver_gazebo_mkmini_passthrough.yaml b/src/vehicle_pkg/config/vehicle_drivers/vehicle_driver_gazebo_mkmini_passthrough.yaml new file mode 100644 index 0000000..dc50392 --- /dev/null +++ b/src/vehicle_pkg/config/vehicle_drivers/vehicle_driver_gazebo_mkmini_passthrough.yaml @@ -0,0 +1,10 @@ +# Gazebo MK-mini consumes Nav2 Twist messages directly through the Ackermann +# plugin. This profile intentionally has no hardware driver or adapter. +vehicle_driver: + name: gazebo_mkmini_passthrough + display_name: Gazebo MK-mini Twist passthrough + adapter: "" + driver_launch: + package: "" + launch: "" + adapter_params: {} diff --git a/src/vehicle_pkg/launch/mkmini_gazebo.launch.py b/src/vehicle_pkg/launch/mkmini_gazebo.launch.py new file mode 100644 index 0000000..2fbd6e4 --- /dev/null +++ b/src/vehicle_pkg/launch/mkmini_gazebo.launch.py @@ -0,0 +1,35 @@ +"""Opt-in Gazebo backend for the MK-mini vehicle profile.""" + +import os + +from ament_index_python.packages import get_package_share_directory +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription, SetEnvironmentVariable +from launch.conditions import IfCondition +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch.substitutions import EnvironmentVariable, LaunchConfiguration + + +def generate_launch_description(): + pkg_share = get_package_share_directory('vehicle_pkg') + gazebo_share = get_package_share_directory('gazebo_ros') + model_dir = os.path.join(pkg_share, 'models') + world_path = os.path.join(pkg_share, 'worlds', 'mkmini_gazebo.world') + gui = LaunchConfiguration('gui') + + return LaunchDescription([ + DeclareLaunchArgument('gui', default_value='true'), + SetEnvironmentVariable( + name='GAZEBO_MODEL_PATH', + value=[model_dir, os.pathsep, EnvironmentVariable('GAZEBO_MODEL_PATH', default_value='')], + ), + IncludeLaunchDescription( + PythonLaunchDescriptionSource(os.path.join(gazebo_share, 'launch', 'gazebo.launch.py')), + launch_arguments={ + 'world': world_path, + 'gui': gui, + 'verbose': 'false', + 'pause': 'false', + }.items(), + ), + ]) diff --git a/src/vehicle_pkg/launch/vehicle.launch.py b/src/vehicle_pkg/launch/vehicle.launch.py index 12e61c8..1c9c267 100755 --- a/src/vehicle_pkg/launch/vehicle.launch.py +++ b/src/vehicle_pkg/launch/vehicle.launch.py @@ -24,6 +24,10 @@ from vehicle_pkg.profiles import resolve_plan ARGUMENTS = [ DeclareLaunchArgument('sim_mode', default_value='false'), + # Empty keeps the existing platform profile behavior (MK-mini sim = CARLA). + # gazebo is opt-in so the real vehicle and current CARLA flows are unchanged. + DeclareLaunchArgument('simulator', default_value=''), + DeclareLaunchArgument('gui', default_value='true'), DeclareLaunchArgument('lidar', default_value='ouster'), # carla spawn 용 (choices 완화) DeclareLaunchArgument('level', default_value='None', choices=['None', '2d', '3d']), DeclareLaunchArgument('platform', default_value='mkmini'), @@ -46,6 +50,8 @@ ARGUMENTS = [ def build(context, *args, **kwargs): sim_mode = LaunchConfiguration('sim_mode').perform(context) + simulator = LaunchConfiguration('simulator').perform(context) + gui = LaunchConfiguration('gui').perform(context) lidar = LaunchConfiguration('lidar').perform(context) level = LaunchConfiguration('level').perform(context) platform = LaunchConfiguration('platform').perform(context) @@ -69,7 +75,8 @@ def build(context, *args, **kwargs): pkg_share, platform_name, sim_mode, vehicle_driver, sensor_driver, extra_config_dirs=extra_config_dirs, sensor_driver_params=sensor_driver_params, - vehicle_driver_params=vehicle_driver_params) + vehicle_driver_params=vehicle_driver_params, + simulator=simulator) sim = (sim_mode == 'true') actions = [] @@ -90,6 +97,12 @@ def build(context, *args, **kwargs): ('spawn_imu', spawn_imu), ], )) + elif sim and plan['simulator'] == 'gazebo': + gazebo_launch = os.path.join(pkg_share, 'launch', 'mkmini_gazebo.launch.py') + actions.append(IncludeLaunchDescription( + PythonLaunchDescriptionSource(gazebo_launch), + launch_arguments=[('gui', gui)], + )) elif not sim: actions.append(Node(package='vehicle_pkg', executable='pub_clock', name='pub_clock', output='screen')) diff --git a/src/vehicle_pkg/models/mkmini_gazebo/model.config b/src/vehicle_pkg/models/mkmini_gazebo/model.config new file mode 100644 index 0000000..f50fbe0 --- /dev/null +++ b/src/vehicle_pkg/models/mkmini_gazebo/model.config @@ -0,0 +1,7 @@ + + + mkmini_gazebo + 1.0 + model.sdf + Lightweight Ackermann MK-mini model for Gazebo learning runs. + diff --git a/src/vehicle_pkg/models/mkmini_gazebo/model.sdf b/src/vehicle_pkg/models/mkmini_gazebo/model.sdf new file mode 100644 index 0000000..5d59150 --- /dev/null +++ b/src/vehicle_pkg/models/mkmini_gazebo/model.sdf @@ -0,0 +1,44 @@ + + + + + 0 0 0.16 0 0 0 + + + 38.02.02.63.2 + 0 0 0.16 0 0 01.05 0.70 0.32 + 0 0 0.16 0 0 01.05 0.70 0.320.12 0.20 0.25 10.12 0.35 0.42 1 + 0.56 0 0.23 0 0 00.06 0.42 0.100.95 0.65 0.08 10.95 0.65 0.08 1 + + + 0.30 0 0 0 0 01.00.010.010.01 + base_linkfront_fork0 0 1-0.50.5 + + 0.30 0 0 0 0 01.20.020.010.020 0 0 1.5708 0 00.140.180 0 0 1.5708 0 00.140.180.04 0.04 0.04 10.04 0.04 0.04 1 + front_forkfront_drive_wheel0 1 0 + + -0.30 0.36 0 0 0 01.00.020.010.020 0 0 1.5708 0 00.140.100 0 0 1.5708 0 00.140.100.04 0.04 0.04 10.04 0.04 0.04 1 + base_linkrear_left_wheel0 1 0 + + -0.30 -0.36 0 0 0 01.00.020.010.020 0 0 1.5708 0 00.140.100 0 0 1.5708 0 00.140.100.04 0.04 0.04 10.04 0.04 0.04 1 + base_linkrear_right_wheel0 1 0 + + 0 0 0.52 0 0 00.20.0010.0010.001 + 0.0750.100.85 0.12 0.10 10.85 0.12 0.10 1 + true10false3601-3.141593.14159161-0.260.260.2018.00.02~/out:=/carla/hero/lidar_filteredsensor_msgs/PointCloud2os_lidar + + base_linkos_lidar + + + cmd_vel:=/cmd_velodom:=/odom_custom + front_steering_jointfront_drive_joint + rear_left_jointrear_right_joint + 0.720.280.28 + 120.01.50.8 + truetruetrue + odombase_link + + + diff --git a/src/vehicle_pkg/package.xml b/src/vehicle_pkg/package.xml index a977a2f..a4aabe8 100755 --- a/src/vehicle_pkg/package.xml +++ b/src/vehicle_pkg/package.xml @@ -13,6 +13,7 @@ yhs_can_interfaces yhs_can_control vanjee_lidar_sdk + gazebo_ros ament_copyright ament_flake8 diff --git a/src/vehicle_pkg/setup.py b/src/vehicle_pkg/setup.py index e2be388..4d168e9 100755 --- a/src/vehicle_pkg/setup.py +++ b/src/vehicle_pkg/setup.py @@ -20,6 +20,8 @@ setup( (os.path.join('share', package_name, 'config', 'platforms'), glob('config/platforms/*.yaml')), (os.path.join('share', package_name, 'config', 'vehicle_drivers'), glob('config/vehicle_drivers/*.yaml')), (os.path.join('share', package_name, 'config', 'sensor_drivers'), glob('config/sensor_drivers/*.yaml')), + (os.path.join('share', package_name, 'models', 'mkmini_gazebo'), glob('models/mkmini_gazebo/*')), + (os.path.join('share', package_name, 'worlds'), glob('worlds/*.world')), ], install_requires=['setuptools'], zip_safe=True, diff --git a/src/vehicle_pkg/vehicle_pkg/profiles.py b/src/vehicle_pkg/vehicle_pkg/profiles.py index 120ac8c..0e454b4 100755 --- a/src/vehicle_pkg/vehicle_pkg/profiles.py +++ b/src/vehicle_pkg/vehicle_pkg/profiles.py @@ -99,7 +99,7 @@ def _merge_params(prof, kind, raw_b64): def resolve_plan(pkg_share, platform_name, sim_mode, vehicle_driver_arg='', sensor_driver_arg='', extra_config_dirs='', sensor_driver_params='', - vehicle_driver_params=''): + vehicle_driver_params='', simulator=''): """platform/sim_mode/override 로 launch 플랜(dict) 해소. ROS 비의존. sim_mode 는 'true'/'false' 문자열. override 가 빈 문자열이면 platform 기본값 사용. @@ -113,7 +113,14 @@ def resolve_plan(pkg_share, platform_name, sim_mode, extra_dirs = [d for d in str(extra_config_dirs).split(':') if d] # 드라이버 이름 선택 (선택 source = platform 프로파일 데이터) - if sim: + simulator_name = str(simulator).strip() + if simulator_name and not sim: + raise ValueError('[profiles] simulator override requires sim_mode:=true') + + if sim and simulator_name == 'gazebo': + vd_name = P.get('gazebo_vehicle_driver', P['sim_vehicle_driver']) + sd_name = P.get('gazebo_sensor_driver', P['sim_sensor_driver']) + elif sim: vd_name = P['sim_vehicle_driver'] sd_name = P['sim_sensor_driver'] else: @@ -149,7 +156,7 @@ def resolve_plan(pkg_share, platform_name, sim_mode, return { 'platform': P['name'], - 'simulator': P.get('simulator', 'carla' if sim else 'real'), + 'simulator': simulator_name or P.get('simulator', 'carla' if sim else 'real'), 'drive_type': P['drive_type'], 'perception_profile': P.get('perception_profile', P['name']), 'lidar_frame': P.get('lidar_frame'), diff --git a/src/vehicle_pkg/worlds/mkmini_gazebo.world b/src/vehicle_pkg/worlds/mkmini_gazebo.world new file mode 100644 index 0000000..6283721 --- /dev/null +++ b/src/vehicle_pkg/worlds/mkmini_gazebo.world @@ -0,0 +1,21 @@ + + + + 0 0 -9.8 + + false + 0 0 10 0 0 0 + 0.8 0.8 0.8 1 + 0.2 0.2 0.2 1 + -0.5 0.1 -0.9 + + + true + + 0 0 1100 100 + 0 0 1100 1000.22 0.25 0.29 10.22 0.25 0.29 1 + + + model://mkmini_gazebo + +