From 1f13d97602b4d803d7a86cf3a3a353a5b2c88e67 Mon Sep 17 00:00:00 2001 From: Yovany Molina Date: Mon, 9 Oct 2023 16:37:35 -0400 Subject: [PATCH 01/25] (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 02/25] 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 03/25] 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 04/25] 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 05/25] 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 06/25] 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 07/25] 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 From b3ca7c49a03fa0b36321e7f69653938a078b7dee Mon Sep 17 00:00:00 2001 From: Daniel Parra <74571960+DaniParr@users.noreply.github.com> Date: Mon, 6 Nov 2023 14:20:58 -0500 Subject: [PATCH 08/25] Wayfinding optimization (#1101) * Removed IndyAV file * Reduced error by 50 percent * reformatted file --- .../vrx_missions/vrx_wayfinding_2.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/NaviGator/mission_control/navigator_missions/vrx_missions/vrx_wayfinding_2.py b/NaviGator/mission_control/navigator_missions/vrx_missions/vrx_wayfinding_2.py index 60496d0b8..966f38be0 100644 --- a/NaviGator/mission_control/navigator_missions/vrx_missions/vrx_wayfinding_2.py +++ b/NaviGator/mission_control/navigator_missions/vrx_missions/vrx_wayfinding_2.py @@ -5,6 +5,7 @@ from .vrx import Vrx ___author___ = "Alex Perez" +# Optimized by Daniel Parra class VrxWayfinding2(Vrx): @@ -42,12 +43,18 @@ async def run(self, parameters): poses = poses[:start_pose_index] path = path[1:] - # self.send_feedback('Sorted poses' + str(poses)) await self.wait_for_task_such_that(lambda task: task.state in ["running"]) # do movements for index in path: self.send_feedback(f"Going to {poses[index]}") - # Go to goal + P = 0.85 + part_way_point = [x * P for x in poses[index][0][:-1]] + part_way_point.append(poses[index][0][-1]) + self.send_feedback( + f"\nPartway:\n{part_way_point}\nEndPoint:\n{poses[index][0]}", + ) + + await self.send_trajectory_without_path([part_way_point, poses[index][1]]) await self.send_trajectory_without_path(poses[index]) From 0f3d837a05d28c7d848b4e73c90a99088d3f8949 Mon Sep 17 00:00:00 2001 From: Mrinall Umasudhan Date: Thu, 9 Nov 2023 23:44:00 -0500 Subject: [PATCH 09/25] Update test_packets_sub9.py (#1100) * Update test_packets_sub9.py * Update test_packets_sub9.py * Reformatted sub9 usb_to_can test files with black --------- Co-authored-by: Cameron Brown --- .../drivers/mil_usb_to_can/test/test_packets_sub9.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mil_common/drivers/mil_usb_to_can/test/test_packets_sub9.py b/mil_common/drivers/mil_usb_to_can/test/test_packets_sub9.py index 01c1dc47a..c58a8c32c 100755 --- a/mil_common/drivers/mil_usb_to_can/test/test_packets_sub9.py +++ b/mil_common/drivers/mil_usb_to_can/test/test_packets_sub9.py @@ -8,7 +8,7 @@ @dataclass -class TestPacket(Packet, msg_id=0x47, subclass_id=0x44, payload_format="BHf"): +class TestPacket(Packet, msg_id=0x47, subclass_id=0x44, payload_format="?Hd"): example_bool: bool example_int: int example_float: float @@ -23,7 +23,7 @@ def test_simple_packet(self): packet = TestPacket(False, 42, 3.14) self.assertEqual(packet.msg_id, 0x47) self.assertEqual(packet.subclass_id, 0x44) - self.assertEqual(packet.payload_format, "BHf") + self.assertEqual(packet.payload_format, "?Hd") self.assertEqual(packet.example_bool, False) self.assertEqual(packet.example_int, 42) self.assertEqual(packet.example_float, 3.14) @@ -36,6 +36,13 @@ def test_assembled_packet(self): self.assertEqual(assembled[2], packet.msg_id) self.assertEqual(assembled[3], packet.subclass_id) + def test_format(self): + packet = TestPacket(False, 42, 3.14) + self.assertEqual( + TestPacket.from_bytes(TestPacket.__bytes__(packet)), + packet, + ) + def test_comparisons(self): packet = TestPacket(False, 42, 3.14) packet_two = TestPacket(False, 42, 3.14) From 27734544fa18a8478093a70342d5bb53156af8ec Mon Sep 17 00:00:00 2001 From: cameron brown <52760912+cbrxyz@users.noreply.github.com> Date: Sat, 9 Dec 2023 10:33:11 -0800 Subject: [PATCH 10/25] Add param to reduce TF warnings in VRX (#1107) --- .../navigator_launch/launch/vrx/vrx_tf.launch | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/NaviGator/mission_control/navigator_launch/launch/vrx/vrx_tf.launch b/NaviGator/mission_control/navigator_launch/launch/vrx/vrx_tf.launch index f46bcca90..a9bdd66e8 100644 --- a/NaviGator/mission_control/navigator_launch/launch/vrx/vrx_tf.launch +++ b/NaviGator/mission_control/navigator_launch/launch/vrx/vrx_tf.launch @@ -1,5 +1,8 @@ + + true + @@ -11,9 +14,10 @@ - - - - + + + + + From 1b57fc4c22609ac00039224771b2c4a673bc7750 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 11:59:30 -0500 Subject: [PATCH 11/25] Update pre-commit hooks to latest versions (#1103) 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) * Update pre-commit hooks to latest versions updates: - [github.com/psf/black: 23.9.1 → 23.10.1](https://github.com/psf/black/compare/23.9.1...23.10.1) - [github.com/pre-commit/mirrors-clang-format: v16.0.6 → v17.0.4](https://github.com/pre-commit/mirrors-clang-format/compare/v16.0.6...v17.0.4) - [github.com/astral-sh/ruff-pre-commit: v0.0.292 → v0.1.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.292...v0.1.4) - [github.com/codespell-project/codespell: v2.2.5 → v2.2.6](https://github.com/codespell-project/codespell/compare/v2.2.5...v2.2.6) - [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.5.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v4.5.0) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix spelling mistakes for codespell * Fix too short underline --------- 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 --- .github/workflows/gh_pages.yaml | 2 +- .pre-commit-config.yaml | 15 ++++++++------- .../nodes/path_planner.py | 2 +- .../navigator_kill_board/constants.py | 1 + .../battery_voltage.py | 6 +++--- .../navigator_alarm_handlers/odom_kill.py | 4 +--- .../launch/mission_params.yaml | 8 ++++---- .../navigator_missions/constant_velocity.py | 2 +- .../demonstrate_navigation.py | 4 ++-- .../navigator_missions/detect_deliver_2016.py | 4 +--- .../navigator_missions/move.py | 2 +- .../navigator_missions/pose_editor.py | 4 +--- .../navigator_missions/vrx_missions/dock.py | 2 +- .../rviz_satellite/src/aerialmap_display.cpp | 2 +- NaviGator/scripts/bash_aliases.sh | 2 +- .../utils/navigator_msgs/srv/GetDockBays.srv | 2 +- .../navigator_tools/nodes/navigator_status_tui | 6 ++---- .../nodes/navigator_emergency.py | 2 +- NaviGator/utils/voltage_gui/src/voltage_gui.py | 2 +- .../config/passive_sonar.yaml | 2 +- .../launch/subsystems/nav_box.launch | 8 ++++---- .../scripts/generate_config | 8 +++++--- .../subjugator_perception/nodes/dice_detect.py | 2 +- .../nodes/hsv_calibration.py | 16 ++++++++++------ .../nodes/orange_rectangle_finder.py | 2 +- .../HOG/HOG_SVM_trainer.py | 4 +--- .../machine_learning/boost_auto.py | 5 +++-- .../subjugator_vision_tools/marker_occ_grid.py | 3 +-- .../subjugator_vision_tools/rviz.py | 1 - .../visual_threshold_tools.py | 1 - .../test/test_path_marker.py | 1 - .../diagnostics/gazebo_tests/common.py | 1 - .../shaders/shader_manager.py | 1 - .../subjugator_sim_tools/shaders/shaders.py | 1 - .../subjugator_sim_tools/widgets/sub.py | 1 - .../scripts/self_check.py | 1 - docs/design/passive_sonar/passive_sonar.rst | 4 ++-- docs/electrical/onboarding.md | 2 +- docs/extensions/attributetable.py | 1 + docs/extensions/builder.py | 1 + .../planning/indyav_path/path_recorder.rst | 2 +- docs/navigator/lessons22.md | 2 +- docs/software/adding_documentation.md | 2 +- docs/software/getting_started.md | 2 +- docs/software/help.md | 2 +- docs/software/noetic_migration.md | 2 +- mil_common/axros | 2 +- mil_common/drivers/mil_passive_sonar/README.md | 2 +- .../mil_passive_sonar/scripts/triggering.py | 4 ++-- .../nodes/pneumatic_actuator_node | 2 +- .../mil_usb_to_can/sub8/utils.py | 12 ++++-------- .../mil_usb_to_can/sub9/sub9_driver.py | 11 +++++------ .../gnc/rawgps_common/src/rawgps_common/gps.py | 18 +++++++++--------- .../mil_missions/mil_missions_core/__init__.py | 1 + .../include/mil_vision_lib/cv_tools.hpp | 2 +- .../mil_vision_tools/color_classifier.py | 2 +- .../mil_vision_tools/shape_finder.py | 14 +++++++------- .../mil_vision/mil_vision_tools/vision_node.py | 2 +- .../ros_tools/on_the_fly_thresholder.py | 8 +++++--- .../mil_vision_lib/colorizer/pcd_colorizer.cpp | 2 +- mil_common/ros_alarms/nodes/alarm_server.py | 6 +++--- mil_common/ros_alarms/ros_alarms/__init__.py | 1 + .../ros_alarms/test/roscpp/listener_test.cpp | 2 +- .../ros_alarms/test/rospy/python_tests.py | 4 ++-- .../utils/mil_tools/mil_misc_tools/download.py | 1 + .../utils/mil_tools/mil_ros_tools/cv_debug.py | 1 + .../mil_tools/mil_ros_tools/image_helpers.py | 2 +- .../mil_tools/mil_ros_tools/init_helpers.py | 1 + .../mil_tools/mil_ros_tools/label_me_bag.py | 8 ++++---- .../utils/mil_tools/test/test_ros_tools.py | 5 +---- ruff.toml | 1 + 71 files changed, 128 insertions(+), 136 deletions(-) diff --git a/.github/workflows/gh_pages.yaml b/.github/workflows/gh_pages.yaml index b54342c28..39b70c62a 100644 --- a/.github/workflows/gh_pages.yaml +++ b/.github/workflows/gh_pages.yaml @@ -20,7 +20,7 @@ jobs: # Wait for the CI to finish so we can download the docs artifact - name: Wait for CI - uses: lewagon/wait-on-check-action@v1.0.0 + uses: lewagon/wait-on-check-action@v1.3.3 if: github.event.action != 'closed' with: ref: ${{ github.event.pull_request.head.ref }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7751457af..79a11871a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,15 +11,15 @@ ci: repos: - repo: https://github.com/adrienverge/yamllint.git - rev: v1.32.0 + rev: v1.33.0 hooks: - id: yamllint - repo: https://github.com/psf/black - rev: 23.9.1 + rev: 24.1.1 hooks: - id: black - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v16.0.6 + rev: v17.0.6 hooks: - id: clang-format - repo: https://github.com/PyCQA/autoflake @@ -34,18 +34,18 @@ repos: exclude: ^docker|deprecated|NaviGator/simulation/VRX args: [--severity=warning, --exclude=SC1090] - repo: https://github.com/scop/pre-commit-shfmt - rev: v3.7.0-1 + rev: v3.7.0-4 hooks: - id: shfmt exclude: ^docker|deprecated|NaviGator/simulation/VRX - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: 'v0.0.292' + rev: 'v0.2.0' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/codespell-project/codespell - rev: v2.2.5 + rev: v2.2.6 hooks: - id: codespell args: @@ -73,11 +73,12 @@ repos: - id: prettier-package-xml - id: sort-package-xml - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-added-large-files - id: check-case-conflict - id: check-merge-conflict + exclude_types: [markdown, rst] - id: check-executables-have-shebangs - id: check-symlinks - id: check-json diff --git a/NaviGator/gnc/navigator_path_planner/nodes/path_planner.py b/NaviGator/gnc/navigator_path_planner/nodes/path_planner.py index ba33ca850..1f6ff6793 100755 --- a/NaviGator/gnc/navigator_path_planner/nodes/path_planner.py +++ b/NaviGator/gnc/navigator_path_planner/nodes/path_planner.py @@ -1070,7 +1070,7 @@ def reevaluate_plan(self) -> None: def action_check(self, _: rospy.timer.TimerEvent) -> None: """ Manages action preempting. Serves as the callback to a Timer operating - opereating every self.revisit_period seconds. + operating every self.revisit_period seconds. """ if self.preempted or not self.move_server.is_active(): return diff --git a/NaviGator/hardware_drivers/navigator_kill_board/navigator_kill_board/constants.py b/NaviGator/hardware_drivers/navigator_kill_board/navigator_kill_board/constants.py index 83663e034..d5eaef7e4 100644 --- a/NaviGator/hardware_drivers/navigator_kill_board/navigator_kill_board/constants.py +++ b/NaviGator/hardware_drivers/navigator_kill_board/navigator_kill_board/constants.py @@ -17,6 +17,7 @@ The computer can also command a kill (for example, if ROS notices a criticaly low battery) by sending the COMPUTER.KILL.REQUEST and undone with COMPUTER.CLEAR.REQUEST """ + constants = { "TIMEOUT_SECONDS": 8.0, # How often board must be pinged to not set HEARTBERAT_REMOTE True # Note: not official documented, this is just a guess diff --git a/NaviGator/mission_control/navigator_alarm/navigator_alarm_handlers/battery_voltage.py b/NaviGator/mission_control/navigator_alarm/navigator_alarm_handlers/battery_voltage.py index 6c25b9169..c10b13c91 100644 --- a/NaviGator/mission_control/navigator_alarm/navigator_alarm_handlers/battery_voltage.py +++ b/NaviGator/mission_control/navigator_alarm/navigator_alarm_handlers/battery_voltage.py @@ -27,9 +27,9 @@ def _check_voltage(self, msg): if not self._raised or self._severity != severity: self.broadcaster.raise_alarm( severity=severity, - problem_description="battery critcaly low" - if severity == 2 - else "battery low", + problem_description=( + "battery critcaly low" if severity == 2 else "battery low" + ), parameters={"voltage": voltage}, ) diff --git a/NaviGator/mission_control/navigator_alarm/navigator_alarm_handlers/odom_kill.py b/NaviGator/mission_control/navigator_alarm/navigator_alarm_handlers/odom_kill.py index 2bc5e6c43..d0fa63afd 100755 --- a/NaviGator/mission_control/navigator_alarm/navigator_alarm_handlers/odom_kill.py +++ b/NaviGator/mission_control/navigator_alarm/navigator_alarm_handlers/odom_kill.py @@ -51,9 +51,7 @@ def check_continuity(self, odom): self._raised = True # Avoid raising multiple times rospy.logwarn("ODOM DISCONTINUITY DETECTED") self.ab.raise_alarm( - problem_description="ODOM DISCONTINUITY DETECTED. JUMPED {} METERS".format( - jump, - ), + problem_description=f"ODOM DISCONTINUITY DETECTED. JUMPED {jump} METERS", severity=5, ) self.last_position = position diff --git a/NaviGator/mission_control/navigator_missions/launch/mission_params.yaml b/NaviGator/mission_control/navigator_missions/launch/mission_params.yaml index 7b44edc7e..c4ee5940c 100644 --- a/NaviGator/mission_control/navigator_missions/launch/mission_params.yaml +++ b/NaviGator/mission_control/navigator_missions/launch/mission_params.yaml @@ -157,14 +157,14 @@ dock_shape_1: param: /mission/identify_dock/shape_1 options: [CIRCLE, TRIANGLE, CROSS, ANY] description: > - The shape of the first bay to dock in during the dentify + The shape of the first bay to dock in during the identify Symbols and Dock mission. If set to ANY, mission should dock based on the color parameter and set this parameter during the mission dock_color_1: param: /mission/identify_dock/color_1 options: [RED, GREEN, BLUE, ANY] description: > - The color of the first bay to dock in during the dentify Symbols and Dock + The color of the first bay to dock in during the identify Symbols and Dock mission. If set to ANY, mission should dock based on the shape parameter and set this parameter during the mission @@ -174,7 +174,7 @@ dock_shape_2: description: > # yamllint disable-line rule:line-length The shape of the second bay to dock in during the - dentify Symbols and Dock mission. If set to ANY, + identify Symbols and Dock mission. If set to ANY, mission should dock based on the color parameter and set this parameter during the mission dock_color_2: @@ -183,6 +183,6 @@ dock_color_2: description: > # yamllint disable-line rule:line-length The color of the second bay to dock in during the - dentify Symbols and Dock mission. + identify Symbols and Dock mission. If set to ANY, mission should dock based on the shape parameter and set this parameter during the mission diff --git a/NaviGator/mission_control/navigator_missions/navigator_missions/constant_velocity.py b/NaviGator/mission_control/navigator_missions/navigator_missions/constant_velocity.py index 5ae078c90..a0ce42a26 100644 --- a/NaviGator/mission_control/navigator_missions/navigator_missions/constant_velocity.py +++ b/NaviGator/mission_control/navigator_missions/navigator_missions/constant_velocity.py @@ -66,7 +66,7 @@ def decode_parameters(cls, parameters): return parsed async def run(self, args): - # Publish a velocity of zero for a while to stabalize navigator + # Publish a velocity of zero for a while to stabilize navigator self.send_feedback("Switching trajectory to constant") await self.change_trajectory("constant") await self.nh.sleep(0.1) diff --git a/NaviGator/mission_control/navigator_missions/navigator_missions/demonstrate_navigation.py b/NaviGator/mission_control/navigator_missions/navigator_missions/demonstrate_navigation.py index 6c53d35a4..599a388cc 100644 --- a/NaviGator/mission_control/navigator_missions/navigator_missions/demonstrate_navigation.py +++ b/NaviGator/mission_control/navigator_missions/navigator_missions/demonstrate_navigation.py @@ -68,7 +68,7 @@ async def run(self, parameters): _, closest_reds = await self.get_sorted_objects("red_cylinder", 1) _, closest_greens = await self.get_sorted_objects("green_cylinder", 1) - # Rename the totems for their symantic name + # Rename the totems for their semantic name green_close = closest_greens[0] red_close = closest_reds[0] @@ -83,7 +83,7 @@ async def run(self, parameters): _, closest_reds = await self.get_sorted_objects("red_cylinder", 2) _, closest_greens = await self.get_sorted_objects("green_cylinder", 2) - # Rename the totems for their symantic name + # Rename the totems for their semantic name green_far = closest_greens[1] red_far = closest_reds[1] diff --git a/NaviGator/mission_control/navigator_missions/navigator_missions/detect_deliver_2016.py b/NaviGator/mission_control/navigator_missions/navigator_missions/detect_deliver_2016.py index 28c3ac4d9..dee540de0 100644 --- a/NaviGator/mission_control/navigator_missions/navigator_missions/detect_deliver_2016.py +++ b/NaviGator/mission_control/navigator_missions/navigator_missions/detect_deliver_2016.py @@ -153,9 +153,7 @@ async def do_circle(): await self.nh.sleep(0.25) continue fprint( - "Shape ({}found, using normal to look at other 3 shapes if needed".format( - res[0], - ), + f"Shape ({res[0]}found, using normal to look at other 3 shapes if needed", title="DETECT DELIVER", msg_color="green", ) diff --git a/NaviGator/mission_control/navigator_missions/navigator_missions/move.py b/NaviGator/mission_control/navigator_missions/navigator_missions/move.py index 8ae428057..a9debd213 100755 --- a/NaviGator/mission_control/navigator_missions/navigator_missions/move.py +++ b/NaviGator/mission_control/navigator_missions/navigator_missions/move.py @@ -149,7 +149,7 @@ async def run(self, args): "yl": "yaw_left", "yr": "yaw_right", } - command = command if command not in shorthand else shorthand[command] + command = shorthand.get(command, command) movement = getattr(self.move, command) trans_move = command[:3] != "yaw" diff --git a/NaviGator/mission_control/navigator_missions/navigator_missions/pose_editor.py b/NaviGator/mission_control/navigator_missions/navigator_missions/pose_editor.py index 5f25f36ab..d2b1855cd 100644 --- a/NaviGator/mission_control/navigator_missions/navigator_missions/pose_editor.py +++ b/NaviGator/mission_control/navigator_missions/navigator_missions/pose_editor.py @@ -341,9 +341,7 @@ def as_MoveGoal(self, move_type=MoveGoal.DRIVE, **kwargs): for key in kwargs: if not hasattr(MoveGoal, key): fprint( - "MoveGoal msg doesn't have a field called '{}' you tried to set via kwargs.".format( - key, - ), + f"MoveGoal msg doesn't have a field called '{key}' you tried to set via kwargs.", title="POSE_EDITOR", msg_color="red", ) diff --git a/NaviGator/mission_control/navigator_missions/vrx_missions/dock.py b/NaviGator/mission_control/navigator_missions/vrx_missions/dock.py index 23d7cdfb3..44a3cacae 100644 --- a/NaviGator/mission_control/navigator_missions/vrx_missions/dock.py +++ b/NaviGator/mission_control/navigator_missions/vrx_missions/dock.py @@ -607,7 +607,7 @@ async def prepare_for_docking(self): # This function looks at the two squares in front of the boat # and it gets the middle pixel between the two squares. # If the middle pixel is for some reason not in the middle of our camera... - # adjust the boat postiion before docking + # adjust the boat position before docking print("prepare for landing!") img = await self.front_left_camera_sub.get_next_message() diff --git a/NaviGator/satellite/rviz_satellite/src/aerialmap_display.cpp b/NaviGator/satellite/rviz_satellite/src/aerialmap_display.cpp index 22a307f76..bf5ec8b20 100644 --- a/NaviGator/satellite/rviz_satellite/src/aerialmap_display.cpp +++ b/NaviGator/satellite/rviz_satellite/src/aerialmap_display.cpp @@ -416,7 +416,7 @@ void AerialMapDisplay::assembleScene() // determine location of this tile, flipping y in the process const double x = (tile.x() - loader_->centerTileX()) * tile_w + origin_x; const double y = -(tile.y() - loader_->centerTileY()) * tile_h + origin_y; - // don't re-use any ids + // don't reuse any ids const std::string name_suffix = std::to_string(tile.x()) + "_" + std::to_string(tile.y()) + "_" + std::to_string(map_id_) + "_" + std::to_string(scene_id_); diff --git a/NaviGator/scripts/bash_aliases.sh b/NaviGator/scripts/bash_aliases.sh index 216b1ff80..de6da5f4b 100755 --- a/NaviGator/scripts/bash_aliases.sh +++ b/NaviGator/scripts/bash_aliases.sh @@ -18,7 +18,7 @@ nthrust() { topic="/$1_motor/cmd" publishers=$(rostopic info "$topic" | grep Publishers) if [ "$publishers" != "Publishers: None" ]; then - echo "Somone is already publishing to $topic. Perhaps you need to kill thrust mapper?" + echo "Someone is already publishing to $topic. Perhaps you need to kill thrust mapper?" return 1 fi rostopic pub "$topic" "roboteq_msgs/Command" "setpoint: $2" -r100 diff --git a/NaviGator/utils/navigator_msgs/srv/GetDockBays.srv b/NaviGator/utils/navigator_msgs/srv/GetDockBays.srv index 9a39764bd..7081b1b07 100644 --- a/NaviGator/utils/navigator_msgs/srv/GetDockBays.srv +++ b/NaviGator/utils/navigator_msgs/srv/GetDockBays.srv @@ -2,4 +2,4 @@ geometry_msgs/Point[3] bays #The positions in ENU frame of the center of the three bays 0=left, 1=center, 2=right geometry_msgs/Vector3 normal #Vector or normal pointing away from plane of dock back bool success #False if an error occurred getting dock bays -string error #Descripion of error if success=false +string error #Description of error if success=false diff --git a/NaviGator/utils/navigator_tools/nodes/navigator_status_tui b/NaviGator/utils/navigator_tools/nodes/navigator_status_tui index 3efa0a5d1..0fc39eb3b 100755 --- a/NaviGator/utils/navigator_tools/nodes/navigator_status_tui +++ b/NaviGator/utils/navigator_tools/nodes/navigator_status_tui @@ -35,7 +35,7 @@ class nav_tui: self.panel.hide() panel.update_panels() self.rate = rospy.Rate(2) # Fixed rate for while loop to update at: 2 hz - # The following are default field initalizations for various values that that will be overwritten + # The following are default field initializations for various values that that will be overwritten self.voltage = 0 self.wrench = None self.LAT = None @@ -214,15 +214,13 @@ class nav_tui: if len(self.decode_fault_status(self.FL_fault)) == 0: self.window.addstr(5, self.x / 2 - 7, "No faults", curses.color_pair(3)) else: - n = 0 - for fault in self.decode_fault_status(self.FL_fault): + for n, fault in enumerate(self.decode_fault_status(self.FL_fault)): self.window.addstr( 5 + n, self.x / 2 - 7, "%s" % fault, curses.color_pair(1), ) - n += 1 self.window.addstr(14, self.x / 2 - 7, "Back Left", color) if len(self.decode_fault_status(self.BL_fault)) == 0: diff --git a/NaviGator/utils/remote_control/navigator_emergency_control/nodes/navigator_emergency.py b/NaviGator/utils/remote_control/navigator_emergency_control/nodes/navigator_emergency.py index 8077b4601..0bd27c291 100755 --- a/NaviGator/utils/remote_control/navigator_emergency_control/nodes/navigator_emergency.py +++ b/NaviGator/utils/remote_control/navigator_emergency_control/nodes/navigator_emergency.py @@ -95,7 +95,7 @@ def check_for_timeout(self, joy: Joy): def joy_recieved(self, joy: Joy) -> None: """ - Button elements are being assigned and simplied to readable names. The + Button elements are being assigned and simplified to readable names. The number of deployments or retractions for thrusters are being updated based on several conditions. Moreover, additional settings are changed based on the state of the controller and the activation of potential alarms or switches. diff --git a/NaviGator/utils/voltage_gui/src/voltage_gui.py b/NaviGator/utils/voltage_gui/src/voltage_gui.py index 932dbc22b..79e6a0e85 100644 --- a/NaviGator/utils/voltage_gui/src/voltage_gui.py +++ b/NaviGator/utils/voltage_gui/src/voltage_gui.py @@ -184,7 +184,7 @@ def resizeFont(self) -> None: # done threshFont = QtGui.QFont("Times", (self.fontSize) / 3, QtGui.QFont.Bold) self.labelThresh.setFont(threshFont) - # Sets the text of the thrshold info box + # Sets the text of the threshold info box def initThresh(self) -> None: """ Sets the text of the threshold info box diff --git a/SubjuGator/command/subjugator_launch/config/passive_sonar.yaml b/SubjuGator/command/subjugator_launch/config/passive_sonar.yaml index 9901f9703..e55aec3da 100644 --- a/SubjuGator/command/subjugator_launch/config/passive_sonar.yaml +++ b/SubjuGator/command/subjugator_launch/config/passive_sonar.yaml @@ -3,7 +3,7 @@ dist_h: 2.286e-02 # speed of sound in water v_sound: 1482 -# target Frquency in Hz +# target Frequency in Hz triggering/target_frequency: 30000 # tolerance around target frequerncy in Hz triggering/frequency_tolerance: 100 diff --git a/SubjuGator/command/subjugator_launch/launch/subsystems/nav_box.launch b/SubjuGator/command/subjugator_launch/launch/subsystems/nav_box.launch index eb5e1bc31..3dee6ee81 100644 --- a/SubjuGator/command/subjugator_launch/launch/subsystems/nav_box.launch +++ b/SubjuGator/command/subjugator_launch/launch/subsystems/nav_box.launch @@ -42,10 +42,10 @@ scale: - - [0.993770963897068, 0.00105871125374563, 7.659410525291767e-05] - - [0.00105871125374563, 0.9996814868251349, -0.0011040738267441828] - - [7.659410525291767e-05, -0.001104073826744163, 1.0065910531028952] - shift: [1.2551999807772446e-06, -1.1666595150804588e-06, 6.895773090438596e-08] + - [0.9991765357958566, 0.006242798579443988, -0.008472478269327878] + - [0.006242798579443957, 1.0016179705091928, 0.0059841151097914345] + - [-0.008472478269327836, 0.0059841151097913, 0.999354597532967] + shift: [7.889247409445414e-06, 4.879179471165382e-06, 7.46017199298374e-06] 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 4b65395af..342292350 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 @@ -132,9 +132,11 @@ if __name__ == "__main__": with rosbag.Bag(sys.argv[1]) as bag: points = numpy.array( [ - mil_ros_tools.rosmsg_to_numpy(msg.magnetic_field) - if hasattr(msg, "magnetic_field") - else mil_ros_tools.rosmsg_to_numpy(msg.vector) + ( + mil_ros_tools.rosmsg_to_numpy(msg.magnetic_field) + if hasattr(msg, "magnetic_field") + else mil_ros_tools.rosmsg_to_numpy(msg.vector) + ) for topic, msg, t in bag.read_messages(topics=["/imu/mag_raw"]) ], ) diff --git a/SubjuGator/perception/subjugator_perception/nodes/dice_detect.py b/SubjuGator/perception/subjugator_perception/nodes/dice_detect.py index 55d1dd5e2..312123597 100755 --- a/SubjuGator/perception/subjugator_perception/nodes/dice_detect.py +++ b/SubjuGator/perception/subjugator_perception/nodes/dice_detect.py @@ -93,7 +93,7 @@ def detect(self, dice_img): params.minConvexity = 0.8 # 1 = perfect convex hull # Filter by Inertia params.filterByInertia = True - params.minInertiaRatio = 0.4 # Defines the ellipsoid 1= detects only cirlces + params.minInertiaRatio = 0.4 # Defines the ellipsoid 1= detects only circles # 0 = Detects even lines # Create a detector with the parameters diff --git a/SubjuGator/perception/subjugator_perception/nodes/hsv_calibration.py b/SubjuGator/perception/subjugator_perception/nodes/hsv_calibration.py index 4a67f4bb7..433133431 100755 --- a/SubjuGator/perception/subjugator_perception/nodes/hsv_calibration.py +++ b/SubjuGator/perception/subjugator_perception/nodes/hsv_calibration.py @@ -36,13 +36,17 @@ def parse_string(threshes): def reconfigure(self, config, level): try: self.lower = np.array(self.parse_string(config["dyn_lower"])) - rospy.logwarn("HSV lower bound below minimum value") if ( - self.lower < 0 - ).any() else None + ( + rospy.logwarn("HSV lower bound below minimum value") + if (self.lower < 0).any() + else None + ) self.upper = np.array(self.parse_string(config["dyn_upper"])) - rospy.logwarn("HSV upper bound above maximum values") if ( - self.upper[0] > 179 - ).any() or (self.upper[1:] > 255).any() else None + ( + rospy.logwarn("HSV upper bound above maximum values") + if (self.upper[0] > 179).any() or (self.upper[1:] > 255).any() + else None + ) except ValueError as e: rospy.logwarn(f"Invalid dynamic reconfigure: {e}") diff --git a/SubjuGator/perception/subjugator_perception/nodes/orange_rectangle_finder.py b/SubjuGator/perception/subjugator_perception/nodes/orange_rectangle_finder.py index 0701c3b05..237fe94e3 100755 --- a/SubjuGator/perception/subjugator_perception/nodes/orange_rectangle_finder.py +++ b/SubjuGator/perception/subjugator_perception/nodes/orange_rectangle_finder.py @@ -52,7 +52,7 @@ class OrangeRectangleFinder: * Transform this frames pose into /map frame * Plug this frames pose in /map into a kalman filter to reduce noise - TODO: Allow for two objects to be identifed at once, both filtered through its own KF + TODO: Allow for two objects to be identified at once, both filtered through its own KF """ # Coordinate axes for debugging image diff --git a/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/HOG/HOG_SVM_trainer.py b/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/HOG/HOG_SVM_trainer.py index bbdb7aefb..01e85b3a2 100644 --- a/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/HOG/HOG_SVM_trainer.py +++ b/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/HOG/HOG_SVM_trainer.py @@ -16,8 +16,7 @@ class_list = np.array(0) # loop through the training images -count = 0 -for i in os.listdir(os.path.abspath(folder)): +for count, i in enumerate(os.listdir(os.path.abspath(folder))): # get the roi from the file path = folder + "/" + i roi_str = f.readline() @@ -72,7 +71,6 @@ class_temp = np.empty(len_myinvhog / 9) class_temp.fill(-1) class_list = np.append(class_list, class_temp) - count += 1 # hack class_list = np.delete(class_list, [0]) diff --git a/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/machine_learning/boost_auto.py b/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/machine_learning/boost_auto.py index c9027ff60..c1cf17e1a 100644 --- a/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/machine_learning/boost_auto.py +++ b/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/machine_learning/boost_auto.py @@ -100,10 +100,11 @@ def train_on_data(observation_list, label_list, split_factor=4): s_time = time.time() process_round = 0 # Split this into multiple passes in an attempt to free RAM (no idea if this works). - for x, y in zip(all_observations_split, all_labels_split): + for process_round, (x, y) in enumerate( + zip(all_observations_split, all_labels_split), + ): print(f"Training subset {process_round + 1}/{split_factor}.") boost.train(x, cv2.CV_ROW_SAMPLE, y, params=parameters) - process_round += 1 print(f"Time to complete: {time.time() - s_time}") print("Done! Saving...") diff --git a/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/marker_occ_grid.py b/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/marker_occ_grid.py index 9261de0ac..c547f7847 100644 --- a/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/marker_occ_grid.py +++ b/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/marker_occ_grid.py @@ -174,7 +174,7 @@ def return_pose(self, srv): self.poly_generator = self.polygon_generator() return [0, False, srv.intial_position] - # We search at 1.5 * r so that there is some overlay in the search feilds. + # We search at 1.5 * r so that there is some overlay in the search fields. np_pose = msg_helpers.pose_to_numpy(srv.intial_position) rot_mat = make_2D_rotation( tf.transformations.euler_from_quaternion(np_pose[1])[2], @@ -249,7 +249,6 @@ def polygon_generator(self, n=12): class MarkerOccGrid(OccGridUtils): - """ Handles updating occupancy grid when new data comes in. TODO: Upon call can return some path to go to in order to find them. diff --git a/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/rviz.py b/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/rviz.py index c46dd18ea..e6af8929a 100644 --- a/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/rviz.py +++ b/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/rviz.py @@ -9,7 +9,6 @@ class RvizVisualizer: - """Cute tool for drawing both depth and height-from-bottom in RVIZ""" def __init__(self, topic="visualization/markers"): diff --git a/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/visual_threshold_tools.py b/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/visual_threshold_tools.py index 7ec7d04c9..f30275cfc 100644 --- a/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/visual_threshold_tools.py +++ b/SubjuGator/perception/subjugator_perception/subjugator_vision_tools/visual_threshold_tools.py @@ -63,7 +63,6 @@ def denormalize(val, _min, _max): class ExtentDialog(traits.api.HasTraits): - """A dialog to graphically adjust the extents of a threshold range""" # Data extents diff --git a/SubjuGator/perception/subjugator_perception/test/test_path_marker.py b/SubjuGator/perception/subjugator_perception/test/test_path_marker.py index 4f3a621cc..5674ddf5a 100755 --- a/SubjuGator/perception/subjugator_perception/test/test_path_marker.py +++ b/SubjuGator/perception/subjugator_perception/test/test_path_marker.py @@ -17,7 +17,6 @@ class TestPathMarker(unittest.TestCase): - """ Unit test for perception service finding orange path markers Plays several bags with known pixel coordinates of path marker, diff --git a/SubjuGator/simulation/subjugator_gazebo/diagnostics/gazebo_tests/common.py b/SubjuGator/simulation/subjugator_gazebo/diagnostics/gazebo_tests/common.py index de7bc39f0..38a5baf41 100644 --- a/SubjuGator/simulation/subjugator_gazebo/diagnostics/gazebo_tests/common.py +++ b/SubjuGator/simulation/subjugator_gazebo/diagnostics/gazebo_tests/common.py @@ -8,7 +8,6 @@ class Job: - """Inherit from this!""" _job_name = "generic job" diff --git a/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/shaders/shader_manager.py b/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/shaders/shader_manager.py index edfb7d12f..192755207 100644 --- a/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/shaders/shader_manager.py +++ b/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/shaders/shader_manager.py @@ -36,7 +36,6 @@ def add_item(self, position, intensity): class ShaderManager: - """ This class is used when you want to have an entity switch out shaders at a specific time. If you want to add another rule for when to switch out shaders: diff --git a/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/shaders/shaders.py b/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/shaders/shaders.py index d4a2e1f62..210a68e8e 100644 --- a/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/shaders/shaders.py +++ b/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/shaders/shaders.py @@ -65,7 +65,6 @@ def recursive_dictionary(self, path, text): class Shaders: - """A Shaders class, which automatically contains all of the shaders in the shaders folder WTF? diff --git a/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/widgets/sub.py b/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/widgets/sub.py index cbb628bad..144ec195d 100644 --- a/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/widgets/sub.py +++ b/SubjuGator/simulation/subjugator_simulation/subjugator_sim_tools/widgets/sub.py @@ -83,7 +83,6 @@ def make_visual(self, physical, position, thrust_indicators=False): ) class ThrustGetter: - """This is a pretty garbage thing, and will be replaced by the scenegraph system""" def __init__(self, thruster_name, rdir): diff --git a/SubjuGator/utils/subjugator_diagnostics/scripts/self_check.py b/SubjuGator/utils/subjugator_diagnostics/scripts/self_check.py index 2552541cc..4db32b96c 100755 --- a/SubjuGator/utils/subjugator_diagnostics/scripts/self_check.py +++ b/SubjuGator/utils/subjugator_diagnostics/scripts/self_check.py @@ -18,7 +18,6 @@ class TemplateChecker: - """Template for how each checker class should look. This provides interface functions for the main function to use. You don't have to implement them all in each checker. diff --git a/docs/design/passive_sonar/passive_sonar.rst b/docs/design/passive_sonar/passive_sonar.rst index 522368705..6f23f38ab 100644 --- a/docs/design/passive_sonar/passive_sonar.rst +++ b/docs/design/passive_sonar/passive_sonar.rst @@ -78,8 +78,8 @@ Configuration ************* All parameters that are expected to be changed in tuining are ROS Params initialized in ``passive_sonar.yaml`` -To make a custom configation -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +To make a custom configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * ``roscd subjugator_launch`` diff --git a/docs/electrical/onboarding.md b/docs/electrical/onboarding.md index c48026aaa..45d73e7a7 100644 --- a/docs/electrical/onboarding.md +++ b/docs/electrical/onboarding.md @@ -20,7 +20,7 @@ including meeting times. ## Join the electrical GitHub Unlike the software and mechanical teams (who share a GitHub repository), we use -a separate repository for the electrical team. As a resut, you will need to be added +a separate repository for the electrical team. As a result, you will need to be added to this organization. Once you're in Slack (or you've come to the lab), ask an electrical leader to add you to the GitHub organization. The organization can be found [here](https://github.com/uf-mil-electrical). diff --git a/docs/extensions/attributetable.py b/docs/extensions/attributetable.py index bfee064d7..53372cb61 100644 --- a/docs/extensions/attributetable.py +++ b/docs/extensions/attributetable.py @@ -2,6 +2,7 @@ Credit goes to discord.py and its creators for creating most of this file: https://github.com/Rapptz/discord.py/blob/master/docs/extensions/attributetable.py """ + import importlib import inspect import re diff --git a/docs/extensions/builder.py b/docs/extensions/builder.py index 84de6d59d..881417afc 100644 --- a/docs/extensions/builder.py +++ b/docs/extensions/builder.py @@ -2,6 +2,7 @@ Credit goes to discord.py and its creators for creating most of this file: https://github.com/Rapptz/discord.py/blob/master/docs/extensions/attributetable.py """ + from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.environment.adapters.indexentries import IndexEntries from sphinx.writers.html5 import HTML5Translator diff --git a/docs/indyav/software/planning/indyav_path/path_recorder.rst b/docs/indyav/software/planning/indyav_path/path_recorder.rst index 77c3d4ee3..d1b5f1a47 100644 --- a/docs/indyav/software/planning/indyav_path/path_recorder.rst +++ b/docs/indyav/software/planning/indyav_path/path_recorder.rst @@ -33,7 +33,7 @@ Basic Usage Example - Visualize this new topic in rviz by clicking `Add` and then `/odom2 -> Odometry` -- Watch the red arrow advance from where the sub started to where the sub stopped updting approximately 10 times a second. +- Watch the red arrow advance from where the sub started to where the sub stopped updating approximately 10 times a second. Source Files ^^^^^^^^^^^^ diff --git a/docs/navigator/lessons22.md b/docs/navigator/lessons22.md index 1c92fc298..25607540e 100644 --- a/docs/navigator/lessons22.md +++ b/docs/navigator/lessons22.md @@ -62,7 +62,7 @@ future teams to learn from! It is quicker to tell when tools have gone missing (as each tool now has a dedicated spot in the organizer), and which tool is missing. Furthermore, it becomes easier for software members, electrical members, and mentors to find - tools, even if they maybe are not acquianted with a deep knowledge of the + tools, even if they maybe are not acquainted with a deep knowledge of the mechanical team. * **Focus on bringing less and staying more organized.** - At RobotX 2022, we were one of the teams who had brought the most equipment, yet we had a hard diff --git a/docs/software/adding_documentation.md b/docs/software/adding_documentation.md index cc1a1fd46..d91bf76e3 100644 --- a/docs/software/adding_documentation.md +++ b/docs/software/adding_documentation.md @@ -100,5 +100,5 @@ $ ./scripts/build_docs --scratch ``` ## Contributing changes -Now that you have made and verifed your changes, follow the [contributing guide](contributing) +Now that you have made and verified your changes, follow the [contributing guide](contributing) to add your changes to the repository. diff --git a/docs/software/getting_started.md b/docs/software/getting_started.md index 1215b276e..a40845665 100644 --- a/docs/software/getting_started.md +++ b/docs/software/getting_started.md @@ -420,7 +420,7 @@ launches the Gazebo GUI - aka, the thing you will actually interact with! If all goes according to plan, you should see our robot in its own little world! ## Installing developer tools -After you have verified that your Git setup is working appopriately, take a look +After you have verified that your Git setup is working appropriately, take a look at installing some developer tools on the [Developer Tools](/software/devtools) page. diff --git a/docs/software/help.md b/docs/software/help.md index 060f8376b..f8250fa70 100644 --- a/docs/software/help.md +++ b/docs/software/help.md @@ -63,7 +63,7 @@ for examples of it being used. ## Search the internet If your problem is not MIL-specific (issue with Linux, ROS, C++, etc), -somone has most likely had the same problem and written about it on the internet. +someone has most likely had the same problem and written about it on the internet. You'll be surprised how often you can fix your issue by Googling the error. ## Search Slack diff --git a/docs/software/noetic_migration.md b/docs/software/noetic_migration.md index 6a79ec10a..6a93a86cd 100644 --- a/docs/software/noetic_migration.md +++ b/docs/software/noetic_migration.md @@ -45,7 +45,7 @@ before you commit. Great, the code is now pretty! :D -If you ran `python-modernize`, it will have suggested some changes to you, indcated +If you ran `python-modernize`, it will have suggested some changes to you, indicated by `+` and `-` signs. It may look something like this: ```diff diff --git a/mil_common/axros b/mil_common/axros index a4951d333..1b0399935 160000 --- a/mil_common/axros +++ b/mil_common/axros @@ -1 +1 @@ -Subproject commit a4951d33356c349856532ddef5c97c6ec6810c28 +Subproject commit 1b03999351fb5a61b202ff125f493229c2a1676b diff --git a/mil_common/drivers/mil_passive_sonar/README.md b/mil_common/drivers/mil_passive_sonar/README.md index 572ad4069..7010a3ae0 100644 --- a/mil_common/drivers/mil_passive_sonar/README.md +++ b/mil_common/drivers/mil_passive_sonar/README.md @@ -4,7 +4,7 @@ This package includes the main algorithm to find the direction of a pinger. It a # Running: Ensure that hydrophones -> ros is running and publishing a `mil_passive_sonar/Ping` msg. -Then run `roslaunch mil_passive_sonar mil_passive_sonar.lauch` +Then run `roslaunch mil_passive_sonar mil_passive_sonar.launch` `mil_passive_sonar/FindPinger` diff --git a/mil_common/drivers/mil_passive_sonar/scripts/triggering.py b/mil_common/drivers/mil_passive_sonar/scripts/triggering.py index 897a76949..321a20411 100755 --- a/mil_common/drivers/mil_passive_sonar/scripts/triggering.py +++ b/mil_common/drivers/mil_passive_sonar/scripts/triggering.py @@ -96,7 +96,7 @@ def get_params(self): self.enabled = rospy.get_param("~enable_on_launch") # Attributes about our target frequency range - # target Frquency in Hz + # target Frequency in Hz self.target = rospy.get_param("~target_frequency") # tolerance around that frequerncy in Hz tolerance = rospy.get_param("~frequency_tolerance") @@ -121,7 +121,7 @@ def get_params(self): self.v_sound = rospy.get_param("v_sound") # Misc attributes - # minimum gradient of the max convolution wrt time to trigger a time of arivals calculation + # minimum gradient of the max convolution wrt time to trigger a time of arrivals calculation self.threshold = rospy.get_param("~threshold") self.trigger_offset = rospy.get_param("~trigger_offset") # how far after the triggering time to make upper bound of samples at triggering in sec diff --git a/mil_common/drivers/mil_pneumatic_actuator/nodes/pneumatic_actuator_node b/mil_common/drivers/mil_pneumatic_actuator/nodes/pneumatic_actuator_node index bf8261177..920fb5a92 100755 --- a/mil_common/drivers/mil_pneumatic_actuator/nodes/pneumatic_actuator_node +++ b/mil_common/drivers/mil_pneumatic_actuator/nodes/pneumatic_actuator_node @@ -37,7 +37,7 @@ class Actuator: if isinstance(config, int): return cls.from_int(config) type_str = config["type"] - pulse_time = config["pulse_time"] if "pulse_time" in config else None + pulse_time = config.get("pulse_time") open_id = config["ports"]["open_port"]["id"] open_default = config["ports"]["open_port"]["default"] if "close_port" in config["ports"]: diff --git a/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub8/utils.py b/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub8/utils.py index 0ef0cf9a1..7524e6dfe 100644 --- a/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub8/utils.py +++ b/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub8/utils.py @@ -114,13 +114,11 @@ def __bytes__(self) -> bytes: @overload @classmethod - def _unpack_payload(cls, data: Literal[b""]) -> None: - ... + def _unpack_payload(cls, data: Literal[b""]) -> None: ... @overload @classmethod - def _unpack_payload(cls, data: bytes) -> bytes: - ... + def _unpack_payload(cls, data: bytes) -> bytes: ... @classmethod def _unpack_payload(cls, data: bytes) -> bytes | None: @@ -455,13 +453,11 @@ def calculate_checksum(self, data: bytes) -> int: @overload @classmethod - def from_bytes(cls, data: Literal[b""]) -> None: - ... + def from_bytes(cls, data: Literal[b""]) -> None: ... @overload @classmethod - def from_bytes(cls: type[T], data: bytes) -> T: - ... + def from_bytes(cls: type[T], data: bytes) -> T: ... @classmethod def from_bytes(cls: type[T], data: bytes) -> T | None: diff --git a/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub9/sub9_driver.py b/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub9/sub9_driver.py index 59db73c99..90928ff8d 100755 --- a/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub9/sub9_driver.py +++ b/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub9/sub9_driver.py @@ -31,8 +31,9 @@ class SimulatedUSBtoCANStream(SimulatedSerial): def __init__( self, - devices: list[tuple[type[SimulatedCANDeviceHandle], list[type[Packet]]]] - | None = None, + devices: ( + list[tuple[type[SimulatedCANDeviceHandle], list[type[Packet]]]] | None + ) = None, ): """ Args: @@ -214,16 +215,14 @@ def read_devices( self, *, simulated: Literal[True], - ) -> list[tuple[type[SimulatedCANDeviceHandle], list[type[Packet]]]]: - ... + ) -> list[tuple[type[SimulatedCANDeviceHandle], list[type[Packet]]]]: ... @overload def read_devices( self, *, simulated: Literal[False], - ) -> list[tuple[type[CANDeviceHandle], list[type[Packet]]]]: - ... + ) -> list[tuple[type[CANDeviceHandle], list[type[Packet]]]]: ... def read_devices( self, diff --git a/mil_common/gnc/rawgps_common/src/rawgps_common/gps.py b/mil_common/gnc/rawgps_common/src/rawgps_common/gps.py index 81393bb3f..d8fb03d5b 100644 --- a/mil_common/gnc/rawgps_common/src/rawgps_common/gps.py +++ b/mil_common/gnc/rawgps_common/src/rawgps_common/gps.py @@ -649,9 +649,7 @@ def generate_satellite_message( for i in range(2): dt = t - eph.t_oc assert abs(dt) < week_length / 2 - deltat_SV_L1 = ( - eph.a_f0 + eph.a_f1 * dt + eph.a_f2 * dt**2 + deltat_r - eph.T_GD - ) + deltat_SV_L1 = eph.a_f0 + eph.a_f1 * dt + eph.a_f2 * dt**2 + deltat_r - eph.T_GD t = t_SV - deltat_SV_L1 if i == 1: sat_pos, deltat_r, sat_vel = eph.predict(t) @@ -691,14 +689,16 @@ def generate_satellite_message( time=-pseudo_range / c - deltat_SV_L1, T_iono=T_iono, T_tropo=T_tropo, - carrier_distance=carrier_cycles * c / L1_f0 - if carrier_cycles is not None - else nan, + carrier_distance=( + carrier_cycles * c / L1_f0 if carrier_cycles is not None else nan + ), doppler_velocity=doppler_freq * c / L1_f0, direction_enu=Vector3(*direction_enu), - velocity_plus_drift=doppler_freq * c / L1_f0 + direction.dot(sat_vel) - if doppler_freq is not None - else nan, + velocity_plus_drift=( + doppler_freq * c / L1_f0 + direction.dot(sat_vel) + if doppler_freq is not None + else nan + ), ) diff --git a/mil_common/mil_missions/mil_missions_core/__init__.py b/mil_common/mil_missions/mil_missions_core/__init__.py index f4244279d..e603f4026 100644 --- a/mil_common/mil_missions/mil_missions_core/__init__.py +++ b/mil_common/mil_missions/mil_missions_core/__init__.py @@ -4,6 +4,7 @@ from to create robot-specific mission tasks. These mission classes can be imported by the mission runner and then run. """ + from .base_mission import BaseMission from .chain_with_timeout import MakeChainWithTimeout from .exceptions import ( diff --git a/mil_common/perception/mil_vision/include/mil_vision_lib/cv_tools.hpp b/mil_common/perception/mil_vision/include/mil_vision_lib/cv_tools.hpp index 4709fa85f..af6f30853 100644 --- a/mil_common/perception/mil_vision/include/mil_vision_lib/cv_tools.hpp +++ b/mil_common/perception/mil_vision/include/mil_vision_lib/cv_tools.hpp @@ -76,7 +76,7 @@ unsigned int select_hist_mode(std::vector &histogram_modes, unsigned // Takes in a grayscale image and segments out a semi-homogenous foreground // object with pixel intensities close to . Tuning of last three -// parameters may imrove results but default values should work well in +// parameters may improve results but default values should work well in // most cases. void statistical_image_segmentation(const cv::Mat &src, cv::Mat &dest, cv::Mat &debug_img, const int hist_size, const float **ranges, const int target, std::string image_name = "Unnamed Image", diff --git a/mil_common/perception/mil_vision/mil_vision_tools/color_classifier.py b/mil_common/perception/mil_vision/mil_vision_tools/color_classifier.py index df48a5881..c19e09c5e 100755 --- a/mil_common/perception/mil_vision/mil_vision_tools/color_classifier.py +++ b/mil_common/perception/mil_vision/mil_vision_tools/color_classifier.py @@ -94,7 +94,7 @@ def classify_features(self, features: np.ndarray) -> int: def feature_probabilities(self, features: np.ndarray) -> List[float]: """ - Allows child classes to give probabilties for each possible class given + Allows child classes to give probabilities for each possible class given a features vector, instead of just one classification. By default, gives 1.0 to classified class and 0.0 to others. diff --git a/mil_common/perception/mil_vision/mil_vision_tools/shape_finder.py b/mil_common/perception/mil_vision/mil_vision_tools/shape_finder.py index 5ba5f78cb..33479a753 100644 --- a/mil_common/perception/mil_vision/mil_vision_tools/shape_finder.py +++ b/mil_common/perception/mil_vision/mil_vision_tools/shape_finder.py @@ -213,7 +213,7 @@ def get_pose_3D( cam (Optional[PinholeCameraModel]): The camera model. rectified (bool): If ``cam`` is set, set True if corners were found in an already rectified image (image_rect_color topic). - instrinsics (np.ndarray): Camera intrinisic matrix. + intrinsics (np.ndarray): Camera intrinisic matrix. dist_coeffs (np.ndarray): Camera distortion coefficients. Returns: @@ -304,12 +304,12 @@ def __init__(self, length=1.0, width=1.0): self.model_2D = np.zeros((50, 1, 2), dtype=np.int) # Approximate an ellipse with 50 points, so that verify_contour is reasonable fast still for idx, theta in enumerate(np.linspace(0.0, 2.0 * np.pi, num=50)): - self.model_2D[idx][0][ - 0 - ] = self.length * 0.5 * scale + self.length * 0.5 * scale * np.cos(theta) - self.model_2D[idx][0][ - 1 - ] = self.width * 0.5 * scale + self.width * 0.5 * scale * np.sin(theta) + self.model_2D[idx][0][0] = ( + self.length * 0.5 * scale + self.length * 0.5 * scale * np.cos(theta) + ) + self.model_2D[idx][0][1] = ( + self.width * 0.5 * scale + self.width * 0.5 * scale * np.sin(theta) + ) def get_corners(self, contour, debug_image=None): """ diff --git a/mil_common/perception/mil_vision/mil_vision_tools/vision_node.py b/mil_common/perception/mil_vision/mil_vision_tools/vision_node.py index d1c8d37e9..caaaf7fd6 100755 --- a/mil_common/perception/mil_vision/mil_vision_tools/vision_node.py +++ b/mil_common/perception/mil_vision/mil_vision_tools/vision_node.py @@ -27,7 +27,7 @@ def create_object_msg( is needed/available in your application. Args: - name (str): Name of the identifed object. + name (str): Name of the identified object. attributes (str): Attributes to attach to message, the purpose and value of this attribute will vary by application. Defaults to an empty string. confidence (Optional[float]): Float between 0 and 1 describing the confidence diff --git a/mil_common/perception/mil_vision/ros_tools/on_the_fly_thresholder.py b/mil_common/perception/mil_vision/ros_tools/on_the_fly_thresholder.py index 74fbc58dd..e70de289e 100755 --- a/mil_common/perception/mil_vision/ros_tools/on_the_fly_thresholder.py +++ b/mil_common/perception/mil_vision/ros_tools/on_the_fly_thresholder.py @@ -78,9 +78,11 @@ def __init__(self, img, thresh_type="bgr"): def update_mask(self): self.lower, self.upper = self.trackbars.get_bounds() self.mask = cv2.inRange( - self.image - if self.thresh_type == "bgr" - else cv2.cvtColor(self.image, cv2.COLOR_BGR2HSV), + ( + self.image + if self.thresh_type == "bgr" + else cv2.cvtColor(self.image, cv2.COLOR_BGR2HSV) + ), self.lower, self.upper, ) diff --git a/mil_common/perception/mil_vision/src/mil_vision_lib/colorizer/pcd_colorizer.cpp b/mil_common/perception/mil_vision/src/mil_vision_lib/colorizer/pcd_colorizer.cpp index a0bd83adb..14333e5e3 100644 --- a/mil_common/perception/mil_vision/src/mil_vision_lib/colorizer/pcd_colorizer.cpp +++ b/mil_common/perception/mil_vision/src/mil_vision_lib/colorizer/pcd_colorizer.cpp @@ -24,7 +24,7 @@ PcdColorizer::PcdColorizer(ros::NodeHandle nh, string input_pcd_topic) } catch (std::exception &e) { - _err_msg = "COLORIZER: Suscriber or publisher error caught: "_s + e.what(); + _err_msg = "COLORIZER: Subscriber or publisher error caught: "_s + e.what(); ROS_ERROR(_err_msg.c_str()); return; } diff --git a/mil_common/ros_alarms/nodes/alarm_server.py b/mil_common/ros_alarms/nodes/alarm_server.py index bb602304c..b3a023778 100755 --- a/mil_common/ros_alarms/nodes/alarm_server.py +++ b/mil_common/ros_alarms/nodes/alarm_server.py @@ -178,9 +178,9 @@ def _create_alarm_handlers(self): if alarm_name in self.alarms: self.alarms[alarm_name].update(h.initial_alarm) else: - self.alarms[ - alarm_name - ] = h.initial_alarm # Update even if already added to server + self.alarms[alarm_name] = ( + h.initial_alarm + ) # Update even if already added to server elif ( alarm_name not in self.alarms ): # Add default initial if not there already diff --git a/mil_common/ros_alarms/ros_alarms/__init__.py b/mil_common/ros_alarms/ros_alarms/__init__.py index 600cc75c8..9f257faae 100644 --- a/mil_common/ros_alarms/ros_alarms/__init__.py +++ b/mil_common/ros_alarms/ros_alarms/__init__.py @@ -39,6 +39,7 @@ Topic publishing any getting/setting updates that occur on alarms. """ + from .alarms import ( Alarm, AlarmBroadcaster, diff --git a/mil_common/ros_alarms/test/roscpp/listener_test.cpp b/mil_common/ros_alarms/test/roscpp/listener_test.cpp index 2138546e5..f365a1305 100644 --- a/mil_common/ros_alarms/test/roscpp/listener_test.cpp +++ b/mil_common/ros_alarms/test/roscpp/listener_test.cpp @@ -51,7 +51,7 @@ TEST(ListenerTest, listenerTest) ab.getAlarm() = pxy; ab.clear(); // alarm starts off cleared - // Last update time happened wehen we called ab.clear() + // Last update time happened when we called ab.clear() auto first_query = listener.getLastUpdateTime(); ab.updateSeverity(5); // This is an update to the alarm diff --git a/mil_common/ros_alarms/test/rospy/python_tests.py b/mil_common/ros_alarms/test/rospy/python_tests.py index 9c29a7305..c11b0f061 100755 --- a/mil_common/ros_alarms/test/rospy/python_tests.py +++ b/mil_common/ros_alarms/test/rospy/python_tests.py @@ -17,7 +17,7 @@ def __init__(self, *args): super().__init__(*args) """ Tests alarm client operations - Creates some listeners and some broadcasters and tests various raising and clearing conditoins + Creates some listeners and some broadcasters and tests various raising and clearing conditions Also tests various combination of parameters """ @@ -142,7 +142,7 @@ def test_callbacks(self): self.cleared = False self.both = False - # Make sure callbacks run when they're suppsed to + # Make sure callbacks run when they're supposed to ab_a.raise_alarm() rospy.sleep(0.5) diff --git a/mil_common/utils/mil_tools/mil_misc_tools/download.py b/mil_common/utils/mil_tools/mil_misc_tools/download.py index 85001f69a..fbf3fe61d 100644 --- a/mil_common/utils/mil_tools/mil_misc_tools/download.py +++ b/mil_common/utils/mil_tools/mil_misc_tools/download.py @@ -11,6 +11,7 @@ [3] Download a file via http http://stackoverflow.com/questions/22676 """ + import io as StringIO import os import urllib.request diff --git a/mil_common/utils/mil_tools/mil_ros_tools/cv_debug.py b/mil_common/utils/mil_tools/mil_ros_tools/cv_debug.py index 275abf969..b5695ded9 100644 --- a/mil_common/utils/mil_tools/mil_ros_tools/cv_debug.py +++ b/mil_common/utils/mil_tools/mil_ros_tools/cv_debug.py @@ -1,6 +1,7 @@ """ Shows images for debugging purposes. """ + import sys from typing import Optional diff --git a/mil_common/utils/mil_tools/mil_ros_tools/image_helpers.py b/mil_common/utils/mil_tools/mil_ros_tools/image_helpers.py index 22f8eac56..45e12b931 100644 --- a/mil_common/utils/mil_tools/mil_ros_tools/image_helpers.py +++ b/mil_common/utils/mil_tools/mil_ros_tools/image_helpers.py @@ -98,7 +98,7 @@ class Image_Subscriber: last_image_time (genpy.Time): The time of the last image received. im_sub (rospy.Subscriber): The subscriber to the image topic. The topic name and queue size are received through the constructor. - info_sub (rospy.Susbcriber): The subscriber to the camera info topic. + info_sub (rospy.Subscriber): The subscriber to the camera info topic. The topic name is derived from the root of the supplied topic and the queue size is derived from the constructor. bridge (CvBridge): The bridge between OpenCV and ROS. diff --git a/mil_common/utils/mil_tools/mil_ros_tools/init_helpers.py b/mil_common/utils/mil_tools/mil_ros_tools/init_helpers.py index 0a8541fd6..789b36153 100644 --- a/mil_common/utils/mil_tools/mil_ros_tools/init_helpers.py +++ b/mil_common/utils/mil_tools/mil_ros_tools/init_helpers.py @@ -2,6 +2,7 @@ This module provides functions which help to ensure that resources are available when needed. """ + import time from typing import Any, Optional diff --git a/mil_common/utils/mil_tools/mil_ros_tools/label_me_bag.py b/mil_common/utils/mil_tools/mil_ros_tools/label_me_bag.py index 4e6c7231c..aa7f91142 100755 --- a/mil_common/utils/mil_tools/mil_ros_tools/label_me_bag.py +++ b/mil_common/utils/mil_tools/mil_ros_tools/label_me_bag.py @@ -53,13 +53,13 @@ def __init__(self, config): self.topics = config["topics"] if not isinstance(self.topics, list): self.topics = [self.topics] - self.start = config["start"] if "start" in config else None - self.stop = config["stop"] if "stop" in config else None - self.freq = config["freq"] if "freq" in config else None + self.start = config.get("start") + self.stop = config.get("stop") + self.freq = config.get("freq") self.name = ( config["name"] if "name" in config else self.default_name(self.filename) ) - self.outfile = config["outfile"] if "outfile" in config else self.filename + self.outfile = config.get("outfile", self.filename) class BagToLabelMe: diff --git a/mil_common/utils/mil_tools/test/test_ros_tools.py b/mil_common/utils/mil_tools/test/test_ros_tools.py index bbcc5511b..2c0eeeca5 100644 --- a/mil_common/utils/mil_tools/test/test_ros_tools.py +++ b/mil_common/utils/mil_tools/test/test_ros_tools.py @@ -131,10 +131,7 @@ def test_make_rotation(self): [0.0, 0.0, 0.0], np.cross(p_rotated, q), atol=1e-5, - err_msg="The generated rotation matrix did not align the input vectors, {} to {}".format( - p, - q, - ), + err_msg=f"The generated rotation matrix did not align the input vectors, {p} to {q}", ) self.assertGreater( np.dot(p_rotated, q), diff --git a/ruff.toml b/ruff.toml index 0ec9c21f1..56794e48d 100644 --- a/ruff.toml +++ b/ruff.toml @@ -28,6 +28,7 @@ extend-exclude = [ target-version = "py38" +[lint] ignore = [ "E501", # Line length "F405", # Unknown import From d753bd4559210dd046a8b2adf5a4e9fb63c9417c Mon Sep 17 00:00:00 2001 From: cameron brown <52760912+cbrxyz@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:14:34 -0500 Subject: [PATCH 12/25] Fix pip3 in CI (#1135) * Re-install python3-pip before installing all deps * Re-install python3-pip before installing all deps * Update setup script * Update ci.yaml --- .github/workflows/ci.yaml | 1 + scripts/install.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a99604c0e..de7c09a7a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -31,6 +31,7 @@ jobs: - name: Configure catkin workspace folder structure run: | mkdir -p $GITHUB_WORKSPACE/catkin_ws/src + sudo apt reinstall python3-pip - name: Check out code from GitHub uses: actions/checkout@v3.0.2 with: diff --git a/scripts/install.sh b/scripts/install.sh index 8a95fdf55..94e07590c 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -185,6 +185,7 @@ EOF # Documentation dependencies mil_system_install python3-pip python3-setuptools +sudo apt reinstall -y python3-pip # Disable "automatic updates" Ubuntu prompt (thanks to https://askubuntu.com/a/610623!) sudo sed -i 's/Prompt=.*/Prompt=never/' /etc/update-manager/release-upgrades From 30f5377a483d54426e8845a332fc57e1361f8c12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 00:01:39 -0500 Subject: [PATCH 13/25] Bump aiohttp from 3.8.5 to 3.9.2 (#1119) Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.8.5 to 3.9.2. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.8.5...v3.9.2) --- updated-dependencies: - dependency-name: aiohttp 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 88d330b91..aac5fd48a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,7 +22,7 @@ PyYAML==6.0 urdf-parser-py==0.0.4 # Internet -aiohttp==3.8.5 +aiohttp==3.9.2 aiohttp-xmlrpc==1.5.0 # Documentation From 8436d3997fd17db9e94915ce7fac57246263a37b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 17 Feb 2024 00:02:09 -0500 Subject: [PATCH 14/25] Bump pillow from 10.0.1 to 10.2.0 (#1111) Bumps [pillow](https://github.com/python-pillow/Pillow) from 10.0.1 to 10.2.0. - [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/10.0.1...10.2.0) --- 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 aac5fd48a..6ff0b0ecc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ scipy==1.10.0 scikit-learn==1.1.1 # Computer Vision -Pillow==10.0.1 +Pillow==10.2.0 # File Handling PyYAML==6.0 From 60679254ad256446e729619960f5cd3be1fd3e9f Mon Sep 17 00:00:00 2001 From: cameron brown <52760912+cbrxyz@users.noreply.github.com> Date: Wed, 21 Feb 2024 19:23:02 -0500 Subject: [PATCH 15/25] Update axros version (#1136) --- mil_common/axros | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From bfd946ff43b8d61b338bae60cad59b0352d9fe7c Mon Sep 17 00:00:00 2001 From: PRANETALLU <92874312+PRANETALLU@users.noreply.github.com> Date: Wed, 21 Feb 2024 21:13:35 -0500 Subject: [PATCH 16/25] Simulation raise switch (#1057) * Types and Docstring update * Update navigator_emergency.py * changed to raise exception --------- Co-authored-by: Cameron Brown Co-authored-by: cameron brown <52760912+cbrxyz@users.noreply.github.com> --- .../navigator_emergency_control/nodes/navigator_emergency.py | 3 +-- .../sub8_thrust_and_kill_board/simulation.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/NaviGator/utils/remote_control/navigator_emergency_control/nodes/navigator_emergency.py b/NaviGator/utils/remote_control/navigator_emergency_control/nodes/navigator_emergency.py index 0bd27c291..49b799fa4 100755 --- a/NaviGator/utils/remote_control/navigator_emergency_control/nodes/navigator_emergency.py +++ b/NaviGator/utils/remote_control/navigator_emergency_control/nodes/navigator_emergency.py @@ -67,8 +67,7 @@ def reset(self) -> None: def check_for_timeout(self, joy: Joy): """ - Consists of several procedures that reference parameters that are retrieved from the "Joy" object in - order to determine the state of the controller or whether it is a timeout phase. + This checks for a particular duration when the controller times out. Args: joy (Joy): The Joy message. diff --git a/SubjuGator/drivers/sub8_thrust_and_kill_board/sub8_thrust_and_kill_board/simulation.py b/SubjuGator/drivers/sub8_thrust_and_kill_board/sub8_thrust_and_kill_board/simulation.py index 5f9d0f01f..83c595815 100644 --- a/SubjuGator/drivers/sub8_thrust_and_kill_board/sub8_thrust_and_kill_board/simulation.py +++ b/SubjuGator/drivers/sub8_thrust_and_kill_board/sub8_thrust_and_kill_board/simulation.py @@ -156,4 +156,4 @@ def on_data(self, data: bytes, can_id: int) -> None: packet = HeartbeatMessage.from_bytes(data) self._last_heartbeat = rospy.Time.now() else: - assert False, "No recognized identifier" + raise Exception("No recognized identifier") From 8483ec7f88e0ff51ede628ee9136120e28df9e73 Mon Sep 17 00:00:00 2001 From: PRANETALLU <92874312+PRANETALLU@users.noreply.github.com> Date: Wed, 21 Feb 2024 21:51:05 -0500 Subject: [PATCH 17/25] Read from csv debug (#1058) * Types and Docstring update * Update navigator_emergency.py * error exception added --------- Co-authored-by: Cameron Brown Co-authored-by: cameron brown <52760912+cbrxyz@users.noreply.github.com> --- .../perception/mil_vision/mil_vision_tools/color_classifier.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mil_common/perception/mil_vision/mil_vision_tools/color_classifier.py b/mil_common/perception/mil_vision/mil_vision_tools/color_classifier.py index c19e09c5e..3ff55caef 100755 --- a/mil_common/perception/mil_vision/mil_vision_tools/color_classifier.py +++ b/mil_common/perception/mil_vision/mil_vision_tools/color_classifier.py @@ -210,6 +210,8 @@ def read_from_csv(self, training_file: Optional[str] = None): Args: training_file (Optional[str]): The name of the training file. """ + if training_file is None: + raise NotImplementedError("Cannot read without any training file.") training_file = _get_param(training_file, self.training_file) df = pandas.read_csv(training_file) classes = df.values[:, 1] From b84c524bfb51bb0bad2bb1f5f1f534842278adcd Mon Sep 17 00:00:00 2001 From: cameron brown <52760912+cbrxyz@users.noreply.github.com> Date: Thu, 22 Feb 2024 17:46:04 -0500 Subject: [PATCH 18/25] Fix odom messages being converted to tf (#1137) --- mil_common/gnc/odometry_utils/src/odometry_to_tf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 953f0fcbd..6c2794453 100644 --- a/mil_common/gnc/odometry_utils/src/odometry_to_tf.cpp +++ b/mil_common/gnc/odometry_utils/src/odometry_to_tf.cpp @@ -21,7 +21,7 @@ class odometry_to_tf : public nodelet::Nodelet { 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) + if (_last_tf_stamps.count(msg->header.frame_id) && _last_tf_stamps[msg->header.frame_id] == msg->header.stamp) { return; } From 4474cf7c68c599d4dc4a11879d21904c55ffd719 Mon Sep 17 00:00:00 2001 From: Andres Pulido <52979429+andrespulido8@users.noreply.github.com> Date: Thu, 22 Feb 2024 23:25:39 -0500 Subject: [PATCH 19/25] add lessons learned from RoboSub23 nav tube documentation (#1072) * add lessons learned from RoboSub23 * include nav tube and lessons23 in index for doc * Remove duplication navigation tube doc from #1096 --------- Co-authored-by: Cameron Brown --- .../subjugator_missions/pose_editor.py | 8 ++++---- docs/subjugator/index.rst | 3 ++- docs/subjugator/lessons23.md | 13 +++++++++++++ docs/subjugator/{nav_tube.rst => navtube.rst} | 1 - 4 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 docs/subjugator/lessons23.md rename docs/subjugator/{nav_tube.rst => navtube.rst} (99%) diff --git a/SubjuGator/command/subjugator_missions/subjugator_missions/pose_editor.py b/SubjuGator/command/subjugator_missions/subjugator_missions/pose_editor.py index 6eafca064..ee2562491 100644 --- a/SubjuGator/command/subjugator_missions/subjugator_missions/pose_editor.py +++ b/SubjuGator/command/subjugator_missions/subjugator_missions/pose_editor.py @@ -617,8 +617,8 @@ def as_PoseTwist( def as_PoseTwistStamped( self, - linear: Sequence[int] = [0, 0, 0], - angular: Sequence[int] = [0, 0, 0], + linear: Sequence[float] = [0, 0, 0], + angular: Sequence[float] = [0, 0, 0], ) -> PoseTwistStamped: """ Returns a :class:`~mil_msgs.msg.PoseTwist` message class with the pose @@ -639,8 +639,8 @@ def as_PoseTwistStamped( def as_MoveToGoal( self, - linear: Sequence[int] = [0, 0, 0], - angular: Sequence[int] = [0, 0, 0], + linear: Sequence[float] = [0, 0, 0], + angular: Sequence[float] = [0, 0, 0], **kwargs, ) -> MoveToGoal: return MoveToGoal( diff --git a/docs/subjugator/index.rst b/docs/subjugator/index.rst index 7a9416713..7d60efae4 100644 --- a/docs/subjugator/index.rst +++ b/docs/subjugator/index.rst @@ -16,7 +16,7 @@ SubjuGator 8 Enabling Cameras PID Controller - Nav Tube + Navigation Tube Watercooling electrical @@ -28,5 +28,6 @@ RoboSub RoboSub + Lessons from 2023 Lessons from 2022 Lessons from 2019 diff --git a/docs/subjugator/lessons23.md b/docs/subjugator/lessons23.md new file mode 100644 index 000000000..815f04766 --- /dev/null +++ b/docs/subjugator/lessons23.md @@ -0,0 +1,13 @@ +# Lessons from RoboSub 2023 + +Paraphrasing Dan Frank, “it's clear that if we had made all these mistakes back in Gainesville, we could have been in way better shape for the competition”. + +* **Make a plan and be familiar with the sub** - We should create a solid checklist that spells out all the basic stuff we need to nail before we leave. This should cover nailing down sub moves commands, getting familiar with the missions we already have written, testing those missions in the pool, and making sure our kill system is on point and integrates well with our software. Having a game plan for finals that's solid and picking out a reliable run that can get enough points to really boost our chances is really important. Let's not leave our presentation prep for the last minute – we need to make the presentation and practice at least a week before the competition hits. We should have deadlines for all of these. + +* **Make a plan and be familiar with the sub** - We need to have a Plan B when someone can't make it or falls sick. At least 2-3 people need to be able to rock the sub operation, change and charge batteries, replace mechanical things, etc. Roles in the team need to be crystal clear during the competition. + +* **Track issues and maintenance of parts** - We should track intermitten issues; investigate them, and deal with them, before leaving. The issues showed up every now and then, but we brushed them off thinking they’ll go away. They should've been solved earlier. Also we need a proper log of when we're swapping out parts or using them. That way, we know when it's time for replacements. We only made the move of MacArtney connector switch after stumbling on a Slack conversation from 2019. Having a grip on the tether's age would've helped sort things out sooner. + +* **Easier debugging and Sub Status** - When hardware kills don't unkill after rebooting and sticking the kill wand back in, we should've cracked open those CAN messages to see what was going wrong. Having all this info on a screen or sent to our computers would've made life simpler. About lights and screens, having status symbols or messages on screens for errors or warnings from each board would make debugging easier. Same goes for side lights on the sub – they'd be useful for the electrical and softwar. + +* **Document** - Since hardware takes more effort than firmware, we could try to make it easier to write working prototype firmware to have more time for making hardware. We currently have MIL written drivers, but they have inconsistent documentation and are confusing for some members to use (especially the ones for CAN). diff --git a/docs/subjugator/nav_tube.rst b/docs/subjugator/navtube.rst similarity index 99% rename from docs/subjugator/nav_tube.rst rename to docs/subjugator/navtube.rst index 0456994ec..caf58ad2b 100644 --- a/docs/subjugator/nav_tube.rst +++ b/docs/subjugator/navtube.rst @@ -12,7 +12,6 @@ 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. From ede30bddc00d93dac85894d25eae90395abb4072 Mon Sep 17 00:00:00 2001 From: Cameron Brown Date: Sat, 24 Feb 2024 21:31:44 -0500 Subject: [PATCH 20/25] Add aptitude as installed package, cmonly for building just one package at a time with catkin_make --- scripts/install.sh | 3 ++- scripts/setup.bash | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/install.sh b/scripts/install.sh index 94e07590c..f9db76c6b 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -244,7 +244,8 @@ mil_user_install_dependencies() { nmap \ fd-find \ ripgrep \ - fzf + fzf \ + aptitude } # Add line to user's bashrc which source the repo's setup files diff --git a/scripts/setup.bash b/scripts/setup.bash index 97d54f7da..f164bb84d 100755 --- a/scripts/setup.bash +++ b/scripts/setup.bash @@ -99,6 +99,15 @@ startxbox() { roslaunch navigator_launch shore.launch } +# catkin_make for one specific package only +RED='\033[0;31m' +cmonly() { + cd ~/catkin_ws || exit + catkin_make --only-pkg-with-deps $1 + cd - >/dev/null || exit + echo "${RED}!! Warning: Future calls to catkin_make will just build the '$1' package. To revert this, ensure you run 'cm' or 'cd ~/catkin_ws && catkin_make -DCATKIN_WHITELIST_PACKAGES=\"\"' when you want to recompile the entire repository." +} + alias xbox=startxbox # PYTHONPATH modifications From 824c48143810ad14b5c7cb3fcca45eec9a8dc09c Mon Sep 17 00:00:00 2001 From: Ethan Haengel <58488884+Haengele@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:12:10 -0500 Subject: [PATCH 21/25] Added respawn delay to connector nodes (#1044) * Added respawn delay to connector nodes * Changed errors in DVL, IMU, and Depth Sensor drivers to ROS_ERROR_THROTTLE --- .../subjugator_launch/launch/subsystems/nav_box.launch | 6 +++--- .../sub8_adis16400_imu/include/adis16400_imu/driver.h | 4 ++-- .../drivers/sub8_depth_driver/include/depth_driver/driver.h | 6 +++--- .../sub8_rdi_dvl/include/rdi_explorer_dvl/driver.hpp | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/SubjuGator/command/subjugator_launch/launch/subsystems/nav_box.launch b/SubjuGator/command/subjugator_launch/launch/subsystems/nav_box.launch index 3dee6ee81..fe18b292d 100644 --- a/SubjuGator/command/subjugator_launch/launch/subsystems/nav_box.launch +++ b/SubjuGator/command/subjugator_launch/launch/subsystems/nav_box.launch @@ -7,7 +7,7 @@ - + @@ -17,7 +17,7 @@ - + @@ -26,7 +26,7 @@ - + diff --git a/SubjuGator/drivers/sub8_adis16400_imu/include/adis16400_imu/driver.h b/SubjuGator/drivers/sub8_adis16400_imu/include/adis16400_imu/driver.h index c8fd95b78..dc5146e7f 100644 --- a/SubjuGator/drivers/sub8_adis16400_imu/include/adis16400_imu/driver.h +++ b/SubjuGator/drivers/sub8_adis16400_imu/include/adis16400_imu/driver.h @@ -41,7 +41,7 @@ class Device } catch (const std::exception &exc) { - ROS_ERROR("error on open(%s): %s; reopening after delay", port.c_str(), exc.what()); + ROS_ERROR_THROTTLE(5, "error on open(%s): %s; reopening after delay", port.c_str(), exc.what()); boost::this_thread::sleep(boost::posix_time::seconds(1)); return false; } @@ -62,7 +62,7 @@ class Device } catch (const std::exception &exc) { - ROS_ERROR("error on read: %s; reopening", exc.what()); + ROS_ERROR_THROTTLE(5, "error on read: %s; reopening", exc.what()); open(); return false; } diff --git a/SubjuGator/drivers/sub8_depth_driver/include/depth_driver/driver.h b/SubjuGator/drivers/sub8_depth_driver/include/depth_driver/driver.h index 26cca97c3..2f4468091 100644 --- a/SubjuGator/drivers/sub8_depth_driver/include/depth_driver/driver.h +++ b/SubjuGator/drivers/sub8_depth_driver/include/depth_driver/driver.h @@ -69,7 +69,7 @@ class Device } catch (const std::exception &exc) { - ROS_ERROR("error on write: %s; dropping", exc.what()); + ROS_ERROR_THROTTLE(5, "error on write: %s; dropping", exc.what()); } } @@ -82,7 +82,7 @@ class Device } catch (const std::exception &exc) { - ROS_ERROR("error on read: %s; reopening", exc.what()); + ROS_ERROR_THROTTLE(5, "error on read: %s; reopening", exc.what()); open(); return false; } @@ -98,7 +98,7 @@ class Device } catch (const std::exception &exc) { - ROS_ERROR("error on open(%s): %s; reopening after delay", port.c_str(), exc.what()); + ROS_ERROR_THROTTLE(5, "error on open(%s): %s; reopening after delay", port.c_str(), exc.what()); boost::this_thread::sleep(boost::posix_time::seconds(1)); } } diff --git a/SubjuGator/drivers/sub8_rdi_dvl/include/rdi_explorer_dvl/driver.hpp b/SubjuGator/drivers/sub8_rdi_dvl/include/rdi_explorer_dvl/driver.hpp index 914706c44..80e9cf973 100644 --- a/SubjuGator/drivers/sub8_rdi_dvl/include/rdi_explorer_dvl/driver.hpp +++ b/SubjuGator/drivers/sub8_rdi_dvl/include/rdi_explorer_dvl/driver.hpp @@ -48,7 +48,7 @@ class Device } catch (const std::exception &exc) { - ROS_ERROR_THROTTLE(0.5, "DVL: error on read: %s; reopening serial port", exc.what()); + ROS_ERROR_THROTTLE(5, "DVL: error on read: %s; reopening serial port", exc.what()); open(); return false; } @@ -86,7 +86,7 @@ class Device } catch (const std::exception &exc) { - ROS_ERROR("DVL: error on open(port=%s): %s; reopening after delay", port.c_str(), exc.what()); + ROS_ERROR_THROTTLE(5, "DVL: error on open(port=%s): %s; reopening after delay", port.c_str(), exc.what()); boost::this_thread::sleep(boost::posix_time::seconds(1)); } } @@ -268,7 +268,7 @@ class Device } catch (const std::exception &exc) { - ROS_ERROR_THROTTLE(0.5, "DVL: error on write: %s; dropping heartbeat", exc.what()); + ROS_ERROR_THROTTLE(5, "DVL: error on write: %s; dropping heartbeat", exc.what()); } } From 39b16375e938487fb8e125f33a9a02ceb69abb26 Mon Sep 17 00:00:00 2001 From: Andrew Knee Date: Fri, 1 Mar 2024 19:45:49 -0500 Subject: [PATCH 22/25] removed padding between struct members (#1150) --- .../sub9_thrust_and_kill_board/packets.py | 6 +++--- .../drivers/mil_usb_to_can/mil_usb_to_can/sub9/packet.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/SubjuGator/drivers/sub9_thrust_and_kill_board/sub9_thrust_and_kill_board/packets.py b/SubjuGator/drivers/sub9_thrust_and_kill_board/sub9_thrust_and_kill_board/packets.py index f609c1c42..93d892fd3 100644 --- a/SubjuGator/drivers/sub9_thrust_and_kill_board/sub9_thrust_and_kill_board/packets.py +++ b/SubjuGator/drivers/sub9_thrust_and_kill_board/sub9_thrust_and_kill_board/packets.py @@ -19,7 +19,7 @@ class HeartbeatReceivePacket(Packet, msg_id=0x02, subclass_id=0x01, payload_form @dataclass -class ThrustSetPacket(Packet, msg_id=0x02, subclass_id=0x02, payload_format="Bf"): +class ThrustSetPacket(Packet, msg_id=0x02, subclass_id=0x02, payload_format="=Bf"): """ Packet to set the speed of a specific thruster. @@ -71,7 +71,7 @@ class KillStatus(IntEnum): @dataclass -class KillSetPacket(Packet, msg_id=0x02, subclass_id=0x03, payload_format="BB"): +class KillSetPacket(Packet, msg_id=0x02, subclass_id=0x03, payload_format="=BB"): """ Packet sent by the motherboard to set/unset the kill. @@ -85,7 +85,7 @@ class KillSetPacket(Packet, msg_id=0x02, subclass_id=0x03, payload_format="BB"): @dataclass -class KillReceivePacket(Packet, msg_id=0x02, subclass_id=0x04, payload_format="BB"): +class KillReceivePacket(Packet, msg_id=0x02, subclass_id=0x04, payload_format="=BB"): """ Packet sent by the motherboard to set/unset the kill. diff --git a/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub9/packet.py b/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub9/packet.py index 59ddc3a72..06f625b9b 100644 --- a/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub9/packet.py +++ b/mil_common/drivers/mil_usb_to_can/mil_usb_to_can/sub9/packet.py @@ -117,7 +117,7 @@ def _calculate_checksum(cls, data: bytes) -> tuple[int, int]: def __bytes__(self): payload = struct.pack(self.payload_format, *self.__dict__.values()) data = struct.pack( - f"BBBBH{len(payload)}s", + f"=BBBBH{len(payload)}s", SYNC_CHAR_1, SYNC_CHAR_2, self.msg_id, @@ -126,7 +126,7 @@ def __bytes__(self): payload, ) checksum = self._calculate_checksum(data[2:]) - return data + struct.pack("BB", *checksum) + return data + struct.pack("=BB", *checksum) @classmethod def from_bytes(cls, packed: bytes) -> Packet: @@ -141,12 +141,12 @@ def from_bytes(cls, packed: bytes) -> Packet: if msg_id in _packet_registry and subclass_id in _packet_registry[msg_id]: subclass = _packet_registry[msg_id][subclass_id] payload = packed[6:-2] - if struct.unpack("BB", packed[-2:]) != cls._calculate_checksum( + if struct.unpack("=BB", packed[-2:]) != cls._calculate_checksum( packed[2:-2], ): raise ChecksumException( subclass, - struct.unpack("BB", packed[-2:]), + struct.unpack("=BB", packed[-2:]), cls._calculate_checksum(packed[2:-2]), ) unpacked = struct.unpack(subclass.payload_format, payload) From 69be430f832db672105824a8599924a3b883d543 Mon Sep 17 00:00:00 2001 From: cameron brown <52760912+cbrxyz@users.noreply.github.com> Date: Fri, 1 Mar 2024 16:46:48 -0800 Subject: [PATCH 23/25] Update axros deps to include lookup_node (#1149) --- mil_common/axros | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mil_common/axros b/mil_common/axros index a4951d333..d0f12eedb 160000 --- a/mil_common/axros +++ b/mil_common/axros @@ -1 +1 @@ -Subproject commit a4951d33356c349856532ddef5c97c6ec6810c28 +Subproject commit d0f12eedb4622f5bbc5ba4fb63ae350f27a51f4b From 44997b74e7fdb06c543e517f8165d62249891344 Mon Sep 17 00:00:00 2001 From: gab-conde <108101811+gab-conde@users.noreply.github.com> Date: Sat, 2 Mar 2024 23:37:21 -0500 Subject: [PATCH 24/25] `OnlineBagger` documentation (#1070) * Move docstring into class * Add missing args/returns * Add attributes to class * Fix indentation error * Add OnlineBagger to docs * Fix nested if statements * Slight docs modifications --------- Co-authored-by: Cameron Brown Co-authored-by: cameron brown <52760912+cbrxyz@users.noreply.github.com> --- docs/reference/bagging.rst | 9 + docs/reference/index.rst | 1 + .../utils/mil_tools/nodes/online_bagger.py | 156 ++++++++++++++---- 3 files changed, 133 insertions(+), 33 deletions(-) create mode 100644 docs/reference/bagging.rst diff --git a/docs/reference/bagging.rst b/docs/reference/bagging.rst new file mode 100644 index 000000000..feb007dad --- /dev/null +++ b/docs/reference/bagging.rst @@ -0,0 +1,9 @@ +Online Bagger +------------- + +.. currentmodule:: mil_tools + +.. attributetable:: nodes.online_bagger.OnlineBagger + +.. autoclass:: nodes.online_bagger.OnlineBagger + :members: diff --git a/docs/reference/index.rst b/docs/reference/index.rst index b6f96f49e..c63581a0c 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -31,3 +31,4 @@ by MIL. These subsystems relate to a variety of processes. poi pneumatic sabertooth + bagging diff --git a/mil_common/utils/mil_tools/nodes/online_bagger.py b/mil_common/utils/mil_tools/nodes/online_bagger.py index 5a0c6bb32..5055d3a5f 100755 --- a/mil_common/utils/mil_tools/nodes/online_bagger.py +++ b/mil_common/utils/mil_tools/nodes/online_bagger.py @@ -1,11 +1,13 @@ #!/usr/bin/env python3 +from __future__ import annotations import argparse import datetime import itertools import os from collections import deque +from typing import TYPE_CHECKING import rosbag import rospy @@ -19,20 +21,30 @@ ) from tqdm import tqdm -""" -Online Bagger is a node which subscribes to a list of ros topics, -maintaining a buffer of the most recent n seconds. Parts or all of -these buffered topics can be written to a bag file by -sending a new goal to the /online_bagger/bag action server. - -When run with the -c flag, instead runs an action client which connects -to online bagger, triggering a bag write and displaying a progress bar -as it writes. - -""" +if TYPE_CHECKING: + import genpy class OnlineBagger: + """ + Node that maintains a list of bagged information relating to the specified + topics. + + Subscribes to a list of ROS topics, and maintains a buffer of the most recent + n seconds. Parts or all of these buffered topics can be written to a bag + file by sending a new goal to the /online_bagger/bag action server. When + run with the -c flag, instead runs an action client which connects to online + bagger, triggering a bag write and displaying a progress bar as it writes. + + Attributes: + successful_subscription_count (int): The number of successful subscriptions + to topics. + iteration_count (int): The number of iterations. + streaming (bool): Indicates whether the bagger is streaming. + subscriber_list (list[str]): The list of topics subscribed to the + OnlineBagger. + """ + BAG_TOPIC = "/online_bagger/bag" def __init__(self): @@ -67,6 +79,15 @@ def get_subscriber_list(self, status): """ Get string of all topics, if their subscribe status matches the input (True / False) Outputs each topics: time_buffer(float in seconds), subscribe_statue(bool), topic(string) + + Args: + status (bool): The subscription status used to search for topics with a matching + subscription status. + + Returns: + string: The list of topics that match the desired subscribe status. Each + line in the list contains the buffer time (in seconds) of the topic, the subscrition + status of the topic, and the topic name. """ sub_list = "" for topic in self.subscriber_list: @@ -99,10 +120,23 @@ def get_params(self): self.subscriber_list[topic[0]] = (time, False) def add_unique_topic(topic): + """ + Adds a topic to the subscriber list if the topic is not already in the + list. + + Args: + topic (str): The name of the topic to add to the subscriber list. + """ if topic not in self.subscriber_list: self.subscriber_list[topic] = (self.stream_time, False) def add_env_var(var): + """ + Adds topic(s) to the subscriber list. + + Args: + var (str): The topic(s) to add to the subscriber list. + """ for topic in var.split(): add_unique_topic(topic) @@ -189,7 +223,7 @@ def subscribe_loop(self): self.subscribe, ) - def subscribe(self, time_info=None): + def subscribe(self, _: rospy.timer.TimerEvent | None = None): """ Subscribe to the topics defined in the yaml configuration file @@ -200,13 +234,12 @@ def subscribe(self, time_info=None): Each element in self.subscriber list is a list [topic, Bool] where the Bool tells the current status of the subscriber (success/failure). - - Return number of topics that failed subscription """ - if self.successful_subscription_count == len(self.subscriber_list): - if self.resubscriber is not None: - self.resubscriber.shutdown() - rospy.loginfo("All topics subscribed too! Shutting down resubscriber") + if (self.successful_subscription_count == len(self.subscriber_list)) and ( + self.resubscriber is not None + ): + self.resubscriber.shutdown() + rospy.loginfo("All topics subscribed too! Shutting down resubscriber") for topic, (time, subscribed) in self.subscriber_list.items(): if not subscribed: @@ -221,18 +254,29 @@ def subscribe(self, time_info=None): self.subscriber_list[topic] = (time, True) - def get_topic_duration(self, topic): - """ - Return current time duration of topic + def get_topic_duration(self, topic: str): """ + Returns the current time duration of topic + + Args: + topic (str): The topic for which the duration will be calculated. + Returns: + Duration: The time duration of the topic. + """ return self.topic_messages[topic][-1][0] - self.topic_messages[topic][0][0] - def get_header_time(self, msg): + def get_header_time(self, msg: genpy.Message): """ Retrieve header time if available - """ + Args: + msg (genpy.Message): The ROS message from which to extract the time. + + Returns: + rospy.Time: The timestamp of the topic's header if the topic + has a header. Otherwise, the current time is returned. + """ if hasattr(msg, "header"): return msg.header.stamp else: @@ -240,7 +284,8 @@ def get_header_time(self, msg): def get_time_index(self, topic, requested_seconds): """ - Return the index for the time index for a topic at 'n' seconds from the end of the dequeue + Returns the index for the time index for a topic at 'n' seconds from the end of the dequeue. + For example, to bag the last 10 seconds of data, the index for 10 seconds back from the most recent message can be obtained with this function. The number of requested seconds should be the number of seoncds desired from @@ -248,6 +293,15 @@ def get_time_index(self, topic, requested_seconds): If the desired time length of the bag is greater than the available messages it will output a message and return how ever many seconds of data are available at the moment. Seconds is of a number type (not a rospy.Time type) (ie. int, float) + + Args: + topic (str): The name of the topic for which to get the time index. + requested_seconds (int/float): The number of seconds from the end of the dequeue to search + for the topic. + + Returns: + int: The index for the time index of the topic at requested_seconds seconds from the + end of the dequeue. """ topic_duration = self.get_topic_duration(topic).to_sec() @@ -259,12 +313,17 @@ def get_time_index(self, topic, requested_seconds): index = int(self.get_topic_message_count(topic) * (1 - min(ratio, 1))) return index - def bagger_callback(self, msg, topic): + def bagger_callback(self, msg: genpy.Message, topic: str): """ - Streaming callback function, stops streaming during bagging process - also pops off msgs from dequeue if stream size is greater than specified stream_time + Adds incoming messages to the appropriate topic and removes older messages if necessary. + + Streaming callback function, stops streaming during bagging process and pops off msgs + from dequeue if stream size is greater than specified stream_time. Stream, callback + function does nothing if streaming is not active. - Stream, callback function does nothing if streaming is not active + Args: + msg (genpy.Message): The incoming message. + topic (str): The topic to which the incoming message will be added. """ if not self.streaming: @@ -294,9 +353,16 @@ def bagger_callback(self, msg, topic): self.topic_messages[topic].popleft() time_diff = self.get_topic_duration(topic) - def get_topic_message_count(self, topic): + def get_topic_message_count(self, topic: str): """ Return number of messages available in a topic + + Args: + topic (str): The name of the topic for which to calculate the number + of messages. + + Returns: + int: The number of messages available in the specified topic. """ return len(self.topic_messages[topic]) @@ -304,8 +370,10 @@ def get_topic_message_count(self, topic): def get_total_message_count(self): """ Returns total number of messages across all topics - """ + Returns: + int: The total number of messages available in all topics. + """ total_message_count = 0 for topic in self.topic_messages: total_message_count = total_message_count + self.get_topic_message_count( @@ -315,14 +383,28 @@ def get_total_message_count(self): return total_message_count def _get_default_filename(self): + """ + Uses the current date and time to create a default bag name. + + Returns: + str: The default bag name constructed using format date-time. + """ return ( str(datetime.date.today()) + "-" + str(datetime.datetime.now().time())[0:8] ) - def get_bag_name(self, filename=""): + def get_bag_name(self, filename: str = ""): """ Create ros bag save directory If no bag name is provided, the current date/time is used as default. + + Args: + filename (str): The save directory for the ros bag. The default value + is an empty string, which will result in the default filename being + used. + + Returns: + str: A string representing the path of the ros bag file. """ # If directory param is not set, default to $HOME/bags/ default_dir = self.dir @@ -347,11 +429,19 @@ def get_bag_name(self, filename=""): bag_name = bag_name + ".bag" return os.path.join(bag_dir, bag_name) - def start_bagging(self, req): + def start_bagging(self, req: BagOnlineGoal): """ + Writes collected data to a bag file. + Dump all data in dictionary to bags, temporarily stops streaming during the bagging process, resumes streaming when over. - If bagging is already false because of an active call to this service + If bagging is already false because of an active call to this service. + + Args: + req (BagOnlineGoal): The bagging request information. + + Raises: + IOError: A problem occurs when opening or closing the bag file. """ result = BagOnlineResult() if self.streaming is False: From e58b169728066dc9f5a9b1be5a66d2b64f00e08f Mon Sep 17 00:00:00 2001 From: Mrinall Umasudhan Date: Mon, 4 Mar 2024 19:23:04 -0500 Subject: [PATCH 25/25] Improve Alarm Docs (#1073) * Update alarms.rst * Update alarms.rst * Update alarms.rst * Update alarms.rst * Update alarms.rst * Update and rename alarms.rst to alarmspart2.rst * Update and rename alarmspart2.rst to alarms.rst * Update index.rst * Update and rename alarms.rst to alarmspart2.rst * Create alarms.md * Update alarms.md * Update alarms.md * Create services.md * Update alarms.md * Update alarms.md * Update alarms.md * Update alarms.md * Update alarms.md * Update index.rst * Update alarms.md * Fix docs so script will build * Remove custom services docs page in order to avoid duplicating publicly available info about ROS * Format markdown file to remove long line lengths --------- Co-authored-by: Cameron Brown --- docs/software/alarms.md | 114 ++++++++++++++++++++++++++++++++++++++++ docs/software/index.rst | 1 + 2 files changed, 115 insertions(+) create mode 100644 docs/software/alarms.md diff --git a/docs/software/alarms.md b/docs/software/alarms.md new file mode 100644 index 000000000..80fb51485 --- /dev/null +++ b/docs/software/alarms.md @@ -0,0 +1,114 @@ +# Alarms in ROS + +In the realm of building dependable control systems, the importance of error detection +and effective error-handling mechanisms cannot be overstated. Within this context, +MIL presents a robust solution in the form of a live alarm system. This alarm system +operates discreetly in the background of both the robot's mission and driver codebases, +ready to be activated upon the emergence of errors. Notably, the alarm code doesn't +solely serve to identify and address errors; it can also adeptly manage changes +or updates that extend beyond error scenarios. + +## ROS Alarms: A Service-Oriented Architecture + +The architecture of ROS alarms distinguishes itself by employing a service-oriented +model rather than the usual topic-based approach. In ROS, Services act as the +conduits for interaction between nodes, functioning in a request-response manner. +While ROS topics enable asynchronous data exchange, services facilitate nodes in +seeking specific actions or information from other nodes, awaiting a subsequent +response before proceeding. This method of waiting before proceeding is known as a +synchronous data exchange. This proves especially valuable in tasks that require +direct engagement, such as data retrieval or computations. + +## Alarm System Logic + +The alarm system's functionality is more intricate than that of a typical ROS +service, which usually manages operations of base types (ints, strings, etc.). +In this scenario, the alarm's service server is engineered to manage the tasks +of updating, querying, and processing an alarm object. ROS alarms encompass two +distinct types of clients: the alarm broadcaster and the alarm listener. The +broadcaster initializes and triggers alarms in response to errors or changes, +while the listener monitors the broadcaster's activity and activates designated +a callback function when alarms are raised. The callback function should handle +the error or change appropriately. + +To successfully leverage alarms, the initialization of both the broadcaster and +listener is needed. The listener should be configured to execute a predefined +callback function, addressing errors or changes detected by the broadcaster. +Within your codebase, error detection and alarm-raising procedures should be +integrated. If orchestrated correctly, the callback function will be automatically +invoked, underscoring successful error mitigation. + +Note that there are several special properties that can be attached to your alarm. +Here are a couple of examples: +* When you raise an alarm you can assign a severity level to the alarm [0, 5]. +* You can attach multiple callback functions to the alarm. + * **This is where severity comes into play!** By specifying the required + severity level that is needed to execute the callback when initializing the + function, you can choose which callbacks are executed when the alarm is raised. + * You can also specify a range of severity levels that the alarm would need to + execute a given callback. + +Here is a line-by-line breakdown of an example alarm implementation: + +```python +ab = AlarmBroadcaster("test_alarm") +al = AlarmListener("test_alarm") +ab.clear_alarm() +rospy.sleep(0.1) +``` +This is how you would initialize the alarm broadcaster and listener. Here +make sure to clear any previous alarm data in the broadcaster. + +```python +al.add_callback(cb1) +``` +Make sure to establish the callback function that should be executed once +the alarm is activated. + +```python +ab.raise_alarm() +rospy.sleep(0.1) +assert al.is_raised() +assert cb1_ran +``` +When the alarm is sounded via the `raise_alarm()` function, the callback will be +executed automatically. + +```python +al.clear_callbacks() + +al.add_callback(cb1, severity_required=2) +al.add_callback(cb2, call_when_raised=False) + +rospy.loginfo("Severity Range Test 1") +ab.raise_alarm(severity=4) +rospy.sleep(0.1) +assert not cb1_ran +assert cb2_ran +cb2_ran = False + +rospy.loginfo("Severity Range Test 2") +ab.raise_alarm(severity=1) +rospy.sleep(0.1) +assert cb1_ran +assert not cb2_ran +cb1_ran = False +``` +Note that you can also attach some special properties to your alarm. For instance, +you can attach multiple callback functions to the alarm. You can also configure +whether the callback function should be automatically executed when the alarm is +raised or whether it should be executed manually. Finally, you can assign a +severity level to the alarm which can tell the alarm code which callback functions +should be run. + +## Applications and Context + +The applications of ROS alarms span various contexts, with one notable application +residing in the control of the submersible vehicle's thrust and killboard. The +thrust and killboard, responsible for the sub's electronic operations, is +integrally associated with ROS alarms. Upon the board's activation or deactivation +(hard or soft kill), alarms are invoked to apprise users of these changes. The +listener's callback function comes into play, ensuring that alarms are updated +in alignment with the board's current state. This process triggered each time +the board is deactivated, creates a system whereby users are continually informed +about the board's status changes – essentially manifesting a dynamic live alarm system. diff --git a/docs/software/index.rst b/docs/software/index.rst index 9e779a0eb..5b06f569e 100644 --- a/docs/software/index.rst +++ b/docs/software/index.rst @@ -15,6 +15,7 @@ Various documentation related to practices followed by the MIL Software team. asyncio rqt rostest + alarms Bash Style Guide C++ Style Guide Python Style Guide