Skip to content

Technician Guide ​

Configuration, tuning and maintenance of HotDog on the Lynx M20

Version 1.02026-11-01 PDF (A5)

For the technician who commissions, tunes and maintains the robot: shell, YAML and ROS 2 basics assumed.

About this guide

The first bring-up of a robot and a site, step by step, is in docs/commissioning.md; the operators' tasks in the HotDog User Manual. This guide explains what each setting does, how to change it for good, and how to keep the robot fit. The parameter reference at the end is generated from the packages' config files.

VersionDateChanges
1.02026-11-01First version

How configuration works ​

Where a value comes from ​

Every node reads its parameters in layers; a later layer wins, parameter by parameter:

LayerFileHolds
package defaultssrc/<package>/config/*.yamlwhat every HotDog has
robot profilesrc/hotdog/config/robot.yaml (robot_params)the M20: footprint, height, limits, frames
the stack as tuned for HotDogsrc/hotdog/config/stack.yamlodometry only, the merged cloud, the hooks
this robot and site/etc/hotdog/site.yaml (PARAMS_FILE)what you tune: the only file you edit
launch arguments/etc/hotdog/hotdog.envaddresses, the site, secrets, what runs

The repository files are never edited on a robot: an update would undo the change or conflict with it. Everything this robot and this substation need goes into /etc/hotdog/site.yaml, under the node it belongs to, and survives updates.

The env file ​

/etc/hotdog/hotdog.env is read by the service and by scripts/env.sh (the hotdog command). No comments after a value; quotes around values with spaces.

VariableMeaning
ROBOT_IPthe M20's UDP server (10.21.31.103)
DRIVER_PARAMSthis robot's m20_driver calibration (/etc/hotdog/m20_driver.yaml)
PARAMS_FILEthis robot and site (/etc/hotdog/site.yaml)
ROBOT_PARAMSthis robot's profile when it differs (/etc/hotdog/robot.yaml)
SITE, SITES_DIRthe site to load; where the sites live (~/.hotdog/sites)
POD_IPthe UniPod MT11
HERTZINO_PASSWORDthe acoustic camera's password
TELEGRAM_BOT_TOKENthe alert bot
HOTDOG_WEBHOOK_TOKENbearer of the webhook
INSPECTION, PATROL, REPORTS, ALERTS, PODfalse leaves that part out (default true)
LIDARrslidar (both Airy) or external (clouds published elsewhere)
ROS_DOMAIN_ID, RMW_IMPLEMENTATION0, rmw_fastrtps_cpp

The file is mode 640: it holds secrets. After a change: hotdog restart.

The site file ​

yaml
# /etc/hotdog/site.yaml: GI Cawang, HotDog 01
path_follower_node:
  ros__parameters:
    speed.cruise: 0.4
inspection_node:
  ros__parameters:
    thermal:
      ambient_c: 31.0
patrol_node:
  ros__parameters:
    schedule:
      enabled: true
      times: ["06:00", "14:00", "22:00"]
      route: "2026-11-01_09-30-00"
report_node:
  ros__parameters:
    title: GI Cawang 150 kV
    robot_name: HotDog 01
alert_node:
  ros__parameters:
    robot_name: HotDog 01 - GI Cawang
    language: id
    report_url: http://10.21.31.50:8088/
    telegram:
      chat_ids: ["-1001234567890"]

At start the bringup merges the layers, reports a section that matches no node (a typo) and refuses values out of range with the reason; check hotdog logs after every change.

Try a value live, then keep it ​

Most parameters are live:

bash
source ~/dev/HotDog/scripts/env.sh
ros2 param describe /path_follower_node speed.cruise    # unit, range, live or not
ros2 param set /path_follower_node speed.cruise 0.35

A live change is lost at the next restart: write the value you settled on into the site file. A parameter marked read-only needs the site file and hotdog restart.

The M20 ​

The driver and its calibration ​

m20_driver talks to the M20's UDP server and turns cmd_vel into axis commands. Its own README has the verification on the real robot: the angle unit, standing, the emergency stop, the takeover by the remote, the speed calibration per gait, the signs of turning and strafing. Do it once per robot and keep the result in a copy of the bringup's driver file:

bash
sudo install -D -m 644 ~/dev/HotDog/src/hotdog/config/m20_driver.yaml /etc/hotdog/m20_driver.yaml
sudoedit /etc/hotdog/m20_driver.yaml      # angle_unit, full_scale.<gait>.*, invert_*

Keep odom_frame: camera_init, base_frame: body and publish_tf: true: they make the M20's odometry HotDog's odometry. HotDog patrols in the agile flat gait (stand_up_gait).

The robot profile and braking ​

src/hotdog/config/robot.yaml describes the M20 for every node: the footprint (body, legs and wheels, with the payload mounted), base_height, the speed and acceleration limits and the braking. The protective field, the planner's clearance and the LiDAR self filter follow from it. A robot whose payload sticks out further needs its own profile: copy the file to /etc/hotdog/robot.yaml, change it, and name it in the env file (ROBOT_PARAMS).

max_decel and reaction_time decide how early the robot brakes for an obstacle. Measure them (the Dharma hub's Robot Profile guide): drive at full patrol speed on the site's ground, stop, measure the distance. Keep max_decel at or below the measured deceleration and reaction_time at or above the measured delay. Gravel and wet concrete brake worse than the workshop floor.

Odometry only ​

HotDog maps nothing. The M20's dead reckoning is the odometry and the odometry start is the map origin: the dock.

  • Drift. The error grows with the distance walked; localization/status reports it as sigma_xy (hotdog status: drift). Check on the first patrols of a route that the robot stops where the stop points were taught; split routes that end up too far off.
  • Re-anchoring. Every patrol starts with localization/assume_origin at the dock (patrol_node start.reanchor). A robot moved by hand must be put back on the dock and re-anchored (hotdog anchor).
  • A driver restart resets the odometry. The odometry monitor reports it, localization drops to NONE, the follower pauses and the watchdog stops the patrol after abort.hold_timeout_sec.
  • Tags along a long route correct the drift: fiducials:=true with a calibrated camera and AprilTags recorded on the site (dharma_localization). Without them, keep routes short.

LiDARs and the protective field ​

The Airy ​

rslidar_sdk runs both RoboSense Airy from src/hotdog_base/config/rslidar.yaml: the front one on UDP 6699/7788, the rear one on 6698/7789, stamped on arrival (no PTP needed). cloud_merger_node merges them into /lidar/points in base_link: each input transformed by the URDF plus input_rpy_deg, the robot's own body removed (footprint, self_height for the pod and rails), leveled with the M20's IMU, cut to range_max and height_max. A stale input stops the merged cloud (require_all): perception then reports BLOCKED and the robot stops instead of driving half blind.

Check after mounting or replacing a LiDAR: in RViz the rear cloud lies behind the robot model and the ground stays flat at -base_height while the body tilts; else fix input_rpy_deg in the site file.

What counts as an obstacle ​

lidar_sector_node turns the merged cloud into 360° sectors between filter.height_min (0.15 m: gravel, kerbs, trench covers stay out) and filter.height_max (1.6 m) above the ground. Lower objects, pits and drops are not seen: the route must not need it.

The protective field ​

control_mux_node is the only publisher of /m20/cmd_vel. For every command it checks the 360° scan along the direction of motion with the footprint and the braking model: it slows the robot down (field LIMITED) and stops it (field STOP) so that it can always stop before the nearest obstacle. A stale or blind scan stops it too. The health monitor's speed limit and the latched e-stop apply to every source.

Test it after every change of the profile or the LiDARs, in an open area, at patrol speed: a person walks slowly towards the robot from the front, the back and each side; the robot must stop before them every time.

Patrols and the watchdog ​

Speed and stop points ​

Parameter (node)DefaultEffect
speed.cruise (path_follower_node)0.5m/s along the route; 0.3 for the first patrols of a route
hooks.inspection_timeout_sec (path_follower_node)180s the robot waits at most for the inspection of a stop
max_duration_sec (inspection_node)150s for all targets of a point; keep below the hook timeout
match_radius_m (inspection_node)1.5m, a stop this close to an inspection point inspects it

A stop point waits its dwell (taught, default 5 s) plus the inspection. Each target takes the gimbal settle time (2.5 s), the thermal samples and, with acoustic, the detection time (5 s).

The watchdog ​

patrol_node abort.*, every second while a patrol runs:

ParameterDefaultWhen exceeded
min_battery0.2back to the dock; keep above the follower's critical_battery (0.1)
max_duration_min120back to the dock; set it to about twice the route's duration
hold_timeout_sec180blocked: back to the dock; off the route or lost: stop
nav_timeout_sec5the follower is silent: stop
return_to_docktruefalse: every watchdog action stops the robot instead
near_m, dock_clearance_m2.0, 1.0where the way back starts and how far before the dock it ends

An operator pause, the e-stop or REMOTE is never overruled. The way back is the taught route, reversed from the nearest waypoint of its first pass, without stop points, into <site>/patrol/return.csv; then charge_start docks the M20.

The schedule ​

schedule.enabled, schedule.times (local time of the robot computer, HH:MM), schedule.route (empty: the route patrolled last) and schedule.window_min (a time missed by more than this is skipped). Keep them in the site file; operators switch the schedule on and off with hotdog schedule. The robot computer's time zone must be the substation's (timedatectl).

Thermal inspection ​

The pod ​

unipod_driver runs the UniPod MT11 in the /unipod namespace (POD_IP). inspection_node points it with set_angle and set_zoom, waits pod.settle_sec, refreshes the flat-field correction once per point (thermal.refresh_shutter) and asks the temperatures of boxes in thermal pixels. With the camera's AI super-resolution on, the thermal frame is 1280 × 1024: set thermal.width and thermal.height to match.

The MT11 gives temperatures per point, box and frame, not a radiometric image: the reports show the camera's colour picture as evidence, and the values come from the box measurements.

Targets in the inspection file ​

The operators teach targets with hotdog teach target; refine them in <sites_dir>/<site>/inspection.yaml (read at every inspection, no restart):

yaml
points:
  - name: bay1_disconnector
    x: 12.40
    y: -3.10
    targets:
      - name: bay1_ct_terminals
        pan_deg: -20.0
        tilt_deg: 5.0
        zoom: 2.0
        thermal:
          regions: # boxes in thermal pixels, compared with each other
            - { name: r, box: [80, 120, 200, 260] }
            - { name: s, box: [260, 120, 380, 260] }
            - { name: t, box: [440, 120, 560, 260] }
          max_temp_c: 95.0 # this part's own critical limit
        acoustic: { enabled: true, duration_sec: 8.0 }

Regions are better than strips when the phases are not evenly spread across the picture or other equipment shares the frame. Find the boxes on a thermal snapshot of the target (its report folder) at its zoom.

Limits ​

thermal.absolute, thermal.ambient, thermal.similar each hold attention, warning and critical in °C. The defaults follow the usual infrared inspection practice (NETA MTS):

CriterionValue judgedattention / warning / critical
absolutethe hottest temperature80 / 90 / 105 °C
ambientthe hottest temperature over thermal.ambient_c11 / 21 / 41 °C
similarthe hottest region over the median of the others2 / 4 / 16 °C

Use the substation owner's limits where they exist, and the equipment makers' limits for parts with their own (max_temp_c). Readings depend on the load: note in the site's records that limits were set for the usual load, and read rises over ambient with the load of the day.

thermal.ambient_c is live; operators set it every shift (hotdog ambient).

Partial discharge ​

The camera ​

The HZ-FA-371 is driven over its HTTP API (manual V5.1) by inspection_node; its ROS driver is ROS 1 only. Set up on the camera's web page once: partial discharge mode (gas leak mode is refused), the analysis band and the imaging threshold the manual gives for HV equipment. acoustic.host (factory 192.168.2.204), acoustic.port, acoustic.user; the password only in the env file (HERTZINO_PASSWORD).

One detection ​

For each acoustic target, after the robot stopped: a detection already running is stopped, the newest record noted, a detection of duration_sec started, the record appearing a whole detection later taken (an older one never), the detection stopped, the sound map and PRPD photos saved next to the report.

Severities ​

TypeDefaultParameter
noisenormal
coronaattentionacoustic.corona
surfacewarningacoustic.surface
floatingcriticalacoustic.floating

acoustic.intensity_warning and intensity_critical raise the severity by the sound map's intensity once the site's levels are known (0: off): record a few rounds first, then set them above the usual levels of healthy equipment.

Reports and alerts ​

Reports ​

report_node renders a page per patrol, a page per day and a front page, and serves ~/.hotdog/reports read-only on server.port (8088). title and robot_name name the site and the robot on every page. Retention: days older than retention.days (365), then the oldest days while less than retention.min_free_gb (5 GB) is free; never today. reports/rebuild renders every page again (after changing the title).

Keep what must be archived elsewhere: copy the day folders off the robot (with their images), e.g. weekly with rsync -a robot@<ip>:.hotdog/reports/ <archive>/.

Alerts ​

alert_node sends to the Telegram chats in telegram.chat_ids (the bot token in TELEGRAM_BOT_TOKEN) and to webhook.url. Set up a bot: @BotFather, add it to the crew's group, send a message there, read the group id (negative) from https://api.telegram.org/bot<token>/getUpdates. language: id writes the alerts in Bahasa Indonesia; report_url adds the link to the patrol page; findings.min_severity (warning) and findings.repeat_hours (12) decide what is sent. Alerts are spooled in ~/.hotdog/alerts and sent every retry_sec until delivered, for max_age_hours.

The robot computer needs outbound HTTPS to api.telegram.org; a proxy goes into the env file (HTTPS_PROXY=...).

Network, time and the service ​

Addresses and ports ​

Device / serviceAddress (default)Port
Lynx M2010.21.31.103UDP 30000
RoboSense Airy front / rearsend to the payload computerUDP 6699/7788, 6698/7789
UniPod MT1110.21.31.26 (factory 192.168.144.25)TCP 37260, RTSP 8554
Hertzinno HZ-FA-371192.168.2.204 (factory)HTTP 80
report serverthe payload computerTCP 8088
SSHthe payload computerTCP 22

The payload computer needs an address in each subnet (netplan, docs/commissioning.md). ROS 2 runs with rmw_fastrtps_cpp on domain 0.

Service commands ​

bash
sudo systemctl status hotdog          # running? since when?
hotdog logs                           # journalctl -fu hotdog
hotdog restart                        # sudo systemctl restart hotdog
scripts/setup.sh                      # every component: ok or missing

The service restarts HotDog 5 s after it stops for any reason and deletes ROS logs older than LOG_DAYS (7) at each start.

Time ​

Every stamp comes from the robot computer's clock: scripts/setup.sh install timesync (chrony) keeps it right and health/status warns when it drifts. The schedule runs on its local time: set the time zone with sudo timedatectl set-timezone Asia/Jakarta (or the site's).

Maintenance ​

Schedule ​

WhenTask
every shifthotdog status; ambient temperature; reports and alerts of the previous shift read
weeklyclean the Airy windows, the pod's lenses and thermal window, the acoustic camera's front with a soft, dry cloth; check the payload rails' fasteners; dock contacts clean; copy the reports off the robot
monthlyscripts/setup.sh; free disk (hotdog status: disk); a patrol watched end to end; the protective field test (section 4.3); stop point positions on the longest route
quarterlythermal check against a reference (a calibrated contact thermometer on a warm part, or a blackbody), within the pod maker's accuracy; acoustic camera against a known source; the M20's battery health and maintenance per its manual
yearlythe Site Acceptance Test again; the limits reviewed with the substation owner

Record every maintenance with its date and result.

Update the software ​

bash
cd ~/dev/HotDog
git pull
scripts/setup.sh install repos rosdep build
hotdog restart
scripts/setup.sh && hotdog status

Update with the robot on its dock and the schedule off; switch it on again after a patrol was watched end to end. Read the CHANGELOG first: a new parameter may need a value in the site file.

Back up and restore ​

WhatWhereWhy
the sites~/.hotdog/sites/routes and inspection points: hours of teaching
the robot's settings/etc/hotdog/ (env, site, driver)everything tuned on this robot
the reports~/.hotdog/reports/the inspection record
bash
sudo tar czf hotdog-backup-$(date +%Y%m%d).tgz /etc/hotdog ~/.hotdog/sites

Restore onto a new payload computer: install (docs/commissioning.md), unpack the archive, hotdog restart. A site taught on one M20 works on another only if its dock is the same.

Symptoms and fixes ​

SymptomCause and fix
the bringup stops at starthotdog logs: an unknown section, a value out of range, a missing file named in the env file
health WARN: a sensor below its ratethe LiDAR (ros2 topic hz /lidar/front/points), the M20 odometry (/m20/odom), the network cable
health ERROR: tf, odometry stalethe M20 driver lost the robot: ping $ROBOT_IP, the M20 switched on, /m20/state
field BLIND or STALE, robot does not movea LiDAR is down or its packets don't arrive: require_all stops the cloud; check both
the robot stops for nothingdust or rain on the Airy windows; filter.height_min too low on uneven ground; the self filter too small after a payload change
it drifts off the route in turnsspeed.cruise lower; the M20's speed calibration (driver README)
it stops short of the stop points far from the dockodometry drift: split the route, or tags
thermal values far from the referencelens dirty or wet; emissivity of the target (the pod's settings); the target's region misses the part
similar findings on equipment with one hot phase by designuse regions covering comparable parts only, or thermal: { enabled: true, strips: 0 }
acoustic: every target noise, known discharge missedthe camera's band and threshold; duration_sec longer; distance and direction of the target
acoustic: "gas leak mode"the camera's web page: partial discharge mode
alerts waiting, never senthotdog logs (alert not sent: HTTP 401: wrong token; 400: wrong chat id; network: no route or proxy)
reports server unreachablethe substation firewall (TCP 8088), server.host, another program on the port (hotdog logs)
disk fullretention.days lower, retention.min_free_gb; ROS logs are pruned at each start

Parameter reference ​

Every parameter of HotDog's own config files, with its default and what it does, read from the files themselves. Dharma's parameters are in each dharma_* repository's README; ros2 param describe /<node> <name> gives the unit, the range and whether it is live.

hotdog · robot.yaml ​

robot profile: footprint, limits, base height, frames · src/hotdog/config/robot.yaml

/** ​

ParameterDefaultMeaning
robot.namelynx_m20name of the robot profile
robot.kinematicsomnithe M20 walks and rolls in x, y and yaw
robot.base_height0.42m, base_link (body centre) above the ground when standing
robot.footprint.front0.43
robot.footprint.rear0.43
robot.footprint.half_width0.25
robot.limits.max_vx0.8m/s, patrol on gravel and cable trenches
robot.limits.max_vy0.3m/s
robot.limits.max_wz0.8rad/s
robot.limits.max_accel0.6m/s^2
robot.limits.max_decel0.8m/s^2, braking: measure it (Dharma hub, Robot Profile)
robot.limits.max_yaw_accel1.5rad/s^2
robot.limits.reaction_time0.35s, cmd_vel -> UDP axis command at 20 Hz -> RL controller
robot.frames.mapmapTF frame name
robot.frames.odomodomTF frame name
robot.frames.basebase_linkTF frame name

hotdog · m20_driver.yaml ​

the M20 driver as HotDog runs it · src/hotdog/config/m20_driver.yaml

/** ​

ParameterDefaultMeaning
robot_ip10.21.31.103the M20's UDP server on the wired payload network
odom_framecamera_initThe robot's own odometry is HotDog's odometry: the driver publishes it as the LiDAR- inertial estimators of Dharma do (camera_init -> body on TF), dharma_localization bridges it into odom -> base_link (body is imu_link, the identity of base_link in the URDF).
base_framebodyTF frame name
publish_tftrue
stand_up_gaitflat_agilePatrol in the agile flat gait: the protocol document recommends it for autonomy.
max_vx1.0m/s, above robot.limits (0.8): the control mux limits first
max_vy0.5
max_wz1.0
angle_unitautoset rad or deg once the driver logged which one this robot reports

hotdog · stack.yaml ​

the Dharma stack as tuned for HotDog: odometry only · src/hotdog/config/stack.yaml

odometry_monitor_node ​

ParameterDefaultMeaning
odom_topic/m20/odomthe driver's odometry is the estimator
imu_topic""planar odometry: no tilt check against the IMU
leg_odom_topic""nothing independent to compare it with
stale_sec0.5the motion report comes at 10 Hz

localization_node ​

ParameterDefaultMeaning
imu_frameimu_linkthe driver's body frame in the URDF (identity of base_link)
assume_start_origintruethe odometry start is the map origin: start at the dock
leveling.enabledfalsethe odometry is planar already
estimator.sigma_xy_per_sqrt_m0.05No corrections without tags: the state stays LOCALIZED and sigma only reports the drift. Re-anchor at the dock before every patrol (localization/assume_origin).
estimator.max_sigma_xy100.0
estimator.max_sigma_yaw_deg180.0
tag.auto_localizefalse
tag.auto_correctfalse

lidar_sector_node ​

ParameterDefaultMeaning
input.typepointcloud2
input.pointcloud_topic/lidar/pointshotdog_base cloud_merger_node, front and rear Airy
input.framebase_link
input.timeout_sec0.5
front.fov_deg360.0the rear Airy sees behind: avoidance while backing up too
front.range_max8.0
filter.level_sourcenonecloud_merger_node levels the cloud with the IMU
filter.height_min0.15m above the ground: gravel, kerbs and cable trench covers stay out
filter.height_max1.60
blind.min_points200

path_follower_node ​

ParameterDefaultMeaning
controllerholonomic
avoidance_modepath_shift
speed.cruise0.5m/s
inspection.reverse_distance_m0.0
hooks.inspection[/inspection/inspect]inspection_node at every stop point; a missing service never holds the patrol. The stop waits dwell + inspection_timeout_sec at most: above inspection_node max_duration_sec.
hooks.inspection_timeout_sec180.0

control_mux_node ​

ParameterDefaultMeaning
use_health_limittruescale commands by health/status speed_scale
remote_sources[handheld, dashboard]control/remote/<source>/cmd_vel

health_monitor_node ​

ParameterDefaultMeaning
nodes.expected[""]"topic:min_hz[:max_age_sec]" The bringup adds every node it starts, and the M20 driver's when it starts it.
degradation.rules["sensor:/lidar/points=0.5", "sensor:/m20/odom=0.5", "tf:*=0.5"]
clock.enabledtruethe offset of this computer's clock to its time source (scripts/setup.sh install timesync)

hotdog_base · base.yaml ​

both Airy as one leveled cloud · src/hotdog_base/config/base.yaml

cloud_merger_node ​

ParameterDefaultMeaning
inputs[/lidar/front/points, /lidar/rear/points]rslidar_sdk publishes one cloud per Airy (config/rslidar.yaml); the first input triggers the merged cloud, which perception (lidar_sector_node) and health read.
input_rpy_deg[0.0, 0.0, 0.0, 0.0, 0.0, 180.0]roll, pitch, yaw (deg) of each input on top of its URDF frame. The M20 model gives the rear LiDAR no rotation, but the rear Airy looks backwards: check both against their data (RViz, the robot in front of a wall) before the robot moves on its own.
output_topic/lidar/points
require_alltruea stale side stops the output: perception goes BLOCKED, not half blind
max_age_sec0.3
range_max30.0m from base_link
height_max2.5m above the floor
self_height0.6m above base_link: the pod and the payload rails
level_sourceimuthe M20's odometry is planar: level the cloud here, not from TF
imu_topic/m20/imu

hotdog_inspection · inspection.yaml ​

overheat analysis and partial discharge · src/hotdog_inspection/config/inspection.yaml

inspection_node ​

ParameterDefaultMeaning
enabledtruelive: false lets the stop points pass without inspection
sites_dir~/.hotdog/sites<site>/inspection.yaml: points (map frame) and their targets
reports_dir~/.hotdog/reports<day>/<time>_<point>/report.json + images, <day>/findings.csv
match_radius_m1.5a stop this close to a point inspects it (taught at the same spot)
max_duration_sec150.0per point: keep below the follower's hooks.inspection_timeout_sec
pod.namespace/unipodunipod_driver
pod.settle_sec2.5gimbal and zoom (auto focus) before measuring
thermal.ambient_c30.0live: the air temperature at the site (ros2 param set ... thermal.ambient_c 33.0)
thermal.width640MT11 thermal pixels (1280 x 1024 with AI super-resolution on)
thermal.height512
thermal.samples3per region, the median is used
thermal.refresh_shuttertrueflat-field correction once per point
thermal.absolute{attention: 80.0, warning: 90.0, critical: 105.0}degC
thermal.ambient{attention: 11.0, warning: 21.0, critical: 41.0}degC over ambient_c
thermal.similar{attention: 2.0, warning: 4.0, critical: 16.0}degC over the other phases
acoustic.enabledtruelive
acoustic.host192.168.2.204factory address; this computer needs an address in 192.168.2.x
acoustic.port80
acoustic.useradmin
acoustic.duration_sec5.0detection time when a target sets none
acoustic.coronaattentioncommon on outdoor HV conductors, watch the trend
acoustic.surfacewarningtracking on insulators and terminations
acoustic.floatingcriticala floating (loose) part: arcing
acoustic.intensity_warning0.0a discharge this intense is at least a warning; 0: off
acoustic.intensity_critical0.0and critical; set both once the site's levels are known

hotdog_patrol · patrol.yaml ​

patrols, the watchdog, the schedule · src/hotdog_patrol/config/patrol.yaml

patrol_node ​

ParameterDefaultMeaning
robot_nsm20
sites_dir~/.hotdog/sitesroutes: <site>/routes/<route>.csv
reports_dir~/.hotdog/reports<day>/patrol_<time>.json
battery_topic/{robot_ns}/battery
start.min_battery0.3fraction of a full battery
start.reanchortruelocalization/assume_origin: a patrol starts at the dock (the map origin)
start.stand_up_service/{robot_ns}/stand_upm20_driver: stand, then RL control
start.max_health1start with health WARN, never with ERROR
finish.dock_service/{robot_ns}/charge_startm20_driver: the M20 goes back to its dock
abort.return_to_docktruefalse: a watchdog return stops the robot where it is instead
abort.min_battery0.2back to the dock below this; keep above the follower's critical_battery
abort.max_duration_min120.0a patrol running longer goes back (0: off)
abort.hold_timeout_sec180.0blocked this long: back; off the route or not localized: stop
abort.nav_timeout_sec5.0navigation/status silent this long: the patrol fails
abort.near_m2.0the way back starts at the nearest point of the first pass this near
abort.dock_clearance_m1.0the way back ends this far from the route's start (the dock)
schedule.enabledfalselive: ros2 param set /patrol_node schedule.enabled true
schedule.times["06:00", "14:00", "22:00"]local time of this computer
schedule.route""the route of the scheduled patrols; empty: the route loaded last
schedule.window_min10.0a time missed by more than this (robot busy or off) is skipped

hotdog_reports · reports.yaml ​

report pages, retention, the report server · src/hotdog_reports/config/reports.yaml

report_node ​

ParameterDefaultMeaning
reports_dir~/.hotdog/reportsinspection_node and patrol_node write here
titleHotDog substation patrolheading of every page
robot_nameHotDoge.g. "HotDog 01 - GI Cawang"
trend_days30each finding is compared with the last round within this many days
retention.days365delete days older than this (0: keep everything)
retention.min_free_gb5.0then delete the oldest days while less is free (today never)
retention.period_min60.0min between two retention checks
server.enabledtruehttp://<robot>:8088/ on the substation network, read-only
server.host0.0.0.0127.0.0.1: only this computer (open it through an SSH tunnel)
server.port8088TCP port of the report server

hotdog_alerts · alerts.yaml ​

Telegram and webhook alerts · src/hotdog_alerts/config/alerts.yaml

alert_node ​

ParameterDefaultMeaning
enabledtruelive
languageenen | id (Bahasa Indonesia)
robot_nameHotDoge.g. "HotDog 01 - GI Cawang"
report_url""e.g. http://10.21.31.50:8088/ : a link to the patrol page in every patrol alert
telegram.chat_ids[""]e.g. ["-1001234567890"] (a group) and ["123456789"] (a person)
telegram.photostruethe thermal image or the sound map with each finding
webhook.url""e.g. https://scada.example/api/hotdog : one JSON POST per alert
findings.min_severitywarningattention | warning | critical
findings.repeat_hours12.0the same finding again only after this, unless it got worse
patrol_donetrueevery finished patrol (failed, stopped and returned ones always)
health_repeat_min30.0min, health ERROR announced again only after this
retry_sec15.0the spool is sent every 15 s while the uplink is down
max_age_hours48.0older unsent alerts are dropped
max_queued500alerts kept waiting at most; the oldest are dropped

Released under the Apache License 2.0. Built on the Dharma stack.