Skip to content

Simulator

Overview

OpenMowerNext incorporates a Gazebo simulator and ros_gz integration.

TIP

If you are not familiar with Gazebo, please refer to Gazebo tutorials.

WARNING

This project uses Gazebo Fortress. Formerly known as Ignition Fortress.

Robot simulation

Getting started

Run the following command to start the simulator:

bash
ros2 launch openmower sim.launch.py

If run inside devcontainer, Gazebo GUI will be displayed in a VNC web client. You can access it by opening http://localhost:12345 in your browser.

TIP

Learn more about VNC client.

It's possible to run the simulator with GUI on external host machine. I haven't done it myself since GUI is unstable on MacOS.

Current state

World definition

xml
<?xml version="1.0" ?>
<sdf version="1.8">
    <world name="map">
        <physics name="1ms" type="ignored">
            <max_step_size>0.001</max_step_size>
            <real_time_factor>1.0</real_time_factor>
        </physics>

        <plugin filename="libgz-sim-physics-system.so" name="gz::sim::systems::Physics">
        </plugin>
        <plugin filename="libgz-sim-user-commands-system.so" name="gz::sim::systems::UserCommands">
        </plugin>
        <plugin filename="libgz-sim-scene-broadcaster-system.so" name="gz::sim::systems::SceneBroadcaster">
        </plugin>

        <plugin filename="libgz-sim-navsat-system" name="gz::sim::systems::NavSat">
        </plugin>
        <plugin filename="libgz-sim-imu-system.so" name="gz::sim::systems::Imu">
        </plugin>

        <spherical_coordinates>
            <surface_model>EARTH_WGS84</surface_model>
            <world_frame_orientation>ENU</world_frame_orientation>
            <latitude_deg>-22.9</latitude_deg>
            <longitude_deg>-43.2</longitude_deg>
            <elevation>0</elevation>
            <heading_deg>0</heading_deg>
        </spherical_coordinates>

        <!-- Add sun light with shadows -->
        <light type="directional" name="sun">
            <cast_shadows>true</cast_shadows>
            <pose>0 0 10 0 0 0</pose>
            <diffuse>0.8 0.8 0.8 1</diffuse>
            <specular>0.2 0.2 0.2 1</specular>
            <direction>-0.5 0.1 -0.9</direction>
        </light>

        <!-- OpenMower Docking Station -->
        <model name="docking_station">
            <static>true</static>
            <pose>1.5 1.5 0 0 0 0</pose>

            <!-- Add pose publisher plugin -->
            <plugin filename="libgz-sim-pose-publisher-system.so" name="gz::sim::systems::PosePublisher">
                <publish_link_pose>true</publish_link_pose>
                <publish_nested_model_pose>true</publish_nested_model_pose>
                <update_frequency>1</update_frequency>
                <!-- Charging contact is positioned at [0.32, 0, 0.06] relative to docking station origin -->
            </plugin>

            <!-- Base Plate -->
            <link name="base_plate">
                <visual name="visual">
                    <geometry>
                        <box>
                            <size>0.8 0.4 0.01</size>
                        </box>
                    </geometry>
                    <material>
                        <ambient>0.1 0.1 0.1 1</ambient>
                        <diffuse>0.1 0.1 0.1 1</diffuse>
                        <specular>0.01 0.01 0.01 1</specular>
                    </material>
                </visual>
                <collision name="collision">
                    <geometry>
                        <box>
                            <size>0.8 0.4 0.01</size>
                        </box>
                    </geometry>
                </collision>
            </link>

            <!-- Charging Port -->
            <link name="charging_port">
                <pose>0.35 0 0.075 0 0 0</pose>
                <visual name="visual">
                    <geometry>
                        <box>
                            <size>0.1 0.3 0.15</size>
                        </box>
                    </geometry>
                    <material>
                        <ambient>0.1 0.1 0.1 1</ambient>
                        <diffuse>0.1 0.1 0.1 1</diffuse>
                        <specular>0.01 0.01 0.01 1</specular>
                    </material>
                </visual>
                <collision name="collision">
                    <geometry>
                        <box>
                            <size>0.1 0.3 0.15</size>
                        </box>
                    </geometry>
                </collision>

            </link>

            <!-- Charging Contact - Modified for better visibility -->
            <link name="charging_contact">
                <pose>0.32 0 0.06 0 0 0</pose>
                <visual name="visual">
                    <geometry>
                        <box>
                            <size>0.02 0.15 0.03</size>
                        </box>
                    </geometry>
                    <material>
                        <ambient>1.0 0.0 0.0 1</ambient>
                        <diffuse>1.0 0.0 0.0 1</diffuse>
                        <specular>1.0 1.0 1.0 1</specular>
                        <emissive>0.5 0.0 0.0 1</emissive>
                    </material>
                </visual>
                <collision name="collision">
                    <geometry>
                        <box>
                            <size>0.02 0.15 0.03</size>
                        </box>
                    </geometry>
                </collision>
            </link>

            <!-- Guide Rail Left -->
            <link name="guide_rail_left">
                <pose>0.15 0.2 0.02 0 0 0</pose>
                <visual name="visual">
                    <geometry>
                        <box>
                            <size>0.4 0.02 0.04</size>
                        </box>
                    </geometry>
                    <material>
                        <ambient>0.3 0.3 0.3 1</ambient>
                        <diffuse>0.3 0.3 0.3 1</diffuse>
                        <specular>0.1 0.1 0.1 1</specular>
                    </material>
                </visual>
                <collision name="collision">
                    <geometry>
                        <box>
                            <size>0.4 0.02 0.04</size>
                        </box>
                    </geometry>
                </collision>
            </link>

            <!-- Guide Rail Right -->
            <link name="guide_rail_right">
                <pose>0.15 -0.2 0.02 0 0 0</pose>
                <visual name="visual">
                    <geometry>
                        <box>
                            <size>0.4 0.02 0.04</size>
                        </box>
                    </geometry>
                    <material>
                        <ambient>0.3 0.3 0.3 1</ambient>
                        <diffuse>0.3 0.3 0.3 1</diffuse>
                        <specular>0.1 0.1 0.1 1</specular>
                    </material>
                </visual>
                <collision name="collision">
                    <geometry>
                        <box>
                            <size>0.4 0.02 0.04</size>
                        </box>
                    </geometry>
                </collision>
            </link>

            <!-- Fixed joints for connecting parts -->
            <joint name="base_to_charging_port" type="fixed">
                <parent>base_plate</parent>
                <child>charging_port</child>
            </joint>

            <joint name="charging_port_to_contact" type="fixed">
                <parent>charging_port</parent>
                <child>charging_contact</child>
            </joint>

            <!-- Joints for guide rails -->
            <joint name="base_to_guide_rail_left" type="fixed">
                <parent>base_plate</parent>
                <child>guide_rail_left</child>
            </joint>

            <joint name="base_to_guide_rail_right" type="fixed">
                <parent>base_plate</parent>
                <child>guide_rail_right</child>
            </joint>
        </model>

        <include>
            <uri>
                https://fuel.gazebosim.org/1.0/hexarotor/models/grasspatch
            </uri>
        </include>
    </world>
</sdf>