Skip to content

Commit

Permalink
Major refactor for coordinated multi-winch, RBR support, hardware moc…
Browse files Browse the repository at this point in the history
…king, unit tests, config validation, and dev containers.

feat: Node and tests for validating configuration

feat: Added launch configuration

fix: config validation nodes executable, validate seatrac

fix: missing shebang

feat: Moved validation from nodes to start script

refactor: Multiple winches WIP. New conductor

refactor: Winch movement

refactor: Instrument actions

feat: Fixed service message locations

feat: Added arm controller for RBR

feat: Node for publishing UDP stream, corrected CTD paths

build: dev container configuration

feat: Multi-camera support

fix: config and build fixes found during testing

feat: Better buffering for RBR stream, service definition for running relay on another device

fix: service import and usage errors

debug: runtime progress

fix: Improved namespace handling, debug logging

fix: Moved instrument specific config to respective arms

fix: Include depth from RBR readings

feat: Misc fixes to paths and parameter passing

feat: Improves task behavior, eliminates race condition

refactor: Use semaphores and events instead of locks

feat: Will run scheduled depth when profile fails to gather enough data

feat: Nomenclature update: Instrument->Payload

feat: Convert state class to dataclass

refactor: reorganized task parameters in yaml

refactor: Move winch control to arm base class

feat: Move IFCB operation out of ARM for easier mocking

feat: Hardware mocking for local development/testing

feat: Upgrade aiohttp

fix: IFCB action call error, improvements to naming, loop locking

feat: Switch from queue to event-driven tasks. Add wiz_probe behavior

test: Unit tests for scheduled depth and wiz behaviors

feat: per-task winch speed, chanos arm using RBR sensor

feat: Removed files from old multiwinch method

fix: Removed unused srv folder/reference

fix: Ensure required version of setuptools is available

feat: Removed unused files/references

feat: Config validation skip switch for launch

feat: Moved mock nodes into their own directory

fix: Misc typos

fix: RBR base behavior fixes

refactor: Arm nodes are now launched independently of core PhytO-ARM nodes

refactor: phyto-arm start now takes a launchfile name arg

fix: Check correct semaphore signal

docs: Comments

doc: Updated documentation

feat: renamed arm launchfiles for consistency

feat: Adjusted chanos config for specific depths

feat: Better exceptions for out of bounds cases in arm base

feat: Added support for wiz probe depth offset config

docs: Better example depths

feat: Switched to named locking mechanism to allow crashed arms to reenter existing locks

feat: Convenience running scripts, fixes missing scripts from build

fix: Misc run script issues

fix: docker image ref

feat: Added development section to README

feat: A little more tolerance for malformed RBR messages

feat: Cleaned up example.yaml
  • Loading branch information
figuernd committed Feb 29, 2024
1 parent d7f493f commit a8d9fa5
Show file tree
Hide file tree
Showing 45 changed files with 2,086 additions and 665 deletions.
56 changes: 56 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-dockerfile
{
"name": "Existing Dockerfile",
"build": {
"context": "../",
// Sets the run context to one level up instead of the .devcontainer folder.
// Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
"dockerfile": "../Dockerfile"
},
"workspaceFolder": "/app",
"mounts": [
// Manually mount each file/folder from root of repo since just mounting the parent folder
// would result in the container ROS workspace being erased. Ugly workaround for now.
// Alternatively could use postStart commands to symlink the workspace folder. Might
// introduce other headaches.
"source=${localWorkspaceFolder}/src/aml_ctd,target=/app/src/aml_ctd,type=bind",
"source=${localWorkspaceFolder}/src/ifcb,target=/app/src/ifcb,type=bind",
"source=${localWorkspaceFolder}/src/jvl_motor,target=/app/src/jvl_motor,type=bind",
"source=${localWorkspaceFolder}/src/phyto_arm,target=/app/src/phyto_arm,type=bind",
"source=${localWorkspaceFolder}/src/rbr_maestro3_ctd,target=/app/src/rbr_maestro3_ctd,type=bind",
"source=${localWorkspaceFolder}/.gitignore,target=/app/.gitignore,type=bind",
"source=${localWorkspaceFolder}/configs,target=/app/configs,type=bind",
"source=${localWorkspaceFolder}/deps,target=/app/deps,type=bind",
"source=${localWorkspaceFolder}/.devcontainer,target=/app/.devcontainer,type=bind",
"source=${localWorkspaceFolder}/.git,target=/app/.git,type=bind",
"source=${localWorkspaceFolder}/LICENSE,target=/app/LICENSE,type=bind",
"source=${localWorkspaceFolder}/phyto-arm.service,target=/app/phyto-arm.service,type=bind",
"source=${localWorkspaceFolder}/.github,target=/app/.github,type=bind",
"source=${localWorkspaceFolder}/phyto-arm,target=/app/phyto-arm,type=bind",
"source=${localWorkspaceFolder}/scripts,target=/app/scripts,type=bind",
"source=/home/ifcb/IFCBacquire/Host/Routines,target=/routines,type=bind",
"source=/mnt/data,target=/mnt/data,type=bind"
],
"runArgs": [
"--device=/dev/ttyS3",
"--publish=9090:9090/tcp",
"--publish=8098:8098/tcp",
"--publish=12345:12345/udp"
]

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Uncomment the next line to run commands after the container is created.
// "postCreateCommand": "cat /etc/os-release",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "devcontainer"
}
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,9 @@ __pycache__
.venv
logs
configs
!configs/example.yaml
!configs/example.yaml

# Build artifacts in devcontainer after mount
apt-requirements.txt
deps.rosinstall
python3-requirements.txt
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ RUN apt update \

# Install Python dependencies
COPY deps/python3-requirements.txt ./
RUN pip install --upgrade setuptools==69.1.0
RUN python3 -m pip install -r python3-requirements.txt


Expand Down Expand Up @@ -49,6 +50,7 @@ RUN apt update \

# Copy the rest of the sources
COPY ./src ./src
COPY ./scripts ./scripts

# Build
RUN source ./devel/setup.bash \
Expand Down
335 changes: 245 additions & 90 deletions README.md

Large diffs are not rendered by default.

270 changes: 167 additions & 103 deletions configs/example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,69 +2,25 @@ name: Example


launch_args:
ctd: aml
log_dir: /mnt/data/roslogs/
rosbag_prefix: /mnt/data/rosbags/phyto-arm
winch: false
classifier: false


alerts:
# You can post alert messages to Slack by creating an Incoming Webhook for your channel:
# - type: slack
# url: https://hooks.slack.com/services/...
- type: slack
url: https://hooks.slack.com/services/...


# Node-specific configuration

gps:
host: "172.17.0.1"

conductor:
range:
min: 0.5 # m
max: 2.0 # m

# TODO: Currently unimplemented
speed:
transit: 0.02 # m/s
profile: 0.02 # m/s

# Minimum level of the profiled sensor data to trigger a sample at depth
threshold: 0.0

# Interval at which we run a cartridge debubble, necessary when IFCB on its side
cartridge_debubble_interval: 0 # minutes, 0 = never

# Interval at which we run a bead sample for maintenance
bead_interval: 1440 # minutes, 0 = never

# Scheduled depths are sampled once per time interval, or when the profile
# data does not exceed the configured threshold above.
#
# Note: Adjusting the scheduled depths after the node has started may resume
# from an arbitrary point in the new schedule.
schedule:
every: 60 # minutes, 0 = never
range:
first: 0.5 # m
last: 2.0 # m
count: 4

profiler:
resolution: 0.02 # m
data_topic: "/ctd/aml/port5/phycoerythrin"
data_field: "value"

# Note these values are not read by PhytO-ARM, they are sought by
# the included ds_util_nodes package, which publishes CTD data reads.
# https://bitbucket.org/whoidsl/ds_base/src/master/ds_util_nodes/
ctd_comms:
connection:
type: "SERIAL"
port: "/dev/ttyTHS0"
baud: 115200
data_bits: 8
lock_manager:
# Use this to control how many motors can be in motion at once.
max_moving_winches: 1

ifcb:
address: "172.17.0.1"
Expand All @@ -75,73 +31,181 @@ ifcb:
# container or namespace.
data_dir: "/mnt/data/ifcbdata"

# If launch_args.winch = true
motor:
address: "192.168.13.3"
port: 502
refresh_rate: 1 # hz
counts_per_turn: 8192 # defined in manual p.9

# If launch_args.classifier = true
classifier:
# Topic to get images which are sent to classifier
image_topic: "/ifcb/roi/image"
triton_server_url: "172.17.0.1:9001/"
classifier_model: "ifcb_iv3_onnx"
arm_ifcb:
# Configuration related to tasks
tasks:
phy_peak:
# Minimum level of the profiled sensor data to trigger a sample at depth
threshold: 0.0
scheduled_depth:
# Scheduled depths are sampled once per time interval, or when the profile
# data does not exceed the configured threshold above.
#
# Note: Adjusting the scheduled depths after the node has started may resume
# from an arbitrary point in the new schedule.
every: 60 # minutes, 0 = never
range:
first: 0.7 # m
last: 1.5 # m
count: 3
wiz_probe:
# List of times to sample the Wiz probe in UTC time. List can be any size
times:
- "12:00"
- "14:00"
- "16:00"
- "18:00"
# Minutes to hold this position
duration: 30
# For this number of minutes before the next time, no other tasks will be scheduled.
# Allows any existing tasks to complete and gives the winch time to move into position.
preparation_window: 15
# Use phycoerythrin peak to determine sample depth
use_phy_peak: true
# If use_phy_peak == true, then this is the offset from the peak to sample at.
# This is added directly to the phy_peak depth, so positive values add depth.
peak_offset: 0.5 # m
# Depth to sample at if phycoerythrin peak is not used, or if peak not found
# Ensure this value is within the winch range or PhytO-ARM will abort
default_depth: 1.0

ifcb_maintenance:
# Interval at which we run a cartridge debubble, necessary when IFCB on its side
cartridge_debubble_interval: 0 # minutes, 0 = never
# Interval at which we run a bead sample for maintenance
bead_interval: 1440 # minutes, 0 = never

ctd_topic: '/arm_ifcb/ctd/depth'

# Note these values are not read by PhytO-ARM, they are sought by
# the included ds_util_nodes package, which publishes CTD data reads.
# https://bitbucket.org/whoidsl/ds_base/src/master/ds_util_nodes/
ctd_comms:
connection:
type: "SERIAL"
port: "/dev/ttyS3"
baud: 115200
data_bits: 8

profiler:
resolution: 0.02 # m
data_topic: "/ctd/aml/port5/phycoerythrin"
data_field: "value"

motor:
address: "192.168.13.3"
port: 502
refresh_rate: 1 # hz
counts_per_turn: 8192 # defined in manual p.9

winch:
enabled: true

camera:
# Raymarine CAM220IP defaults
video_stream_url: "rtsp://admin:1234@192.168.13.30/h264"
range:
min: 0.7 # m
max: 1.5 # m

# The spool circumference is needed for an initial estimate of speed
spool_circumference: 0.6604 # m

# Used for calculating rpm_ratio = 60 * gear_ratio / spool_circumference
gear_ratio: 60

max_speed: 0.02 # m/s
# Distance from target at which we will reduce speed by half. This controls
# the sharpness of our velocity function. A smaller number produces a more
# abrupt stop.
half_speed_dist: 0.05 # m

winch:
# TODO: Almost none of these values are used yet!
# Distance from the target at which we are close enough to stop.
epsilon: 0.01 # m

# The spool circumference is needed for an initial estimate of speed
spool_circumference: 0.6604 # m
safety_envelopes:
position: 0.1 # meters
time: # Unused for now
extra_pct: 10.0
extra_sec: 10.0

gear_ratio: 60

max_speed: 0.02 # m/s
acceleration: 1 # m/s^2
arm_chanos:
tasks:
downcast:
speed: 0.005 # m/s
upcast:
stage_duration: 60 # seconds
stages:
- 1.5 # meters
- 1.0
- 0.7

# Distance from target at which we will reduce speed by half. This controls
# the sharpness of our velocity function. A smaller number produces a more
# abrupt stop.
half_speed_dist: 0.05 # m
ctd_topic: '/arm_chanos/ctd/depth'

# Distance from the target at which we are close enough to stop.
epsilon: 0.01 # m
motor:
address: "192.168.13.4"
port: 502
refresh_rate: 1 # hz
counts_per_turn: 8192 # defined in manual p.9

safety_envelopes:
time:
extra_pct: 10.0
extra_sec: 10.0
position: 0.1 # meters
winch:
enabled: true

range:
min: 0.7 # m
max: 1.5 # m

# The spool circumference is needed for an initial estimate of speed
spool_circumference: 0.6604 # m

# Used for calculating rpm_ratio = 60 * gear_ratio / spool_circumference
gear_ratio: 60

max_speed: 0.02 # m/s
# Distance from target at which we will reduce speed by half. This controls
# the sharpness of our velocity function. A smaller number produces a more
# abrupt stop.
half_speed_dist: 0.05 # m

# Distance from the target at which we are close enough to stop.
epsilon: 0.01 # m

safety_envelopes:
position: 0.1 # meters
time: # Unused for now
extra_pct: 10.0
extra_sec: 10.0


# If launch_args.classifier = true
classifier:
# Topic to get images which are sent to classifier
image_topic: "/ifcb/roi/image"
triton_server_url: "172.17.0.1:9001/"
classifier_model: "ifcb_iv3_onnx"

camera:
fore_camera:
video_stream_url: "rtsp://admin:example_password@192.168.13.123/"
aft_camera:
video_stream_url: "rtsp://admin:example_password@192.168.13.124/"

web:
field_map:
commitHash:
# Will get value from COMMIT_HASH environment variable
environment: COMMIT_HASH
# Default is optional for environment variables. Will error
# if variable does not exist and no default provided
default: 'No hash'
ctdDepth:
# Must have 'default' if not 'environment'
default: .nan
# Optional 'topic' to update value
topic: /ctd/depth
# Required only when 'topic' is used
topic_field: depth
gpsLatitude:
#optional indicates that a parameter will not be required to be present by the config validator
commitHash: #optional
environment: COMMIT_HASH #optional, get value from COMMIT_HASH environment variable
default: 'No hash' #optional for environment variables
ctdDepth: #optional
default: .nan # 'default' required if not using 'environment'
topic: /ctd/depth #optional, ROS topic to update value
topic_field: depth #optional unless 'topic' is used
gpsLatitude: #optional
topic: /gps/fix
topic_field: latitude
# Replace with desired default lat/long
default: -999999
gpsLongitude:
default: -999999 # Replace with desired default lat
gpsLongitude: #optional
topic: /gps/fix
topic_field: longitude
default: -999999
defaultOnly:
# No topic means this default value is permanent
default: 'static_value'
default: -999999 # Replace with desired default long
defaultOnlyExample: #optional
default: 'static_value' # No topic, making this default value permanent
Loading

0 comments on commit a8d9fa5

Please sign in to comment.