From 1f13d97602b4d803d7a86cf3a3a353a5b2c88e67 Mon Sep 17 00:00:00 2001 From: Yovany Molina Date: Mon, 9 Oct 2023 16:37:35 -0400 Subject: [PATCH 1/7] (Last of the) Su23 documentation (#1096) * Added changes from recent testings - Changed the thruster ID values to correspond to the current thruster connection setup. - Changed FRV thruster direction from -1Z to +1Z. - Changed PID values for the sub. Values are still not ideal and will be adjusted over the next few testing sessions. - Changed the identifier for the USB to CAN board's USB to serial converter. - Changed tcp address for the depth sensor, imu, and dvl connection scripts to their ip addresses instead of their DNS names (there is an issue with the DNS server in the network box, or in the lab, or both). - Made changes to the sub8.urdf.xacro for gazebo to avoid URDF inertia warning. - Added bag_debugging_controller.launch file which is a launch file to record bags for debugging the PID controller on the sub. * Add documentation for bag_debugging_controller.launch * pre-commit and CI fixes...probably * Added documentation about PID controller - Added documentation page about PID controller containing information about the bag_debugging_controller.launch file and some tips for how to tune the PID controller. - Reverted subjugator_launch/readme.md changes to reflect moving to a new documentation page. - Modified adaptive controller values to remove commented out kd values. * Modify URDF fix to fix /mission_server crash - Another URDF xacro fix has been applied to the URDF xacro file using these ROS forum posts as reference: https://answers.ros.org/question/393006/urdf-link-not-properly-fixed-to-world/, https://answers.ros.org/question/192817/error-msg-the-root-link_base-has-an-inertia-specified-in-the-urdf-but-kdl/. NOTE: This is not a complete fix yet. I'm getting a tf republisher error that 'base_link' and 'map' do not have a connection with TF having 2+ unconnected trees. Additionally, gazebogui does not work since the /gzclient/set_physics_properties service is not advertised (even though /gazebo/set_physics_properties is). * Added documentation and changes made during summer Note that these are changes I made on my local PC that I'm getting around to submitting. - Added documentation for the nav tube including calibration for the IMU. - Added documentation for filling the watercooling loop (missing emptying loop and adding photos for clarification). - Made edits to testing procedures to reflect materials we ended up using at different points + reiteration of red battery tube cap. - Modified MOTD to reflect changes in local documentation. - Modified magnetic hardsoft compensation script for changes in matplotlib and numpy structure. * Remove trailing whitespace --------- Co-authored-by: Cameron Brown --- .../scripts/generate_config | 13 +-- SubjuGator/etc/motd | 9 ++ docs/subjugator/index.rst | 2 + docs/subjugator/nav_tube.rst | 98 +++++++++++++++++++ docs/subjugator/watercooling.rst | 70 +++++++++++++ docs/testingprocedures.md | 33 ++++--- 6 files changed, 203 insertions(+), 22 deletions(-) create mode 100644 SubjuGator/etc/motd create mode 100644 docs/subjugator/nav_tube.rst create mode 100644 docs/subjugator/watercooling.rst diff --git a/SubjuGator/drivers/magnetic_compensation/sub8_magnetic_hardsoft_compensation/scripts/generate_config b/SubjuGator/drivers/magnetic_compensation/sub8_magnetic_hardsoft_compensation/scripts/generate_config index f818bd613..4b65395af 100755 --- a/SubjuGator/drivers/magnetic_compensation/sub8_magnetic_hardsoft_compensation/scripts/generate_config +++ b/SubjuGator/drivers/magnetic_compensation/sub8_magnetic_hardsoft_compensation/scripts/generate_config @@ -9,6 +9,7 @@ import rosbag import roslib import scipy.linalg import yaml +from mpl_toolkits.mplot3d import Axes3D from tf import transformations roslib.load_manifest("magnetic_hardsoft_compensation") @@ -20,7 +21,7 @@ def normalized_matrix(m): def calculate_error(points): - radii = map(numpy.linalg.norm, points) + radii = list(map(numpy.linalg.norm, points)) error = numpy.std(radii) / numpy.mean(radii) return error @@ -47,7 +48,7 @@ def fit_ellipsoid(points): B = numpy.ones((points.shape[0], 1)) - X = numpy.linalg.lstsq(A, B)[0].flatten() + X = numpy.linalg.lstsq(A, B, rcond=-1)[0].flatten() if X[0] < 0: X = -X # make sure ka turns out positive definite @@ -150,7 +151,7 @@ if __name__ == "__main__": import matplotlib.pyplot as plt fig = plt.figure(figsize=(10, 10)) - ax = fig.add_subplot("111", projection="3d") + ax = Axes3D(fig) ax.scatter([0], [0], [0], s=100, c="r") ax.scatter(*zip(*points[::10, :])) axisEqual3D(ax) @@ -168,7 +169,7 @@ if __name__ == "__main__": import matplotlib.pyplot as plt fig = plt.figure(figsize=(10, 10)) - ax = fig.add_subplot("111", projection="3d") + ax = Axes3D(fig) ax.scatter([0], [0], [0], s=100, c="r") ax.scatter(*zip(*points[::10, :])) ax.scatter(*zip(*compensated[::10, :]), c="g") @@ -183,8 +184,8 @@ if __name__ == "__main__": print( yaml.dump( { - "scale": (map(float, x) for x in scale), - "shift": map(float, shift), + "scale": scale.tolist(), + "shift": shift.tolist(), }, ), ) diff --git a/SubjuGator/etc/motd b/SubjuGator/etc/motd new file mode 100644 index 000000000..bf6bb0855 --- /dev/null +++ b/SubjuGator/etc/motd @@ -0,0 +1,9 @@ +#-------#-------#-------#-------#-------#-------#-------#-------# + You have connected to SubjuGator 8! +#-------#-------#-------#-------#-------#-------#-------#-------# + +If you are testing the sub in the water (or are preparing to do so), please make sure to read the Subjugator Testing Procedures page on uf-mil.github.io for useful tips, advice, and checklists. + +We (the previous MIL members) will watch your testing session with great interest. + +Happy Testing! diff --git a/docs/subjugator/index.rst b/docs/subjugator/index.rst index 28566c2ac..7a9416713 100644 --- a/docs/subjugator/index.rst +++ b/docs/subjugator/index.rst @@ -16,6 +16,8 @@ SubjuGator 8 Enabling Cameras PID Controller + Nav Tube + Watercooling electrical diff --git a/docs/subjugator/nav_tube.rst b/docs/subjugator/nav_tube.rst new file mode 100644 index 000000000..0456994ec --- /dev/null +++ b/docs/subjugator/nav_tube.rst @@ -0,0 +1,98 @@ +======== +Nav Tube +======== + +One of the major components of SubjuGator 8 is the navigation (nav tube). This pressure vessel is located right below the main pressure vessel and contains all of our navigation sensors and equipment. The navigation computer located inside the vessel allows access to the data from these components through a direct ethernet connection. + +.. warning:: + + This system was originally used on SubjuGator 7 and it was ported over with little to no changes in hardware. This does mean that the system will need a major overhaul for continued use of SubjuGator 8. + +Navigation Computer +=================== + +The navigation computer consists of a Gumstix Overo Computer-on-Module that mounts to a carrier board. The carrier board contains headers for the Teledyne Dopper Velocity Logger (DVL) connector board, Analog Devices Inertial Measurement Unit (IMU), and the pressure sensor. At one point, the navigation computer was also connected to a GPS antenna. + +.. warning:: + + No documentation or PCB design files exist for the navigation computer carrier board and there are no more functioning spare boards. Additionally, only the newer GumStix Overo COM boards are available to purchase (with a lead time of roughly 1 year) which may not be compatible with the current system. Be very careful when working inside of the navigation tube. + +Troubleshooting The Nav Tube Connection +--------------------------------------- + +If you cannot ping the Navigation Computer (192.168.37.61), please ensure (in the following order) that: + +* You are pinging 192.168.37.61. +* The ethernet subconn cable has been connected between both pressure vessels. +* You restart the sub at least once. +* That the proper ethernet interface is configured in /etc/netplan YAML file. You may need to check ifconfig for the 'enpXs0' interface (where X is a whole number) if you have unplugged and replugged anything in the sub recently (especially the graphics card). Make sure to test the netplan with ``sudo netplan try`` so that you don't get locked out of the sub because of a bad configuration! +* The ethernet cables are properly connected inside the main pressure vessel. +* The ethernet cables and other cables are properly connected inside the Nav tube. +* The navigation computer is receiving power AND is turned on (green AND blue light on the GumStix). Make sure to be extra careful and vigilent when opening and handling the navigation computer. + +ADIS16400/16405-BMLZ IMU & Magnetometer +=========================================== + +The `ADIS16400-BMLZ `_ / `ADIS16405-BMLZ `_ is the device responsible for tracking our position and orientation in the water. Currently, there is an ADIS16400 IMU in the sub, but it previously used an ADIS16405. + +.. warning:: + + These components are obsolete! It may be difficult to find replacement parts in the future if SubjuGator 8 will see continued use... + +Calibrating the Magnetometer +---------------------------- + +The magnetometer inside of the ADIS16400/16405 measures the strength of the magnetic field at the orientation it faces. We use this data in conjunction with the IMU's gyroscopes and accelerometers to determine the orientation of the sub in the water. The process of calibrating the magnetometer is called magnetic hardsoft compensation and essentially changes how we bias the data it gives us. + +.. note:: + + Calibrating the magnetometer must be done in a pool. + +To calibrate the magnetometer you must first collect magnetometer data (``/imu/mag_raw``) to use for the calibration script. This can be done through the following: + +.. code-block:: bash + + $ roslaunch subjugator_launch sub8.launch + +or if you prefer to not launch the entire sub: + +.. code-block:: bash + + $ roslaunch subjugator_launch nav_box.launch imu:=true + +Then, in a separate terminal window, navigate to a known directory start recording the rosbag by typing: + +.. code-block:: bash + + $ rosbag record -O .bag /imu/mag_raw + +where is a substitute for whatever name you want to give to your bag (I recommend something memorable, like Frank or Penelope). This will record the bag data in the directory that the terminal window is in. + +When you have started recording the bag, have members who are in the water rotate the sub. Only the sub should move, not the members holding onto the sub. The calibration can be done in any order, but you must complete a full roll, pitch, and yaw rotation plus have a few minutes of data with all three occurring at the same time. Once you are done collecting data, kill the recording window using ``ctrl+c``. + +Next, we must run the calibration script with our data. This script is located in ``SubjuGator/drivers/magnetic_compensation/sub8_magnetic_hardsoft_compensation/scripts``. Type the following: + +.. code-block:: bash + + $ ./generate_config + +note that this is a python script, so + +.. code-block:: bash + + $ python3 generate_config + +is also valid. + +.. note:: + + If the script fails because of the ``fit_ellipsoid`` method and the points on the first figure are colinear or nearly colinear you may not have collected thorough enough data. The alternate possibility is a malfunctioning magnetometer. + +The output of the script should be a 3x3 matrix labeled ``scale`` and a length 3 vector labeled ``shift``. These values go into the ``scale`` and ``shift`` values located inside of ``subjugator_launch/launch/subsystems/nav_box.launch``. + +After running ``cm``, you will have (hopefully) successfully calibrated the magnetometer. Make sure to test the sub after calibration to see if the new configuration values are an improvement over the old ones. + +Important Links and Datasheets +============================== + +- `ADIS16400/ADIS16405 Datasheet `_ diff --git a/docs/subjugator/watercooling.rst b/docs/subjugator/watercooling.rst new file mode 100644 index 000000000..5344e68bf --- /dev/null +++ b/docs/subjugator/watercooling.rst @@ -0,0 +1,70 @@ +============ +Watercooling +============ + +SubjuGator 8's hardware requires a watercooling loop for the CPU, graphics card, and ESCs. + +Filling the Water cooling Loop +============================== + +.. note:: + + Filling the water cooling loop requires at least 2 people. + +Materials +--------- + +* Sub Shore Power Supply +* Sub battery tube cover +* Sub battery cables +* Large Funnel +* Small Funnel +* Stool or Chair +* Deionized Water w/ Biocide +* Vacuum Pump +* Extra water cooling connectors and tubing +* Water cooling reservoir +* Bucket + +.. note:: + + While deionized water with biocide is preferred for longevity, distilled water will work fine. You should not use purified water. Bonus points if the water is dyed orange :) + +No-Pump Procedure +----------------- + +These steps should be taken when there is no external pump to help with the filling process. + +.. warning:: + + Exercise caution during steps 8 and 9 as the sub will be powered on with a water hazard nearby. + +#. Move the main vessel onto the wooden platform and down to the floor. +#. Set up the environment as shown in the picture below. +#. Gravity feed the system by filling the reservoir with water and letting the bubbles come out naturally. Move on when no more bubbles come out. +#. Empty the reservoir until the water is below the "stove pipe" (metal tube inside the reservoir). +#. Blow into the tube exposed to air to force the water into the loop while extracting the air inside of the loop. Make sure to fill the reservoir until the water is below the "stove pipe" when there is an air gap inside of the water inlet tube. Move on when you cannot remove any more bubbles. +#. Attach the vacuum pump to the tube exposed to air and pump until the pressure reaches around 10 PSI. Pinch the outlet tube and break the vacuum to allow water to fill the low pressure spots. Repeat this step until at least a decent amount of water makes it past the pump. +#. With water at the ready, connect the sub to shore power and fill the reservoir with water (you do not have to worry about the "stove pipe"). +#. Wiggle the sub around while the pump is running to extract any trapped bubbles. + +Emptying the Water Cooling Loop +=============================== + +The water cooling loop should be emptied before the sub is shipped anywhere. Emptying the water cooling loop is easier than filling it up. + +.. note:: + + Emptying the water cooling loop requires at least 2 people. + +Materials +--------- + +* Vacuum pump +* Extra water cooling connectors and tubing +* Water cooling reservoir +* Bucket + + +Procedure +--------- diff --git a/docs/testingprocedures.md b/docs/testingprocedures.md index 2fcf81852..b1a6d4dc5 100644 --- a/docs/testingprocedures.md +++ b/docs/testingprocedures.md @@ -2,6 +2,8 @@ ## Before leaving +For best results, packing should be done at least one day before a testing session. This + ### Packing list * Power Strip * Table @@ -16,7 +18,6 @@ * 5/32 Allen Key * Duct tape and scissor * Buoyancy foams for the sub -* Allen Key for paintball tank * Pliers * Flat-head screwdriver * Kill wand @@ -27,22 +28,22 @@ * O'ring grease (Molykote 55) * Cable grease (Molykote 44) * Hot glue gun -* Zip ties +* Hot glue sticks +* Large and small zip ties * clippers -* Towels +* Towel(s) * [Sunscreen](https://www.youtube.com/watch?v=sTJ7AzBIJoI) - +* Tent (If going to Graham Pool or Florida Pool) +* Chairs (If going to Graham Pool) ### Software/Electrical Checklist -* Update and build code -* Verify all sensors output data -* Verify thrusters spin given command -* Verify kill (soft an hard) -* Grease all electrical connectors appropriately - +* Update (`git pull`) and build (`cm`) code. +* Verify all sensors output data. +* Verify that the correct thrusters spin given the appropriate command. +* Verify kill (soft and hard). +* Grease all electrical connectors appropriately. ## At testing site - * Get wall power to powerstrip. * Setup and connect to Network Box. * Roll tether and connect it to network box. **(DO NOT USE POE)** @@ -51,11 +52,11 @@ * SSH into sub. * Start tmux, write code. * Grease O-rings with Molykote 55 every time a pressure vessel is closed. -* Make sure ALL pneumatic tubes are inserted correctly. **(DO NOT FLOOD THE VALVE BOX)** -* Make sure all holes to paintball tank are sealed correctly. **(THIS WILL ALSO RESULT IN FLOODING IF NOT DONE)** +* * **ENSURE THAT THE RED PRESSURE RELIEF CAP ON THE BATTERY TUBE HAS BEEN SCREWED IN PLACE AFTER CHANGING BATTERIES** * Person getting into the pool must do backflip. -* Deploy sub. (check for bubbles, make sure buoyancy is correct) +* Deploy sub. (check for bubbles, make sure buoyancy is correct). * Verify odometry. -What happens when the valve box isn't closed: -![What happens when the valve box isn't closed.](/flooded_valve_box.jpg) +### Troubleshooting + +- :ref:`Troubleshooting The Nav Tube Connection` From 8765ea2d92d4817c3e539a3b78eb483308b5342c Mon Sep 17 00:00:00 2001 From: Keerat Kohli <100006952+KeeratKK@users.noreply.github.com> Date: Tue, 10 Oct 2023 17:59:10 -0400 Subject: [PATCH 2/7] Removed the assignee and deadline fields from the github issue template (#1098) Co-authored-by: Keerat Kohli --- .github/ISSUE_TEMPLATE/navigator.yaml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/navigator.yaml b/.github/ISSUE_TEMPLATE/navigator.yaml index 8e528b706..a3617fae6 100644 --- a/.github/ISSUE_TEMPLATE/navigator.yaml +++ b/.github/ISSUE_TEMPLATE/navigator.yaml @@ -7,26 +7,6 @@ body: attributes: value: | Hey, thanks for taking the time to add this software issue! - - type: input - id: assignee - attributes: - label: Assignee - description: > - Does this issue need to be completed by a specific person on the team? - If so, mention them below. - placeholder: ex. @torvalds is already working on this task! - validations: - required: false - - type: input - id: deadline - attributes: - label: Deadline - description: > - Does this task need a deadline? _If this task is related to a competition, - it should have a deadline._ - placeholder: ex. 2023-12-25 - validations: - required: false - type: textarea id: description attributes: From 70f0f360ba3f55ded3b870078e48bac4a6da9462 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 22:08:38 +0000 Subject: [PATCH 3/7] Update pre-commit hooks to latest versions (#1087) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update pre-commit hooks to latest versions updates: - [github.com/pre-commit/mirrors-clang-format: v14.0.6 → v15.0.7](https://github.com/pre-commit/mirrors-clang-format/compare/v14.0.6...v15.0.7) - [github.com/charliermarsh/ruff-pre-commit: v0.0.247 → v0.0.254](https://github.com/charliermarsh/ruff-pre-commit/compare/v0.0.247...v0.0.254) * Run apt-get update before upgrade (#1001) The package index from the runner image will go out of date and dependencies may be unresolveable. If upgrade is run before update the index can be stale for the upgrade step. * Remove clang-format upgrade because of lack of aarch64 wheels for Linux * Update pre-commit hooks to latest versions updates: - [github.com/adrienverge/yamllint.git: v1.29.0 → v1.30.0](https://github.com/adrienverge/yamllint.git/compare/v1.29.0...v1.30.0) - [github.com/psf/black: 23.1.0 → 23.3.0](https://github.com/psf/black/compare/23.1.0...23.3.0) - [github.com/pre-commit/mirrors-clang-format: v14.0.6 → v16.0.0](https://github.com/pre-commit/mirrors-clang-format/compare/v14.0.6...v16.0.0) - [github.com/PyCQA/autoflake: v2.0.1 → v2.0.2](https://github.com/PyCQA/autoflake/compare/v2.0.1...v2.0.2) - [github.com/scop/pre-commit-shfmt: v3.6.0-1 → v3.6.0-2](https://github.com/scop/pre-commit-shfmt/compare/v3.6.0-1...v3.6.0-2) - [github.com/charliermarsh/ruff-pre-commit: v0.0.254 → v0.0.260](https://github.com/charliermarsh/ruff-pre-commit/compare/v0.0.254...v0.0.260) - [github.com/codespell-project/codespell: v2.2.2 → v2.2.4](https://github.com/codespell-project/codespell/compare/v2.2.2...v2.2.4) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix spelling mistakes for codespell * Update pre-commit hooks to latest versions updates: - [github.com/adrienverge/yamllint.git: v1.30.0 → v1.31.0](https://github.com/adrienverge/yamllint.git/compare/v1.30.0...v1.31.0) - [github.com/pre-commit/mirrors-clang-format: v16.0.0 → v16.0.2](https://github.com/pre-commit/mirrors-clang-format/compare/v16.0.0...v16.0.2) - [github.com/PyCQA/autoflake: v2.0.2 → v2.1.1](https://github.com/PyCQA/autoflake/compare/v2.0.2...v2.1.1) - [github.com/charliermarsh/ruff-pre-commit: v0.0.260 → v0.0.263](https://github.com/charliermarsh/ruff-pre-commit/compare/v0.0.260...v0.0.263) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update files to match new pre-commit updates * Update pre-commit hooks to latest versions updates: - [github.com/psf/black: 23.3.0 → 23.7.0](https://github.com/psf/black/compare/23.3.0...23.7.0) - [github.com/pre-commit/mirrors-clang-format: v16.0.4 → v16.0.6](https://github.com/pre-commit/mirrors-clang-format/compare/v16.0.4...v16.0.6) - [github.com/PyCQA/autoflake: v2.1.1 → v2.2.0](https://github.com/PyCQA/autoflake/compare/v2.1.1...v2.2.0) - [github.com/scop/pre-commit-shfmt: v3.6.0-2 → v3.7.0-1](https://github.com/scop/pre-commit-shfmt/compare/v3.6.0-2...v3.7.0-1) - https://github.com/charliermarsh/ruff-pre-commit → https://github.com/astral-sh/ruff-pre-commit - [github.com/astral-sh/ruff-pre-commit: v0.0.270 → v0.0.282](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.270...v0.0.282) - [github.com/codespell-project/codespell: v2.2.4 → v2.2.5](https://github.com/codespell-project/codespell/compare/v2.2.4...v2.2.5) * Update with pre-commit changes * Update pre-commit hooks to latest versions updates: - [github.com/psf/black: 23.7.0 → 23.9.1](https://github.com/psf/black/compare/23.7.0...23.9.1) - [github.com/shellcheck-py/shellcheck-py: v0.9.0.5 → v0.9.0.6](https://github.com/shellcheck-py/shellcheck-py/compare/v0.9.0.5...v0.9.0.6) - [github.com/astral-sh/ruff-pre-commit: v0.0.287 → v0.0.292](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.287...v0.0.292) --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jarrod Sanders <50600614+kawaiiPlat@users.noreply.github.com> Co-authored-by: Cameron Brown --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5db81ae41..7751457af 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: hooks: - id: yamllint - repo: https://github.com/psf/black - rev: 23.7.0 + rev: 23.9.1 hooks: - id: black - repo: https://github.com/pre-commit/mirrors-clang-format @@ -28,7 +28,7 @@ repos: - id: autoflake args: [--remove-all-unused-imports, --ignore-init-module-imports] - repo: https://github.com/shellcheck-py/shellcheck-py - rev: v0.9.0.5 + rev: v0.9.0.6 hooks: - id: shellcheck exclude: ^docker|deprecated|NaviGator/simulation/VRX @@ -40,7 +40,7 @@ repos: exclude: ^docker|deprecated|NaviGator/simulation/VRX - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: 'v0.0.287' + rev: 'v0.0.292' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 36c6c50e9f50a823f7f87e2929622d4fbfc66b87 Mon Sep 17 00:00:00 2001 From: cameron brown <52760912+cbrxyz@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:11:50 -0400 Subject: [PATCH 4/7] Limit TF_REPEATED_DATA messages by checking for repeated transforms, also remove dummy world join to rejoin map + base_link trees in simulation (#1097) --- .../simulation/subjugator_gazebo/urdf/sub8.urdf.xacro | 7 ------- mil_common/gnc/odometry_utils/src/odometry_to_tf.cpp | 8 ++++++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/SubjuGator/simulation/subjugator_gazebo/urdf/sub8.urdf.xacro b/SubjuGator/simulation/subjugator_gazebo/urdf/sub8.urdf.xacro index 9290884dd..3f4517335 100644 --- a/SubjuGator/simulation/subjugator_gazebo/urdf/sub8.urdf.xacro +++ b/SubjuGator/simulation/subjugator_gazebo/urdf/sub8.urdf.xacro @@ -11,8 +11,6 @@ - - @@ -33,11 +31,6 @@ - - - - - diff --git a/mil_common/gnc/odometry_utils/src/odometry_to_tf.cpp b/mil_common/gnc/odometry_utils/src/odometry_to_tf.cpp index d2ec5a6bf..953f0fcbd 100644 --- a/mil_common/gnc/odometry_utils/src/odometry_to_tf.cpp +++ b/mil_common/gnc/odometry_utils/src/odometry_to_tf.cpp @@ -4,7 +4,9 @@ #include #include +#include #include +#include namespace odometry_utils { @@ -13,11 +15,17 @@ class odometry_to_tf : public nodelet::Nodelet private: ros::Subscriber odom_sub; tf::TransformBroadcaster tf_br; + std::map _last_tf_stamps; void handle_odom(const nav_msgs::Odometry::ConstPtr& msg) { tf::Transform transform; poseMsgToTF(msg->pose.pose, transform); + if (_last_tf_stamps.count(msg->header.frame_id) && _last_tf_stamps[msg->header.frame_id] <= msg->header.stamp) + { + return; + } + _last_tf_stamps[msg->header.frame_id] = msg->header.stamp; tf::StampedTransform stamped_transform(transform, msg->header.stamp, msg->header.frame_id, msg->child_frame_id); tf_br.sendTransform(stamped_transform); } From a2ff9eca5e361e25ae09398be7bae96b0febba0a Mon Sep 17 00:00:00 2001 From: cameron brown <52760912+cbrxyz@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:13:04 -0400 Subject: [PATCH 5/7] Small VRX 2023 changes (#1095) * Fix small axros bug, move vrx classifier to start first in launch file, fix heisenbug in mission runner * send_feedback should convert all input to string --- .../launch/vrx/vrx_master.launch | 2 +- .../navigator_missions/vrx_missions/vrx.py | 144 +++++++++--------- mil_common/axros | 2 +- .../mil_missions_core/base_mission.py | 1 + mil_common/mil_missions/nodes/mission_server | 4 + 5 files changed, 78 insertions(+), 75 deletions(-) diff --git a/NaviGator/mission_control/navigator_launch/launch/vrx/vrx_master.launch b/NaviGator/mission_control/navigator_launch/launch/vrx/vrx_master.launch index 944df5bfa..377f824de 100644 --- a/NaviGator/mission_control/navigator_launch/launch/vrx/vrx_master.launch +++ b/NaviGator/mission_control/navigator_launch/launch/vrx/vrx_master.launch @@ -7,6 +7,7 @@ + @@ -30,5 +31,4 @@ - diff --git a/NaviGator/mission_control/navigator_missions/vrx_missions/vrx.py b/NaviGator/mission_control/navigator_missions/vrx_missions/vrx.py index d629df644..91514c01d 100644 --- a/NaviGator/mission_control/navigator_missions/vrx_missions/vrx.py +++ b/NaviGator/mission_control/navigator_missions/vrx_missions/vrx.py @@ -29,145 +29,143 @@ class Vrx(NaviGatorMission): nh: NodeHandle - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - @staticmethod - async def init(): - if hasattr(Vrx, "_vrx_init"): + @classmethod + async def setup(cls): + if hasattr(cls, "_cls_init"): return - Vrx.from_lla = Vrx.nh.get_service_client("/fromLL", FromLL) - Vrx.to_lla = Vrx.nh.get_service_client("/toLL", ToLL) - Vrx.task_info_sub = Vrx.nh.subscribe("/vrx/task/info", Task) - await Vrx.task_info_sub.setup() - Vrx.scan_dock_color_sequence = Vrx.nh.get_service_client( + cls.from_lla = cls.nh.get_service_client("/fromLL", FromLL) + cls.to_lla = cls.nh.get_service_client("/toLL", ToLL) + cls.task_info_sub = cls.nh.subscribe("/vrx/task/info", Task) + cls.scan_dock_color_sequence = cls.nh.get_service_client( "/vrx/scan_dock_deliver/color_sequence", ColorSequence, ) - Vrx.fire_ball = Vrx.nh.advertise("/wamv/shooters/ball_shooter/fire", Empty) - Vrx.station_keep_goal = Vrx.nh.subscribe( + cls.fire_ball = cls.nh.advertise("/wamv/shooters/ball_shooter/fire", Empty) + cls.station_keep_goal = cls.nh.subscribe( "/vrx/station_keeping/goal", GeoPoseStamped, ) - Vrx.wayfinding_path_sub = Vrx.nh.subscribe("/vrx/wayfinding/waypoints", GeoPath) - Vrx.station_keeping_pose_error = Vrx.nh.subscribe( + cls.wayfinding_path_sub = cls.nh.subscribe("/vrx/wayfinding/waypoints", GeoPath) + cls.station_keeping_pose_error = cls.nh.subscribe( "/vrx/station_keeping/pose_error", Float64, ) - Vrx.station_keeping_rms_error = Vrx.nh.subscribe( + cls.station_keeping_rms_error = cls.nh.subscribe( "/vrx/station_keeping/rms_error", Float64, ) - Vrx.wayfinding_min_errors = Vrx.nh.subscribe( + cls.wayfinding_min_errors = cls.nh.subscribe( "/vrx/wayfinding/min_errors", Float64MultiArray, ) - Vrx.wayfinding_mean_error = Vrx.nh.subscribe( + cls.wayfinding_mean_error = cls.nh.subscribe( "/vrx/wayfinding/mean_error", Float64, ) - Vrx.perception_landmark = Vrx.nh.advertise( + cls.perception_landmark = cls.nh.advertise( "/vrx/perception/landmark", GeoPoseStamped, ) await asyncio.gather( - Vrx.fire_ball.setup(), - Vrx.station_keep_goal.setup(), - Vrx.wayfinding_path_sub.setup(), - Vrx.station_keeping_pose_error.setup(), - Vrx.station_keeping_rms_error.setup(), - Vrx.wayfinding_min_errors.setup(), - Vrx.wayfinding_mean_error.setup(), - Vrx.perception_landmark.setup(), + cls.task_info_sub.setup(), + cls.fire_ball.setup(), + cls.station_keep_goal.setup(), + cls.wayfinding_path_sub.setup(), + cls.station_keeping_pose_error.setup(), + cls.station_keeping_rms_error.setup(), + cls.wayfinding_min_errors.setup(), + cls.wayfinding_mean_error.setup(), + cls.perception_landmark.setup(), ) - Vrx.animal_landmarks = Vrx.nh.subscribe("/vrx/wildlife/animals/poses", GeoPath) - Vrx.beacon_landmark = Vrx.nh.get_service_client("beaconLocator", AcousticBeacon) - Vrx.circle_animal = Vrx.nh.get_service_client("/choose_animal", ChooseAnimal) - Vrx.set_long_waypoint = Vrx.nh.get_service_client( + cls.animal_landmarks = cls.nh.subscribe("/vrx/wildlife/animals/poses", GeoPath) + cls.beacon_landmark = cls.nh.get_service_client("beaconLocator", AcousticBeacon) + cls.circle_animal = cls.nh.get_service_client("/choose_animal", ChooseAnimal) + cls.set_long_waypoint = cls.nh.get_service_client( "/set_long_waypoint", MoveToWaypoint, ) - Vrx.yolo_objects = Vrx.nh.subscribe("/yolov7/detections", Detection2DArray) - Vrx.tf_listener = axros_tf.TransformListener(Vrx.nh) - await Vrx.tf_listener.setup() - Vrx.database_response = Vrx.nh.get_service_client( + cls.yolo_objects = cls.nh.subscribe("/yolov7/detections", Detection2DArray) + cls.tf_listener = axros_tf.TransformListener(cls.nh) + await cls.tf_listener.setup() + cls.database_response = cls.nh.get_service_client( "/database/requests", ObjectDBQuery, ) - Vrx.get_two_closest_cones = Vrx.nh.get_service_client( + cls.get_two_closest_cones = cls.nh.get_service_client( "/get_two_closest_cones", TwoClosestCones, ) await asyncio.gather( - Vrx.animal_landmarks.setup(), - Vrx.yolo_objects.setup(), + cls.animal_landmarks.setup(), + cls.yolo_objects.setup(), ) - Vrx.pcodar_reset = Vrx.nh.get_service_client("/pcodar/reset", Trigger) + cls.pcodar_reset = cls.nh.get_service_client("/pcodar/reset", Trigger) - Vrx.front_left_camera_info_sub = None - Vrx.front_left_camera_sub = None - Vrx.front_right_camera_info_sub = None - Vrx.front_right_camera_sub = None + cls.front_left_camera_info_sub = None + cls.front_left_camera_sub = None + cls.front_right_camera_info_sub = None + cls.front_right_camera_sub = None - Vrx._vrx_init = True + cls._cls_init = True - @staticmethod - async def shutdown(): + @classmethod + async def shutdown(cls): + return await asyncio.gather( - Vrx.task_info_sub.shutdown(), - Vrx.animal_landmarks.shutdown(), - Vrx.yolo_objects.shutdown(), - Vrx.fire_ball.shutdown(), - Vrx.station_keep_goal.shutdown(), - Vrx.wayfinding_path_sub.shutdown(), - Vrx.station_keeping_pose_error.shutdown(), - Vrx.station_keeping_rms_error.shutdown(), - Vrx.wayfinding_min_errors.shutdown(), - Vrx.wayfinding_mean_error.shutdown(), - Vrx.perception_landmark.shutdown(), + cls.task_info_sub.shutdown(), + cls.animal_landmarks.shutdown(), + cls.yolo_objects.shutdown(), + cls.fire_ball.shutdown(), + cls.station_keep_goal.shutdown(), + cls.wayfinding_path_sub.shutdown(), + cls.station_keeping_pose_error.shutdown(), + cls.station_keeping_rms_error.shutdown(), + cls.wayfinding_min_errors.shutdown(), + cls.wayfinding_mean_error.shutdown(), + cls.perception_landmark.shutdown(), ) def cleanup(self): pass - @staticmethod - async def init_front_left_camera(): - if Vrx.front_left_camera_sub is None: - Vrx.front_left_camera_sub = Vrx.nh.subscribe( + @classmethod + async def init_front_left_camera(cls): + if cls.front_left_camera_sub is None: + cls.front_left_camera_sub = cls.nh.subscribe( "/wamv/sensors/cameras/front_left_camera/image_raw", Image, ) - if Vrx.front_left_camera_info_sub is None: - Vrx.front_left_camera_info_sub = Vrx.nh.subscribe( + if cls.front_left_camera_info_sub is None: + cls.front_left_camera_info_sub = cls.nh.subscribe( "/wamv/sensors/cameras/front_left_camera/camera_info", CameraInfo, ) await asyncio.gather( - Vrx.front_left_camera_sub.setup(), - Vrx.front_left_camera_info_sub.setup(), + cls.front_left_camera_sub.setup(), + cls.front_left_camera_info_sub.setup(), ) - @staticmethod - async def init_front_right_camera(): - if Vrx.front_right_camera_sub is None: - Vrx.front_right_camera_sub = Vrx.nh.subscribe( + @classmethod + async def init_front_right_camera(cls): + if cls.front_right_camera_sub is None: + cls.front_right_camera_sub = cls.nh.subscribe( "/wamv/sensors/cameras/front_right_camera/image_raw", Image, ) - if Vrx.front_right_camera_info_sub is None: - Vrx.front_right_camera_info_sub = Vrx.nh.subscribe( + if cls.front_right_camera_info_sub is None: + cls.front_right_camera_info_sub = cls.nh.subscribe( "/wamv/sensors/cameras/front_right_camera/camera_info", CameraInfo, ) await asyncio.gather( - Vrx.front_right_camera_sub.setup(), - Vrx.front_right_camera_info_sub.setup(), + cls.front_right_camera_sub.setup(), + cls.front_right_camera_info_sub.setup(), ) async def geo_pose_to_enu_pose(self, geo): diff --git a/mil_common/axros b/mil_common/axros index 1b0399935..a4951d333 160000 --- a/mil_common/axros +++ b/mil_common/axros @@ -1 +1 @@ -Subproject commit 1b03999351fb5a61b202ff125f493229c2a1676b +Subproject commit a4951d33356c349856532ddef5c97c6ec6810c28 diff --git a/mil_common/mil_missions/mil_missions_core/base_mission.py b/mil_common/mil_missions/mil_missions_core/base_mission.py index bc41dc62c..e6e5e01df 100644 --- a/mil_common/mil_missions/mil_missions_core/base_mission.py +++ b/mil_common/mil_missions/mil_missions_core/base_mission.py @@ -121,6 +121,7 @@ def send_feedback(self, message: str) -> None: mission is a child mission, it will call the send_feedback_child of its parent, allowing missions to choose how to use the feedback from its children. """ + message = str(message) if self.parent: self.parent.send_feedback_child(message, self) else: diff --git a/mil_common/mil_missions/nodes/mission_server b/mil_common/mil_missions/nodes/mission_server index 3548d0b58..0009b8b8e 100755 --- a/mil_common/mil_missions/nodes/mission_server +++ b/mil_common/mil_missions/nodes/mission_server @@ -29,8 +29,10 @@ class MissionRunner: missions_loaded: bool base_mission: type[BaseMission] missions: dict[str, type[BaseMission]] + _running_tasks: set[asyncio.Task] def __init__(self): + self._running_tasks = set() pass async def init(self): @@ -213,6 +215,7 @@ class MissionRunner: self.mission = self.missions[goal.mission]() self.mission_future = asyncio.create_task(self.run_with_callback(parameters)) self.mission_future.add_done_callback(self.mission_finished_cb) + self._running_tasks.add(self.mission_future) async def run_with_callback(self, parameters): try: @@ -242,6 +245,7 @@ class MissionRunner: mission, or raises an exception. Publishes the correct result to the action clients. """ result = DoMissionResult() + self._running_tasks.remove(task) try: task_result = task.result() From 0a606c4e253e63e76030c621af6d4ef673a84153 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Oct 2023 18:34:17 -0400 Subject: [PATCH 6/7] Bump pillow from 9.3.0 to 10.0.1 (#1089) Bumps [pillow](https://github.com/python-pillow/Pillow) from 9.3.0 to 10.0.1. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/9.3.0...10.0.1) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: cameron brown <52760912+cbrxyz@users.noreply.github.com> --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 90237fb22..88d330b91 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ scipy==1.10.0 scikit-learn==1.1.1 # Computer Vision -Pillow==9.3.0 +Pillow==10.0.1 # File Handling PyYAML==6.0 From e2c479cb52783f3e4709d529b0e6d70328e25c9b Mon Sep 17 00:00:00 2001 From: cameron brown <52760912+cbrxyz@users.noreply.github.com> Date: Tue, 24 Oct 2023 16:45:57 -0400 Subject: [PATCH 7/7] Fix iso links in getting started docs (#1099) --- docs/software/getting_started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/software/getting_started.md b/docs/software/getting_started.md index 6e94e1653..1215b276e 100644 --- a/docs/software/getting_started.md +++ b/docs/software/getting_started.md @@ -63,8 +63,8 @@ methods. | Architecture | URL | | ------------ | --- | -| AMD64 (most Windows computers, Intel-based Mac computers) | [focal-desktop-amd64.iso](https://cdimage.ubuntu.com/focal/daily-live/current/focal-desktop-amd64.iso) | -| ARM64 (Apple Silicon Mac computers) | [focal-desktop-arm64.iso](https://cdimage.ubuntu.com/focal/daily-live/current/focal-desktop-arm64.iso) | +| AMD64 (most Windows computers, Intel-based Mac computers) | [focal-desktop-amd64.iso](https://releases.ubuntu.com/focal/ubuntu-20.04.6-desktop-amd64.iso) | +| ARM64 (Apple Silicon Mac computers) | Unfortunately, Ubuntu 20.04 no longer has an ARM-compatible ISO. While we are working on finding/building a new iso image, you may not be able to install. | The following subsections cover various installation methods. Please choose the installation option that best meets your use case. If you're not sure what the