diff --git a/README.md b/README.md index d48b931d..afa39fbc 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,7 @@ An alternative to using the images from MBARI's DockerHub would be to build from If you have an NVIDIA graphics card ``` + ./build.bash nvidia_opengl_ubuntu24 ./build.bash mbari_wec ``` Otherwise diff --git a/docker/build.bash b/docker/build.bash index 9f6f53a8..a7e8d9e0 100755 --- a/docker/build.bash +++ b/docker/build.bash @@ -29,14 +29,14 @@ fi # Get path to current directory DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -# Default base image, defined in nvidia_opengl_ubuntu22/Dockerfile +# Default base image, defined in nvidia_opengl_ubuntu24/Dockerfile # Ubuntu with nvidia-docker2 beta opengl support, i.e. -# nvidia/opengl:1.0-glvnd-devel-ubuntu22.04, doesn't exist for Ubuntu 22.04 -# at time of writing. Use homebrewed version in ./nvidia_opengl_ubuntu22/. +# nvidia/opengl:1.2-glvnd-devel-ubuntu24.04, doesn't exist for Ubuntu 24.04 +# at time of writing. Use homebrewed version in ./nvidia_opengl_ubuntu24/. # https://hub.docker.com/r/nvidia/opengl -#base="nvidia_opengl_ubuntu22:latest" -base="nvidia/opengl:1.2-glvnd-devel-ubuntu22.04" +base="nvidia_opengl_ubuntu24:latest" +#base="nvidia/opengl:1.2-glvnd-devel-ubuntu22.04" image_suffix="_nvidia" # Parse and remove args @@ -44,7 +44,7 @@ PARAMS="" while (( "$#" )); do case "$1" in --no-nvidia) - base="ubuntu:jammy" + base="ubuntu:noble" image_suffix="_no_nvidia" shift ;; @@ -77,7 +77,7 @@ docker build --rm -t $image_plus_tag --build-arg base=$base --build-arg user_id= echo "Built $image_plus_tag" # Don't add extra tag if just building the NVIDIA image -if [[ "$image_name" != nvidia_opengl_ubuntu22 ]]; then +if [[ "$image_name" != nvidia_opengl_ubuntu24 ]]; then # Extra tag in case you have both the NVIDIA and no-NVIDIA images docker tag $image_plus_tag $image_name$image_suffix:latest echo "Tagged as $image_name$image_suffix:latest" diff --git a/docker/mbari_wec/Dockerfile b/docker/mbari_wec/Dockerfile index 0d966014..d0f15400 100644 --- a/docker/mbari_wec/Dockerfile +++ b/docker/mbari_wec/Dockerfile @@ -48,36 +48,39 @@ RUN locale-gen en_US en_US.UTF-8 && \ export LANG=en_US.UTF-8 # Add ROS 2 apt repository -# Set up keys -RUN curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg -# Set up sources.list -RUN /bin/sh -c 'echo "deb [arch=amd64,arm64] http://packages.ros.org/ros2/ubuntu `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list' \ - && /bin/sh -c 'echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null' +RUN ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}') \ + && curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo $VERSION_CODENAME)_all.deb" # If using Ubuntu derivates use $UBUNTU_CODENAME +RUN dpkg -i /tmp/ros2-apt-source.deb # ppa for libfshydrodynamics free surface hydrodynamics dependency until # alternative in this PR: https://github.com/osrf/mbari_wec_gz/pull/138 RUN curl -s --compressed "https://hamilton8415.github.io/ppa/KEY.gpg" | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/ppa.gpg >/dev/null \ && sudo curl -s --compressed -o /etc/apt/sources.list.d/my_list_file.list "https://hamilton8415.github.io/ppa/my_list_file.list" -# Set up Gazebo keys and install -RUN /bin/sh -c 'wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg' \ - && /bin/sh -c 'echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null' \ - && apt update \ +# Install ROS 2 Jazzy and Gazebo Harmonic (from ros-gz) +RUN apt update \ && apt install -y \ python3-rosdep \ python3-vcstool \ python3-colcon-common-extensions \ - ros-humble-desktop \ - ros-humble-rmw-cyclonedds-cpp \ - gz-garden \ - libfshydrodynamics=1.3.1 \ + ros-jazzy-desktop \ + ros-jazzy-rmw-cyclonedds-cpp \ + ros-jazzy-rosbag2-storage-mcap \ + ros-jazzy-sdformat-urdf \ + ros-jazzy-plotjuggler \ + ros-jazzy-plotjuggler-msgs \ + ros-jazzy-plotjuggler-ros \ + ros-jazzy-ros-gz \ + ros-jazzy-gz-sim-vendor \ + ros-jazzy-gz-math-vendor \ + libfshydrodynamics=1.4.0 \ && apt clean # For timing in tests, need to use cyclonedds for ROS 2 rather than default # rmw provider ENV RMW_IMPLEMENTATION rmw_cyclonedds_cpp # Using non-official Gazebo + ROS combination, set it explicitly -ENV GZ_VERSION garden +ENV GZ_VERSION harmonic # Add a user with the same user_id as the user outside the container # Requires a docker build argument `user_id` @@ -94,24 +97,31 @@ USER $USERNAME # When running a container start in the developer's home folder WORKDIR /home/$USERNAME +RUN ls # Create project directory and import packages ENV MBARI_WEC_WS /home/$USERNAME/mbari_wec_ws RUN mkdir -p ${MBARI_WEC_WS}/src \ && cd ${MBARI_WEC_WS}/src/ \ && wget https://raw.githubusercontent.com/osrf/mbari_wec/main/mbari_wec_all.yaml \ + && cat mbari_wec_all.yaml + +RUN cd ${MBARI_WEC_WS}/src \ && vcs import < mbari_wec_all.yaml +# Workaround for gz sim and math python bindings +RUN python3 -m pip install -i https://mbari-org.github.io/gz-python-bindings/simple gz-python-bindings --break-system-packages + # Install rosdep dependencies RUN sudo apt update \ && cd ${MBARI_WEC_WS} \ && sudo rosdep init \ && rosdep update \ - && rosdep install --from-paths src --ignore-src -r -y -i --rosdistro humble \ + && rosdep install --from-paths src --ignore-src -r -y -i --rosdistro jazzy \ && sudo rm -rf /var/lib/apt/lists/* \ && sudo apt clean # Build the project -RUN /bin/bash -c 'source /opt/ros/humble/setup.bash \ +RUN /bin/bash -c 'source /opt/ros/jazzy/setup.bash \ && cd ${MBARI_WEC_WS} \ && colcon build' @@ -125,7 +135,7 @@ ENV RUN_SH /home/$USERNAME/run_simulation.bash RUN touch ${RUN_SH} \ && chmod 755 ${RUN_SH} \ && echo ". ${SETUP_SH}" >> ${RUN_SH} \ - && echo "ros2 launch buoy_gazebo mbari_wec.launch.py pbloghome:=/logs" >> ${RUN_SH} + && echo "ros2 launch buoy_gazebo mbari_wec.launch.py pbloghome:=/logs rosbag2:=true" >> ${RUN_SH} # Start the container at a bash prompt ENTRYPOINT ["/bin/bash" , "-c", "source ${SETUP_SH} && /bin/bash"] diff --git a/docker/nvidia_opengl_ubuntu22/Dockerfile b/docker/nvidia_opengl_ubuntu24/Dockerfile similarity index 99% rename from docker/nvidia_opengl_ubuntu22/Dockerfile rename to docker/nvidia_opengl_ubuntu24/Dockerfile index 19a24d1f..fcc21734 100644 --- a/docker/nvidia_opengl_ubuntu22/Dockerfile +++ b/docker/nvidia_opengl_ubuntu24/Dockerfile @@ -18,7 +18,7 @@ # builds an equivalent, to run X server in an Ubuntu 20.04 Docker image. # https://hub.docker.com/r/nvidia/opengl -FROM ubuntu:jammy +FROM ubuntu:noble ##### # Following lines are copied from diff --git a/docker/nvidia_opengl_ubuntu22/NGC-DL-CONTAINER-LICENSE b/docker/nvidia_opengl_ubuntu24/NGC-DL-CONTAINER-LICENSE similarity index 100% rename from docker/nvidia_opengl_ubuntu22/NGC-DL-CONTAINER-LICENSE rename to docker/nvidia_opengl_ubuntu24/NGC-DL-CONTAINER-LICENSE diff --git a/docker/run.bash b/docker/run.bash index a63ca742..e19336b4 100755 --- a/docker/run.bash +++ b/docker/run.bash @@ -33,7 +33,11 @@ fi # Default to NVIDIA #DOCKER_OPTS="--runtime=nvidia" -DOCKER_OPTS="--gpus all --env NVIDIA_DRIVER_CAPABILITIES=all" +DOCKER_OPTS="--gpus all -e NVIDIA_DRIVER_CAPABILITIES=all" +# workarounds for MESA/ZINK Vulkan issue +DOCKER_OPTS="$DOCKER_OPTS -v /usr/share/glvnd/egl_vendor.d/10_nvidia.json:/usr/share/glvnd/egl_vendor.d/10_nvidia.json" +DOCKER_OPTS="$DOCKER_OPTS -e LIBGL_KOPPER_DISABLE=true -e __GLX_VENDOR_LIBRARY_NAME=nvidia" +DOCKER_OPTS="$DOCKER_OPTS -e __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/10_nvidia.json:/usr/share/glvnd/egl_vendor.d/50_mesa.json" # Parse and remove args PARAMS="" diff --git a/docs/docs/ROS2/cpp_api.md b/docs/docs/ROS2/cpp_api.md index 80d7ebaa..19038cdc 100644 --- a/docs/docs/ROS2/cpp_api.md +++ b/docs/docs/ROS2/cpp_api.md @@ -31,6 +31,7 @@ - power_callback - trefoil_callback - powerbuoy_callback + - latent_callback (SIM ONLY) Template argument: **ControllerImplCRTP** The concrete controller class that inherits from this interface. It must implement any callbacks or parameter-setting routines it needs. @@ -120,6 +121,19 @@ public void Interface(const std::string & node_name, const b **check_for_services** If true, attempt to verify service availability before use. +### spin + +```cpp +public void spin() +``` + +**brief** Sets up a `MultiThreadedExecutor` and spins the node (blocking). + + If you need non-blocking control over program flow, you may skip calling this function, but a + `MultiThreadedExecutor` is required for this node. You may call non-blocking spin functions of a + `MultiThreadedExecutor` in your own loop. + + ### use_sim_time ```cpp @@ -276,6 +290,54 @@ public shared_future send_pc_retract_command(const float & retract) **return** A future containing the service response. +### get_inc_wave_height + +```cpp +public buoy_interfaces::srv::IncWaveHeight::Response::SharedPtr get_inc_wave_height( + const float x, + const float y, + const float t, + const bool use_buoy_origin = false, + const bool use_relative_time = false +) +``` + +*Defined at buoy_api_cpp/include/buoy_api/interface.hpp#1164* + +**brief** Get incident wave height at a single location and time + +**x** float meters, x component of wave height location +**y** float meters, y component of wave height location +**t** float seconds, sim time to evaluate wave height +**use_buoy_origin** boolean, (x,y) are relative to buoy location +**use_relative_time** boolean, t is relative to current sim time + +**return** vector of IncWaveHeight data (with a single index) + +```cpp +public buoy_interfaces::srv::IncWaveHeight::Response::SharedPtr get_inc_wave_height( + const std::vector x, + const std::vector y, + const std::vector t, + const bool use_buoy_origin = false, + const bool use_relative_time = false, + const float timeout = 2.0, + const bool use_callback = false +) +``` + +**brief** Get incident wave height at multiple locations and times + +**x** std::vector meters, x component of wave height location +**y** std::vector meters, y component of wave height location +**t** std::vector seconds, sim time to evaluate wave height +**use_buoy_origin** boolean, all (x,y) are relative to buoy location +**use_relative_time** boolean, all t are relative to current sim time + +**return** vector of IncWaveHeight data + */ + + ### set_params ```cpp @@ -363,3 +425,14 @@ protected void powerbuoy_callback(const buoy_interfaces::msg::PBRecord & ) **brief** Override this function to subscribe to /powerbuoy_data to receive PBRecord telemetry. **data** Incoming PBRecord containing a slice of all microcontroller telemetry data. + + +### latent_callback + +```cpp +protected void latent_callback(const buoy_interfaces::msg::LatentData & ) +``` +**brief** Override this function to subscribe to /latent_data to receive LatentData sim-only data. + +**data** Incoming LatentData containing sim-only values e.g. losses, waves, etc. + diff --git a/docs/docs/ROS2/python_api.md b/docs/docs/ROS2/python_api.md index 3e99de33..44b1bee2 100644 --- a/docs/docs/ROS2/python_api.md +++ b/docs/docs/ROS2/python_api.md @@ -31,6 +31,7 @@ one, a subscriber for that topic will not be set up: - self.power_callback - self.trefoil_callback - self.powerbuoy_callback +- self.latent_callback (sim only) @@ -52,6 +53,20 @@ Initialize the Interface node. - `wait_for_services` (`bool`): if True and if check_for_services, block until all services are available - `kwargs`: additional keyword arguments forwarded to ROS 2 Node + + +#### spin + +```python +def spin() +``` + +Sets up a `MultiThreadedExecutor` and spins the node (blocking). + +If you need non-blocking control over program flow, you may skip calling this function, but a +`MultiThreadedExecutor` is required for this node. You may call non-blocking spin functions of a +`MultiThreadedExecutor` in your own loop. + #### use\_sim\_time @@ -218,6 +233,30 @@ Set additional damping gain in the piston retract direction. - `retract` (`float`): additional damping gain for retraction - `blocking` (`bool`): if True, wait for the service call to complete + + +#### get\_inc\_wave\_height + +```python +def get_inc_wave_height(self, x, y, t, use_buoy_origin, use_relative_time, timeout=2.0) +``` + +Request incident wave height at specific location(s) and time(s). + +**Arguments**: +- `x` (`float` or `list`): x position(s) of desired wave height(s) +- `y` (`float` or `list`): y position(s) of desired wave height(s) +- `t` (`float` or `list`): t time(s) in seconds of sim time of desired wave height(s) +- `use_buoy_origin` (`bool`): if True, x and y are relative to buoy origin +- `use_relative_time` (`bool`): if True, desired time(s) are relative to current sim time + else, time(s) will be absolute sim time +- `timeout` (`float`): if not None, wait for timeout sec for the service call to complete + else, wait forever + +**Returns**: +- `list` of `IncWaveHeight` data + + #### set\_params @@ -314,3 +353,17 @@ PBRecord contains a slice of all microcontroller's telemetry data - `data`: incoming PBRecord + + +#### latent\_callback + +```python +def latent_callback(self, data) +``` + +Override this function to subscribe to /latent_data to receive sim-only LatentData. + +**Arguments**: + +- `data`: incoming LatentData + diff --git a/docs/docs/Tutorials/Install/Install_docker.md b/docs/docs/Tutorials/Install/Install_docker.md index 2e014c70..d9cad47e 100644 --- a/docs/docs/Tutorials/Install/Install_docker.md +++ b/docs/docs/Tutorials/Install/Install_docker.md @@ -60,6 +60,7 @@ is convenient if you would like to make any changes. 2. Build the docker image If you have an NVIDIA graphics card ``` + ./build.bash nvidia_opengl_ubuntu24 ./build.bash mbari_wec ``` Otherwise @@ -115,4 +116,4 @@ collected in the sim will also be the same ROS 2 messages collected on the physi ``` The simulation software should now be available. To run and test, proceed to the -[Run the Simulator](../../../tutorials/#running-the-simulator) tutorial series. +[Run the Simulator](../../tutorials.md#running-the-simulator) tutorial series. diff --git a/docs/docs/Tutorials/Install/Install_source.md b/docs/docs/Tutorials/Install/Install_source.md index 2cc869bd..caad275a 100644 --- a/docs/docs/Tutorials/Install/Install_source.md +++ b/docs/docs/Tutorials/Install/Install_source.md @@ -1,86 +1,158 @@ # Install from source ## Requirements -Use Ubuntu 22.04. -1. Install [ROS 2 Humble](https://docs.ros.org/en/humble/index.html) - MBARI WEC is tested against the cyclonedds rmw implementation, so set that up as follows: - ``` - sudo apt install -y ros-humble-rmw-cyclonedds-cpp - export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp - ``` +### Ubuntu 24.04, ROS 2 Jazzy, Gazebo Harmonic +!!! info "NOTE:" + These are the current recommended requirements. Ubuntu 22.04, ROS 2 Humble, Gazebo Garden + instructions are no longer maintained for `mbari_wec` as Gazebo Garden is EOL. -2. Install [Gazebo Garden](https://gazebosim.org/docs/garden) +Follow instructions for [Installing Gazebo with ROS](https://gazebosim.org/docs/harmonic/ros_installation/). -3. Install necessary tools - ``` - sudo apt install python3-vcstool python3-colcon-common-extensions python3-pip git wget - ``` +1. [Install](https://docs.ros.org/en/jazzy/Installation/Ubuntu-Install-Debs.html) ROS 2 Jazzy -4. Install necessary libraries - ``` - curl -s --compressed "https://hamilton8415.github.io/ppa/KEY.gpg" | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/ppa.gpg >/dev/null - sudo curl -s --compressed -o /etc/apt/sources.list.d/my_list_file.list "https://hamilton8415.github.io/ppa/my_list_file.list" - sudo apt update - sudo apt install libfshydrodynamics=1.3.1 - ``` + MBARI WEC works best with the cyclonedds rmw implementation, so set that up as follows: + + ``` + sudo apt install ros-jazzy-rmw-cyclonedds-cpp + export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp + ``` + Running the sim with rosbag2 logging uses mcap storage. We also need sdformat-urdf. + So, install those as well: -## Buoy Simulation Software Build + ``` + sudo apt install ros-jazzy-rosbag2-storage-mcap ros-jazzy-sdformat-urdf + ``` -1. Create a workspace, for example: - ``` - mkdir -p ~/mbari_wec_ws/src - cd ~/mbari_wec_ws/src - ``` + To use plotjuggler to view ros2 data live plots (recommended in these tutorials), install like so: -2. Clone all source repos with the help of `vcstool`: - ``` - wget https://raw.githubusercontent.com/osrf/mbari_wec/main/mbari_wec_all.yaml - vcs import < mbari_wec_all.yaml - cd ~/mbari_wec_ws - ``` + ``` + sudo apt install ros-jazzy-plotjuggler ros-jazzy-plotjuggler-msgs ros-jazzy-plotjuggler-ros + ``` -3. Set the Gazebo version to Garden. This is needed because we're not using an - official ROS + Gazebo combination (place this in ~/.bashrc for convenience if rebuilding often): - ``` - export GZ_VERSION=garden - ``` +2. Install Gazebo Harmonic by installing `ros_gz` from the `ros-jazzy-*` apt repos. + + ``` + sudo apt update + sudo apt install ros-jazzy-ros-gz + ``` -4. Install ROS dependencies - ``` - sudo pip3 install -U rosdep - sudo rosdep init - rosdep update - rosdep install --from-paths src --ignore-src -r -y -i - ``` + When using Gazebo Harmonic and ROS 2 Jazzy together, Gazebo packages (`gz-*`) now come from + ROS 2 Jazzy apt repos (`ros-jazzy-gz-*`). We also need to use the `sdformat-urdf` package. + See [here](https://gazebosim.org/docs/harmonic/ros_installation/) for more info. + +3. Set the Gazebo version to Harmonic. (place this in ~/.bashrc for convenience if rebuilding often): + + ``` + export GZ_VERSION=harmonic + ``` + +4. gz-python-bindings + + Python bindings for `gz.math` and `gz.sim` are used in `mbari_wec` but are not distributed via apt or pip. + This repository, [gz-python-bindings](https://github.com/mbari-org/gz-python-bindings) builds the python + bindings and packages them up in a simple `PyPI` index url for an easy pip install. + + 1. Ensure these packages are also installed + + ``` + sudo apt update + sudo apt install ros-jazzy-gz-sim-vendor ros-jazzy-gz-math-vendor + ``` + + 2. pip install + + NOTE: `--break-system-packages` might sound scary, but don't be alarmed -- nothing bad will happen in this case -5. Build and install ``` - source /opt/ros/humble/setup.bash - cd ~/mbari_wec_ws - colcon build + python3 -m pip install -i https://mbari-org.github.io/gz-python-bindings/simple gz-python-bindings --break-system-packages ``` +5. Install necessary tools + + ``` + sudo apt install python3-vcstool python3-colcon-common-extensions python3-pip git wget + ``` + +6. Install necessary libraries + + ``` + curl -s --compressed "https://hamilton8415.github.io/ppa/KEY.gpg" | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/ppa.gpg >/dev/null + sudo curl -s --compressed -o /etc/apt/sources.list.d/my_list_file.list "https://hamilton8415.github.io/ppa/my_list_file.list" + sudo apt update + sudo apt install libfshydrodynamics=1.4.0 + ``` + + +## Buoy Simulation Software Build + +1. Create a workspace, for example: + + ``` + mkdir -p ~/mbari_wec_ws/src + cd ~/mbari_wec_ws/src + ``` + +2. Clone all source repos with the help of `vcstool`: + + ``` + wget https://raw.githubusercontent.com/osrf/mbari_wec/main/mbari_wec_all.yaml + vcs import < mbari_wec_all.yaml + cd ~/mbari_wec_ws + ``` + +3. Install ROS dependencies + + ``` + sudo pip3 install -U rosdep + sudo rosdep init + rosdep update + rosdep install --from-paths src --ignore-src -r -y -i + ``` + +4. Build and install + + ``` + source /opt/ros/jazzy/setup.bash + cd ~/mbari_wec_ws + colcon build + ``` + The simulation software should build without errors. To run and test, proceed to the - [Run the Simulator](../../../tutorials/#running-the-simulator) tutorial series. Or run a quick + [Run the Simulator](../../tutorials.md#running-the-simulator) tutorial series. Or run a quick test as described below to confirm all has worked as expected. ## Run an example to test 1. In a new terminal, source the workspace - ``` - . ~/mbari_wec_ws/install/setup.bash - ``` + + ``` + . ~/mbari_wec_ws/install/setup.bash + ``` -1. Set `SDF_PATH` to allow `robot_state_publisher` parse the robot description +2. Set `SDF_PATH` to allow `robot_state_publisher` parse the robot description from the sdformat model (place this in ~/.bashrc for convenience if rebuilding often): - ``` - export SDF_PATH=$GZ_SIM_RESOURCE_PATH - ``` - -1. Launch the simulation - ``` - ros2 launch buoy_gazebo mbari_wec.launch.py - ``` + ``` + export SDF_PATH=$GZ_SIM_RESOURCE_PATH + ``` + +3. Launch the simulation + + ``` + ros2 launch buoy_gazebo mbari_wec.launch.py + ``` + +## Post-Build Environment Setup + +Place these lines in your ~/.bashrc for convenience to simplify running the sim in the future: + + ``` + source /opt/ros/jazzy/setup.bash + source /path/to/mbari_wec_ws/install/setup.bash + export GZ_VERSION=harmonic + export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp + export SDF_PATH=$GZ_SIM_RESOURCE_PATH + ``` +(NOTE: Remember to replace `/path/to/mbari_wec_ws/install/setup.bash` with your path to your mbari wec workspace) diff --git a/docs/docs/Tutorials/Simulation/SimulatorInteractionPbcmd.md b/docs/docs/Tutorials/Simulation/SimulatorInteractionPbcmd.md index 2644e563..e2b60e66 100644 --- a/docs/docs/Tutorials/Simulation/SimulatorInteractionPbcmd.md +++ b/docs/docs/Tutorials/Simulation/SimulatorInteractionPbcmd.md @@ -28,6 +28,20 @@ $ source install/setup.bash ``` Then, run `pbcmd` or any of the commands listed in its output: +!!! info "NOTE:" + If you receive a message: `pbcmd: command not found` when trying to run, please run the following + command first: + ``` + $ export PATH=$PATH:~/.local/bin + ``` + + Ensure the following is in your `~/.profile` for next time: + ``` + # set PATH so it includes user's private bin if it exists + if [ -d "$HOME/.local/bin" ] ; then + PATH="$HOME/.local/bin:$PATH" + fi + ``` ``` $ pbcmd @@ -132,13 +146,9 @@ controls the rate of the ROS 2 messages from the power converter on the buoy, an ## Example Usage As an example, issue the following commands in a terminal *where the workspace has been sourced*: -1. Launch the simulation without incident waves by issuing the following commands, the first -command over-rides the default sea-state and results in no incident wave-forcing on the buoy when -the "regenerate_models" flag is set to false: +1. Launch the simulation without incident waves by issuing the following command (overriding the default waves): ``` -$ empy -D 'inc_wave_spectrum_type="None"' -o ~/mbari_wec_ws/install/buoy_description/share/buoy_description/models/mbari_wec/model.sdf ~/mbari_wec_ws/install/buoy_description/share/buoy_description/models/mbari_wec/model.sdf.em - -$ ros2 launch buoy_gazebo mbari_wec.launch.py regenerate_models:=false +$ ros2 launch buoy_gazebo mbari_wec.launch.py inc_wave_spectrum:='inc_wave_spectrum_type:None' ``` 2. Start the simulation in the GUI by pressing the play button. @@ -153,7 +163,6 @@ the /spring_data topic, and then create plots to display these messages in separ 5. Issue the following command to introduce a 10A winding current offset in the motor-current/RPM relationship. - ``` $ pc_BiasCurr 10 ``` diff --git a/docs/docs/Tutorials/Simulation/SimulatorOutputLogs.md b/docs/docs/Tutorials/Simulation/SimulatorOutputLogs.md index 30ca87d3..dc904c58 100644 --- a/docs/docs/Tutorials/Simulation/SimulatorOutputLogs.md +++ b/docs/docs/Tutorials/Simulation/SimulatorOutputLogs.md @@ -1,2 +1,274 @@ # Simulator Output Data Logs +When running, the simulator logs data in two formats, a .csv file that matches the format of the log +files the buoy system produces while in operation, and rosbag files that logs the ros message +traffic in a format that can be examined using ROS 2 tools. This tutorial describes the locations +and contents of these files. + +## .csv data files +While running, both the simulator and the buoy itself log telemetry data in text comma separated +value files that can be examined while the simulator is running or processed subsequently. These +data files contain all of the telemetry data available on the buoy while operational. Because not +all parameters are simulated, the .csv files from the simulator have all the fields present and +match the format of the at-sea buoy, but some values that don't make sense to simulate simply +report unchanging default values. + +### .csv file locations + +To match the behavior of the buoy system, the simulator stores these files in a directory called +`.pblogs` in the users home directory (`/home//` or `~/`). The directory format of `.pblogs` is as follows: + +``` +.pblogs +├── 2025-06-21.000 +│   ├── 2025.06.21T12.52.43.csv +│   └── latest -> 2025.06.21T12.52.43.csv +├── 2025-08-06.000 +│   ├── 2025.08.06T08.03.20.csv +│   └── latest -> 2025.08.06T08.03.20.csv +├── 2025-08-06.001 +│   ├── 2025.08.06T09.08.00.csv.gz +│   ├── 2025.08.06T10.08.00.csv +│   └── latest -> 2025.08.06T10.08.00.csv +└── latest_csv_dir -> 2025-08-06.001 +``` + +As seen in this example, every time the simulator is run a new folder is created with the current +date and an index of how many times the simulator has been started on that day, i.e. 2025-08-06.000 +is the first time the simulator ran on August 6th, and 2025-08-06.001 is the second time the +simulator ran on August 6th. This scheme matches how the buoy maintains it's file structure as +well, with the index referring to re-starts of the logging executable instead of simulator runs. +For convenience, a symbolic link is maintained that points to the most recent simulation run +(`latest_csv_dir`). + +Within each directory, .csv files are created that represent up to an hour of data. At the end of +each hour those files are zipped up and a new file is created for the next hour of data. Therefore, +the timestamp shown in the directory listing for each .csv file is the time of the first data in the +file. In cases where the simulator is running faster than real time, the filenames represent the +amount of simulated time that has passed since the beginning of the simulation. + +Note: The simulation environment creates this directory structure at ~/.pblogs when the simulator +is run from the command line. If simulations are run in a batch mode using the facility provided to +support many simulation runs, then these files are located in a different location. +See this tutorial for details: [Parameters and Batch Runs](SimulatorParameters.md) + +### .csv data format +The data in the .csv data files are organized by data source within the system. During operation on +the buoy, each subsystem is generating telemetry asynchronously to one other, and the logging +facility place the data from each on a new line of the .csv files. + +A sample of the first few lines of a typical .csv data files is as follows: + +``` +Source ID, Timestamp (epoch seconds), PC RPM, PC Bus Voltage (V), PC Winding Curr (A), PC Battery Curr (A), PC + Status, PC Load Dump Current (A), PC Target Voltage (V), PC Target Curr (A), PC Diff PSI, PC RPM Std Dev, PC +Scale, PC Retract, PC Aux Torque (mV), PC Bias Curr (A), PC Charge Curr (A), PC Draw Curr (A), BC Voltage, BC + Ips, BC V Balance, BC V Stopcharge, BC Ground Fault, BC_Hydrogen, BC Status, XB Roll XB Angle (deg), XB Pitc +h Angle (deg), XB Yaw Angle (deg), XB X Rate, XB Y Rate, XB Z Rate, XB X Accel, XB Y Accel, XB Z Accel, XB Nor +th Vel, XB East Vel, XB Down Vel, XB Lat, XB Long, XB Alt, XB Temp, SC Load Cell (lbs), SC Range Finder (in), + SC Upper PSI, SC Lower PSI, SC Status, CTD Time, CTD Salinity, CTD Temp, TF Power-Loss Timeouts, TF Tether V +olt, TF Batt Volt, TF Pressure psi, TF Qtn 1, TF Qtn 2, TF Qtn 3, TF Qtn 4, TF Mag 1 gauss, TF Mag 2, TF Mag 3 +, TF Status, TF Ang Rate 1 rad/sec, TF Ang Rate 2, TF Ang Rate 3, TF VPE status, TF Accel 1 m/sec^2, TF Accel + 2, TF Accel 3, TF Comms-Loss Timeouts, TF Maxon status, TF Motor curren mA, TF Encoder counts, +4, 1754492880.215, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,60, 48.000, 48.000, -44.221, -0.000, 0.707, +0.000, 0.707, 0.226, 0.054, 0.421, 0, -0.000, 0.000, 0.000, 0, -8.956, -0.000, -0.009, 60, 0, 0, 0, +3, 1754492880.215, ,,,,,,,,,,,,,,,,,,,,,,,0.000, 0.001, 0.000, 0.000, 0.000, 0.000, 0.076, -0.000, 6.935, 0.36 +0, 0.009, 0.360, 36.74385, -121.87623, -2.821, 0.000, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0, 1754492880.215, ,,,,,,,,,,,,,,,,325.0, 0.00, 2.76, 2.79, 0.06, 3.26, 11264, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,, +1, 1754492880.215, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,446.92, 26.92, 76.22, 188.73, 8192, 0, 0.000000, 0.0 +00, ,,,,,,,,,,,,,,,,,,,,,,, +2, 1754492880.215, 3093.0, 325.0, -10.64, 3.57, 0, 0.83, 0.0, -10.64, 2.910, 0.0, 1.00, 0.60, 0.00, 0.00, 0.00 +, 0.00, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +1, 1754492880.315, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-48.78, 25.46, 77.90, 186.95, 8192, 0, 0.000000, 0.0 +00, ,,,,,,,,,,,,,,,,,,,,,,, + + +``` + +The first line of each file provides a short text description of each field, and after that the data +from each subsystem is logged as it becomes available. To differentiate between data sources, the +first data item in each file is an identifier, as follows: + +- 0 = Battery System + +- 1 = Spring Controller + +- 2 = Power Converter + +- 3 = Buoy AHRS/GPS + +- 4 = Heave Cone Controller + + +After the "Source ID" identifier comes Unix timestamp that records when the data on that line was +captured. As can be seen, to facilitate data ingestion from these files into other tools, the +appropriate number of commas are included on each line so that the data presented lines up with the +data-label on the first line. Because the first character is a single digit identifier, unix tools +can be used to look at this data controller by controller. For example, the following command uses +grep to pick out just the data from the power converter by selecting lines that have a 2 in the +first column: + +``` +$ cat ~/.pblogs/2025-08-06.001/2025.08.06T10.08.00.csv | grep ^2 + +2, 1754492904.515, 1656.4, 311.3, -7.44, 1.62, 0, -0.00, 0.0, -7.44, 2.910, 0.0, 1.00, 0.60, 0.00, 0.00, 0.00, 0.00, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, + +2, 1754492904.615, 1655.1, 311.3, -7.43, 1.61, 0, -0.00, 0.0, -7.43, 2.910, 0.0, 1.00, 0.60, 0.00, 0.00, 0.00, 0.00, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, + +2, 1754492904.715, 1633.7, 311.0, -7.32, 1.57, 0, -0.00, 0.0, -7.32, 2.910, 0.0, 1.00, 0.60, 0.00, 0.00, 0.00, 0.00, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, + +2, 1754492904.815, 1593.0, 310.3, -7.11, 1.48, 0, -0.00, 0.0, -7.11, 2.910, 0.0, 1.00, 0.60, 0.00, 0.00, 0.00, 0.00, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, + +``` + +### .csv data contents +For each data source, particular data is logged as described below. + +#### Battery Controller Data (Source ID = 0) +``` +BC Voltage, BC Ips, BC V Balance, BC V Stopcharge, BC Ground Fault, BC_Hydrogen, BC Status +``` + +- **BC_Voltage**: Measured instantaneous Battery Voltage in Volts. + +- **BC_Ips**: Measured Current Draw for the 24V supply that powers on-board instrumentation (Not Simulated) + +- **BC V Balance**: Number of batteries currently balancing, Encoded value. (Not Simulated) + +- **BC V_StopCharge**: Number of batteries that are above their peak voltage, Encoded Value (Not Simulated) + +- **BC Ground Fault**: Encoded representation of 300V Bus Isolation Monitor result. (Not Simulated) + +- **BC_Hydrogen**: Measure of the hydrogen in the lead-acid battery pack. %LEL. (Not Simulated) + +- **BC Status**: 16 bit status word of Battery system. + +#### Spring Controller Data (Source ID = 1) + +``` +SC Load Cell (lbs), SC Range Finder (in), SC Upper PSI, SC Lower PSI, SC Status, CTD Time, CTD Salinity, CTD Temp +``` + +- **SC Load Cell**: Measured tension between the buoy and the power take-off device (lbs). + +- **SC Range Finder (in)**: Measured piston position in inches. 0.0 = fully retracted, 80.0 = fully extended + +- **SC Upper PSI**: Measured upper spring chamber pressure (psia) + +- **SC Lower PSI**: Measured lower spring chamber pressure (psia) + +- **SC Status**: 16 bit status word of Spring Controller system. + +- **CTD Time**: Deprecated + +- **CTD Salinity**: Deprecated + +- **CTD Temp**: Deprecated + + +#### Power Converter Data (Source ID = 2) +``` +PC RPM, PC Bus Voltage (V), PC Winding Curr (A), PC Battery Curr (A), PC Status, PC Load Dump Current (A), PC Target Voltage (V), PC Target Curr (A), PC Diff PSI, PC RPM Std Dev, PC Scale, PC Retract, PC Aux Torque (mV), PC Bias Curr (A), PC Charge Curr (A), PC Draw Curr (A) +``` + +- **PC RPM**: Instantaneous measured generator rotational velocity (RPM). + +- **PC Bus Voltage**: Measured bus voltage of power converter (Volts). + +- **PC Winding Curr**: Instantaneous measured motor quadrature current (Amps). Is proportional to torque. + +- **PC Battery Curr**: Instantaneous measured current flowing to Battery System (Amps). + +- **PC Status**: 16 bit status word of Power Converter system. + +- **PC Load Dump Current**: Instantaneous measured current flowing to the load dump (Amps). + +- **PC Target Voltage**: Voltage limit setting, actual voltage may be less if the system is current limiting. + +- **PC Target Current**: Instantaneous measured winding quadrature current (Amps). + +- **PC Diff PSI**: Measured pressure of hydraulic system compensator (psi). Not Simulated. + +- **PC RPM Std Dev**: Standard deviation of RPM over the past 30 minutes (RPM). + +- **PC Scale**: Current damping scale factor setting. + +- **PC Retract**: Current retract factor setting. + +- **PC Aux Torque**: Torque sensor input. Not used at sea. Not Simulated. + +- **PC Bias Curr**: Bias Current applied to motor current versus RPM relationship (Amps). + +- **PC Charge Curr**: Battery Current limit (Battery Charge Direction) Amps. + +- **PC Draw Curr**: Battery Draw Limit (Battery Draw Direction). Amps. + + +#### GPS/AHRS Data (Source ID = 3) +``` +XB Roll Angle (deg), XB Pitch Angle (deg), XB Yaw Angle (deg), XB X Rate, XB Y Rate, XB Z Rate, XB X Accel, XB Y Accel, XB Z Accel, XB North Vel, XB East Vel, XB Down Vel, XB Lat, XB Long, XB Alt, XB Temp +``` + +- **XB Roll Angle**: Roll Angle reported from Crossbow Nav440 on the buoy (degrees). + +- **XB Pitch Angle**: Pitch Angle reported from Crossbow Nav440 on the buoy (degrees). + +- **XB Yaw Angle**: Pitch Angle reported from Crossbow Nav440 on the buoy (degrees). + + +#### Heave Cone Controller Data (Source ID = 4) +``` +TF Power-Loss Timeouts, TF Tether Volt, TF Batt Volt, TF Pressure psi, TF Qtn 1, TF Qtn 2, TF Qtn 3, TF Qtn 4, TF Mag 1 gauss, TF Mag 2, TF Mag 3, TF Status, TF Ang Rate 1 rad/sec, TF Ang Rate 2, TF Ang Rate 3, TF VPE status, TF Accel 1 m/sec^2, TF Accel 2, TF Accel 3, TF Comms-Loss Timeouts, TF Maxon status, TF Motor curren mA, TF Encoder counts +``` + +## Logging with rosbag2 + +The previous tutorials, [View ROS 2 Messages](SimulatorOutputROS.md), showed how to view and plot +ROS 2 messages that are output from the sim or physical buoy. The following sections will show how +to enable rosbag2 logging in the normal mode of the sim (batch mode always logs rosbags) and where +rosbags are stored in normal and batch modes. + +#### Normal Mode Simulation + +By default, only the .csv files are logged by the simulator in normal operation. To enable rosbag2 +logging, add the `rosbag2:=true` argument to the standard launch file like so: + +``` +$ ros2 launch buoy_gazebo mbari_wec.launch.py rosbag2:=true +``` + +The rosbags will be stored in the `~/.pblogs/rosbag2` directory with the following structure: + +``` +.pblog +├── latest_rosbag -> rosbag2/rosbag2_20250811115646 +└── rosbag2 + ├── rosbag2_20250806172159 + │ ├── metadata.yaml + │ └── rosbag2_20250806172159_0.mcap + ├── rosbag2_20250806180923 + │ ├── metadata.yaml + │ └── rosbag2_20250806180923_0.mcap + ├── rosbag2_20250811115336 + │ ├── metadata.yaml + │ └── rosbag2_20250811115336_0.mcap + └── rosbag2_20250811115646 + ├── metadata.yaml + └── rosbag2_20250811115646_0.mcap +``` + +where `latest_rosbag` is a symlink to the rosbag saved for the latest run of the simulator. The +rosbags will use the [mcap](https://mcap.dev/guides/getting-started/ros-2) storage format. For more +information on working with rosbag2, please see the official ROS 2 +[rosbag2 documentation](https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools/Recording-And-Playing-Back-Data/Recording-And-Playing-Back-Data.html). + +#### Batch Mode Simulation + +Running the simulation and file structure of logging in batch mode is described in this tutorial: +[Tutorial: Adjust Simulator parameters](SimulatorParameters.md) + +## Control Simulator with pbcmd + +The next tutorial, [Tutorial: Control Simulator with pbcmd](SimulatorInteractionPbcmd.md), will show +how to send certain commands to the simulated (or physical) buoy using our command-line utility. diff --git a/docs/docs/Tutorials/Simulation/SimulatorOutputROS.md b/docs/docs/Tutorials/Simulation/SimulatorOutputROS.md index e42dca09..605dd79f 100644 --- a/docs/docs/Tutorials/Simulation/SimulatorOutputROS.md +++ b/docs/docs/Tutorials/Simulation/SimulatorOutputROS.md @@ -1,25 +1,63 @@ # View ROS 2 Messages -While running, the simulator generates exactly the same ROS 2 messages that the buoy hardware does during operation. These are grouped into ROS 2 topics that corresponds to data being produced by each micro-controller or instrument on the buoy. To see all ROS 2 topics being published to on the system, issue the following command (after sourcing the workspace if needed in a new terminal ``` $ . ~/mbari_wec_ws/install/setup.bash``` +The data in each of the topics and services below correspond to the message descriptions which +can be seen in [ROS 2 Interface->Interfaces (ROS 2 Messages)](../../ROS2/messages.md) along with a +description of each field. + +## Topics + +While running, the simulator generates exactly the same ROS 2 messages that the buoy hardware does +during operation. These are grouped into ROS 2 topics that corresponds to data being produced by +each micro-controller or instrument on the buoy. To see all ROS 2 topics being published to on the +system, issue the following command (after sourcing the workspace if needed in a new terminal +` $ . ~/mbari_wec_ws/install/setup.bash`): ``` $ ros2 topic list /ahrs_data +/battery_data +/bc_record /clock +/events/write_split /joint_states +/latent_data /parameter_events +/pc_record /power_data /rosout +/sc_record /spring_data /tf +/tf_record /tf_static +/trefoil_data +/trefoil_imu +/trefoil_mag +/xb_gps /xb_imu +/xb_record ``` -The topics /ahrs_data, /battery_data, /spring_data, /power_data, and /heavecone_data corresponds to the buoy-based instrumentation (AHRS), battery controller, spring controller, power-converter controller, and heave-cone controller. Several of these topics are only available in simulation, and only /ahrs_data, /battery_data, /spring_data, /power_data, and /heavecone_data will be present on the real buoy. +Several of the topics listed with `ros2 topic list` are only available in simulation. Only the +following topics will be present on the real buoy: + +- /ahrs_data +- /battery_data +- /spring_data +- /power_data +- /trefoil_data +corresponding to: -To see the data being published in these topics, issue the following command and the data will scroll by, for example: +- buoy-based instrumentation (AHRS) +- battery controller +- spring controller +- power-converter controller +- heave-cone controller + + +To see the data being published in these topics, issue the following command and the data will +scroll by, for example: ``` $ ros2 topic echo power_data @@ -49,7 +87,55 @@ status: 0 --- ``` -The data in each topic corresponds to the message descriptions which can be seen here along with a description of each field. +## Services + +Several ROS 2 services are used by the command-line interface `pbcmd` +([Tutorial: Control Simulator Output with pbcmd](SimulatorInteractionPbcmd.md)) to issue commands to the +controllers on the buoy. To see a list issue the following command (result below only shows +important services): + +``` +$ ros2 service list +/bc_reset_command +/bender_command +/bus_command +/gain_command +/inc_wave_height +/pc_batt_switch_command +/pc_bias_curr_command +/pc_charge_curr_lim_command +/pc_draw_curr_lim_command +/pc_pack_rate_command +/pc_retract_command +/pc_scale_command +/pc_std_dev_targ_command +/pc_v_targ_max_command +/pc_wind_curr_command +/pump_command +/sc_pack_rate_command +/sc_reset_command +/tether_command +/tf_reset_command +/tf_set_actual_pos_command +/tf_set_charge_mode_command +/tf_set_curr_lim_command +/tf_set_mode_command +/tf_set_pos_command +/tf_set_state_machine_command +/tf_watchdog_command +/valve_command +``` + +## Logging During Simulation + +By default, data is logged to .csv files matching the format and file layout of the log files on +the physical buoy system. When running the simulator in single or batch modes, +[rosbag2](https://docs.ros.org/en/jazzy/Tutorials/Beginner-CLI-Tools/Recording-And-Playing-Back-Data/Recording-And-Playing-Back-Data.html) +logging to file may also be enabled (using [mcap](https://mcap.dev/guides/getting-started/ros-2) storage mode). +A detailed tutorial of logging with .csv and rosbag2 can be found in: +[Tutorial: Simulator Output Data Logs](SimulatorOutputLogs.md) -The next tutorial "[View Messages with Plotjuggler](SimulatorOutputPlotjuggler.md)" shows how to conveniently plot these data items while the simulator is running. +## Plotting Live Data +The next tutorial, [Tutorial: View Messages with Plotjuggler](SimulatorOutputPlotjuggler.md), shows how to +conveniently plot these ROS 2 data items while the simulator is running. diff --git a/docs/docs/Tutorials/Simulation/SimulatorParameters.md b/docs/docs/Tutorials/Simulation/SimulatorParameters.md index b97d68d6..f8b06661 100644 --- a/docs/docs/Tutorials/Simulation/SimulatorParameters.md +++ b/docs/docs/Tutorials/Simulation/SimulatorParameters.md @@ -1,21 +1,29 @@ # Parameters and Batch Runs ## Introduction -When running a simple instance of the simulator as described in the [Run the Simulator](RunSimulator.md) Tutorial. i.e. using: +When running a simple instance of the simulator as described in the +[Run the Simulator](RunSimulator.md) Tutorial. i.e. using: ``` $ ros2 launch buoy_gazebo mbari_wec.launch.py ``` -the simulation uses a number of defaults for a range of parameters. In most cases, one may want to run the simulator with different values for these parameters, and/or run a number of simulations that iterate across a range of values for particular parameters. For instance, one may want to run the simulator in a batch mode that runs the same buoy and controller set-up in a range of sea-states. +the simulation uses a number of defaults for a range of parameters. In most cases, one may want to +run the simulator with different values for these parameters, and/or run a number of simulations +that iterate across a range of values for particular parameters. For instance, one may want to run +the simulator in a batch mode that runs the same buoy and controller set-up in a range of sea-states. -To facilitate this, a batch tool is provided that allows one to specify ranges for a number of parameters, and then run a number of simulations for all combinations of parameters, saving the results separately. +To facilitate this, a batch tool is provided that allows one to specify ranges for a number of +parameters, and then run a number of simulations for all combinations of parameters, saving the +results separately. -This tutorial describes these capabilities, demonstrates with some examples, and discusses how this tool can be used. +This tutorial describes these capabilities, demonstrates with some examples, and discusses how this +tool can be used. ## Parameters -There are a number of parameters that impact the behavior of the simulator, and must be specified at start-up: +There are a number of parameters that impact the behavior of the simulator, and must be specified at +start-up: - **Simulation duration**: How long the simulation will run for (simulation time) in seconds. - **Time-step size**: The simulation proceeds at a fixed time-step size, and this can be specified for each run. @@ -29,7 +37,9 @@ There are a number of parameters that impact the behavior of the simulator, and - ** GUI Output**: The graphical output of the simulator can be turned on or off as needed, for large batches of runs that are meant to run un-attended this is probably not appropriate, but for single runs or debugging the graphical output can be useful. ## Example Batch File -The above parameters are specified in a .yaml file that the batch-run tool reads in before execution begins. A commented example is below and illustrates the use of the above parameters. Lines that begin with # are comments and have no impact. +The above parameters are specified in a .yaml file that the batch-run tool reads in before execution +begins. A commented example is below and illustrates the use of the above parameters. Lines that +begin with # are comments and have no impact. ``` # @@ -63,14 +73,22 @@ IncidentWaveSpectrumType: Szz: [0.0, 0.4, 1.0, 1.0, 0.0] ``` -As seen in this example, some parameters are enforced to be scalar values and apply to the entire batch of specified runs. These are the specification of simulation duration (300), random seed (42), and the physics real-time factor (11). +As seen in this example, some parameters are enforced to be scalar values and apply to the entire +batch of specified runs. These are the specification of simulation duration (300), random seed (42), +and the physics real-time factor (11). -The remaining run-specific parameters can be specified as arrays, and the batch-run tool then executes simulations for all possible combinations of these values. Note that some values are specified in pairs. For instance, three mono-chromatic waves are specified by this file with a specification of (A=1.0m, T=12s), (A=2.0m, T=14s), and (A=3.0m, T=15s), not nine runs that include all possible combinations of the specified amplitude and periods. +The remaining run-specific parameters can be specified as arrays, and the batch-run tool then +executes simulations for all possible combinations of these values. Note that some values are +specified in pairs. For instance, three mono-chromatic waves are specified by this file with a +specification of (A=1.0m, T=12s), (A=2.0m, T=14s), and (A=3.0m, T=15s), not nine runs that include +all possible combinations of the specified amplitude and periods. -Obviously it would be very easy to write a batch file specification that includes thousands of runs, more practical usage will most likely iterate over a small number of parameters at at a time. +Obviously it would be very easy to write a batch file specification that includes thousands of runs, +more practical usage will most likely iterate over a small number of parameters at at a time. ## Running an example -For a simpler example, a batch file that iterates across a range of sea-states is used. As a concise example, the following file illustrates this, comments have been removed for brevity. +For a simpler example, a batch file that iterates across a range of sea-states is used. As a +concise example, the following file illustrates this, comments have been removed for brevity. ``` duration: 3 @@ -87,7 +105,9 @@ IncidentWaveSpectrumType: Tp: [14.0, 16.0] ``` -To run this example, create the above file in a new directory and name it "IrregularWaves.yaml", source the simulator installation directory, and start the simulation using the batch tool. (Note that the run duration is very short for this example to allow it to complete quickly) +To run this example, create the above file in a new directory and name it "IrregularWaves.yaml", +source the simulator installation directory, and start the simulation using the batch tool. +(Note that the run duration is very short for this example to allow it to complete quickly) ``` $ mkdir FOO @@ -97,9 +117,15 @@ $ . ~/mbari_wec_ws/install/setup.bash $ ros2 launch buoy_gazebo mbari_wec_batch.launch.py sim_params_yaml:=IrregularWaves.yaml ``` -Running these commands will run the simulation, all output is stored in a directory named similar to `batch_results_20230228210735', the trailing numbers indicate a timestamp. Inside this directory the yaml file is repeated, along with a log file 'batch_results.log' that lists all of the simulation runs that were performed. Alongside that are specific directories that hold output from each run. For convenience, a symbolic link is formed that points at the most recent batch output directory. +Running these commands will run the simulation, all output is stored in a directory named similar to +`batch_results_20230228210735', the trailing numbers indicate a timestamp. Inside this directory +the yaml file is repeated, along with a log file 'batch_results.log' that lists all of the +simulation runs that were performed. Alongside that are specific directories that hold output from +each run. For convenience, a symbolic link is formed that points at the most recent batch output +directory. -Within the output directory, there is a file named 'batch_runs.log' that shows each individual run that was performed, and the associated parameter. In this case it has the following contents: +Within the output directory, there is a file named 'batch_runs.log' that shows each individual run +that was performed, and the associated parameter. In this case it has the following contents: ``` # Generated 4 simulation runs @@ -111,37 +137,138 @@ cWaveSpectrumParams 3, 0, 20230228212510, rosbag2_batch_sim_3_20230228212510, 0.01, 11.0, 42, 3.0, closed, 1.0, 0.5, Bretschneider;Hs:4.0;Tp:16.0 ``` -For simulations that take longer to run, it can be convenient to tail this log file from the terminal to keep track of progress. i.e. From the directory the batch was started from: +For simulations that take longer to run, it can be convenient to tail this log file from the +terminal to keep track of progress. i.e. From the directory the batch was started from: ``` $ tail -f latest_batch_results/batch_runs.log ``` ## Finding the output -Within the batch process output directory, (e.g. `batch_results_20230228210735'), the output of each simulation run is stored within a single sub-directory. The resulting directory tree from the above example is as follows: +Within the batch process output directory, (e.g. `batch_results_20230301200627'), the output of each +simulation run is stored within a single sub-directory. The resulting directory tree from the above +example is as follows: ``` $ tree batch_results_20230301200627/ batch_results_20230301200627/ ├── batch_runs.log ├── IrregularWaves_20230301200627.yaml +├── latest_csv_dir -> results_run_3_20230301200640/pblog +├── latest_rosbag -> results_run_3_20230301200640/rosbag2 ├── results_run_0_20230301200627 +│ ├── pblog +│   │   ├── 2023.03.01T20.06.27.csv +│   │   └── latest -> 2023.03.01T20.06.27.csv │   └── rosbag2 │   ├── metadata.yaml │   └── rosbag2_0.db3 ├── results_run_1_20230301200632 +│ ├── pblog +│   │   ├── 2023.03.01T20.06.32.csv +│   │   └── latest -> 2023.03.01T20.06.32.csv │   └── rosbag2 │   ├── metadata.yaml │   └── rosbag2_0.db3 ├── results_run_2_20230301200636 +│ ├── pblog +│   │   ├── 2023.03.01T20.06.36.csv +│   │   └── latest -> 2023.03.01T20.06.36.csv │   └── rosbag2 │   ├── metadata.yaml │   └── rosbag2_0.db3 └── results_run_3_20230301200640 + ├── pblog +    │   ├── 2023.03.01T20.06.40.csv +    │   └── latest -> 2023.03.01T20.06.40.csv └── rosbag2 ├── metadata.yaml └── rosbag2_0.db3 ``` - This output includes rosbag files and .csv files that are in the same format as the files generated on the physical buoy. In general the information in these two files are the same, the .csv files are in clear text and are easy to inspect, and can be processed by the same tools used for the actual buoy data. The rosbag files are binary files that encode all of the ROS2 messages on the computer during the simulation. These files can be processed by a number of tools for post-processing and inspection of results. It is also possible to load the rosbag files into plotjuggler for plotting and inspection, as described in the [View Messages with Plotjuggler](SimulatorOutputPlotjuggler.md) Tutorial. +This output includes rosbag files and .csv files that are in the same format as the files generated +on the physical buoy. In general the information in these two files are the same, the .csv files +are in clear text and are easy to inspect, and can be processed by the same tools used for the +actual buoy data. The rosbag files are binary files that encode all of the ROS2 messages on the +computer during the simulation. These files can be processed by a number of tools for post- +processing and inspection of results. It is also possible to load the rosbag files into plotjuggler +for plotting and inspection, as described in the +[View Messages with Plotjuggler](SimulatorOutputPlotjuggler.md) Tutorial. + +## Passing params directly to launch file + +Many of these parameters may be passed directly as arguments to `mbari_wec.launch.py`. To see a list, +enter the following command: +``` +$ ros2 launch buoy_gazebo mbari_wec.launch.py -s +Arguments (pass arguments as ':='): + + 'door_state': + open or closed + (default: 'None') + + 'physics_step': + step size in seconds + (default: 'None') + + 'physics_rtf': + sim real-time factor + (default: 'None') + + 'scale_factor': + target winding current scale factor + (default: 'None') + + 'inc_wave_seed': + random seed for incident wave computation + (default: 'None') + + 'battery_soc': + initial battery state of charge as pct (0-1) + (default: 'None') + + 'battery_emf': + initial battery emf in Volts + (default: 'None') + + 'x_mean_pos': + desired mean piston position in meters + (default: 'None') + + 'inc_wave_spectrum': + incident wave spectrum defined as inc_wave_spectrum_type:type;p1:v1:v2;p2:v1:v2 + (default: 'None') + + 'world_file': + Gazebo world filename.sdf + (default: 'mbari_wec.sdf') + + 'world_name': + Gazebo + (default: 'mbari_wec_world') + + 'pbloghome': + root pblog directory + (default: '/home/anderson/.pblogs') + + 'pblogdir': + specific pblog directory in pbloghome + (default: '') + + 'rosbag2': + save rosbags to /rosbag2/rosbag2_ + (default: 'false') + + 'debugger': + run gazebo in gdb + (default: 'false') + + 'extra_gz_args': + extra_gz_args + (default: '') + + 'regenerate_models': + regenerate template models using defaults + (default: 'true') +``` diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index efb29e47..eb195bef 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -41,6 +41,7 @@ extra_javascript: - js/extra.js markdown_extensions: + - admonition - mdx_math - pymdownx.highlight: anchor_linenums: False diff --git a/mbari_wec_all.yaml b/mbari_wec_all.yaml index 672c487b..acddbd08 100644 --- a/mbari_wec_all.yaml +++ b/mbari_wec_all.yaml @@ -12,14 +12,3 @@ repositories: type: git url: https://github.com/osrf/mbari_wec_gz version: main - # Must compile ros_gz from source because Humble + Garden is not an official combination - # freezing for release - ros_gz: - type: git - url: https://github.com/gazebosim/ros_gz - version: humble - # version: 7c62a1ce3cfb4eb3b54e1cfd092c9b63a9d5f255 - sdformat_urdf: - type: git - url: https://github.com/ros/sdformat_urdf - version: humble