Skip to content

Molly interfaces ​

The single reference for every topic, service and file of Molly 2.0 on Dharma 0.2. The handheld (PROTOCOL.md) and the dashboard (web.md) are built against it. Names are absolute; nodes declare them relative and run in the root namespace. The robot driver lives under /<robot_ns>/ (default /robot/), see src/xtras/README.md. Each package README has the details; the types are in dharma_interfaces and molly_interfaces.

Frames ​

map ─ odom ─ camera_init ─ body ─ base_link ─┬─ livox_frame ─ livox_imu_frame
 │  (localization)  (FAST-LIO2)  (static)     ├─ front_camera_link ─ front_camera_optical_frame
 │                                            └─ legs, imu_link, ultrasound_* (robot URDF)
 └─ the site map, AprilTags, POIs and routes are all in `map`
  • map → odom comes from localization_node (an EKF fusing the AprilTags in view, an RViz or simulator pose estimate, or the start pose when a new map is recorded). The map is used for path finding, visitor filtering and display.
  • The frame names are the robot profile's robot.frames (config/robot.yaml).
  • odom → camera_init and body → base_link are static (from the URDF: base_link → livox_imu_frame).
  • The robot driver never publishes odom → base_link.

Sites ​

A site is one mapped place: its occupancy map, the AprilTags that anchor it and its routes (Dharma's site manager), and its POIs and tours (Molly's site_content_node). One directory per site under sites_dir (SITES_DIR, default ~/dev/Molly/map):

map/<site>/
├── map.yaml        # map_server format: image, resolution, origin [x, y, yaw], negate 0,
│                   # occupied_thresh 0.65, free_thresh 0.25, mode trinary
├── map.pgm         # 8-bit: 0 occupied, 254 free, 205 unknown; row 0 is the top (max y)
├── tags.json       # {tag_frame: {x, y, z, qx, qy, qz, qw}} in map (localization/record_tags)
├── pois.json       # {"pois": [Poi fields...]} in list order (molly_guide)
├── tours.json      # {"tours": [Tour fields...]} (molly_guide)
└── routes/         # taught routes, <date>_<time>.csv: x, y, yaw_deg, dwell_sec (> 0: stop point)

Site names and POI / tour ids: ^[a-z0-9][a-z0-9_-]{0,47}$. The active site is remembered in ~/.molly/site, the last route loaded in ~/.molly/last_route. A mapping reset moves the map, tags, POIs and tours into <site>/backup-<time>/. JSON files are written atomically (temp file + rename) with a .bak of the previous version.

Topics ​

TopicTypePublisherNotes
/mapnav_msgs/OccupancyGridsite_manager_nodelatched; the live grid while mapping, the site map otherwise
/site/statusdharma_interfaces/SiteStatussite_manager_nodelatched: site, sites, has_map, mapping, tags, routes
/site/pois, /site/toursmolly_interfaces/PoiArray, TourArraysite_content_nodelatched, the active site's
/mapping/grid, /mapping/statusOccupancyGrid, MappingStatusgrid_mapper_nodelatched
/localization/statusdharma_interfaces/LocalizationStatuslocalization_nodelatched: state (NONE, localized), source, tags in view
/localization/posePoseWithCovarianceStampedlocalization_nodemap → base_link while localized
/localization/tag_markersvisualization_msgs/MarkerArraylocalization_nodelatched
/odometry/statusdharma_interfaces/OdometryStatusodometry_monitor_nodelatched
/planner/statusdharma_interfaces/PlannerStatusplanner_nodelatched: state, goal, remaining, replans
/planner/path, /planner/costmapPath, OccupancyGridplanner_nodelatched
/navigation/waypoints, /navigation/pathWaypointPath, Pathpath_loader_node, path_follower_nodelatched, the loaded route
/navigation/statusdharma_interfaces/NavigationStatuspath_follower_nodelatched: state, pause reasons, index, remaining
/navigation/stop_pointdharma_interfaces/StopPointEventpath_follower_noderoute stop points
/perception/sector_scan, /perception/safety_scandharma_interfaces/SectorScanlidar_sector_nodefront sectors / 360°
/perception/visitorsmolly_interfaces/Visitorsvisitor_tracker_node (molly_interaction)in front, behind, beside
/perception/visitor_markersvisualization_msgs/MarkerArrayvisitor_tracker_nodeRViz
/tour/statemolly_interfaces/TourStateguide_nodelatched: state, tour, stop, activity, message
/tour/cmdmolly_interfaces/TourCommandthe dashboardlike /tour/control, without an answer
/interaction/speech_statusmolly_interfaces/SpeechStatusspeech_nodelatched
/interaction/say_textstd_msgs/Stringanyonespeak, fire and forget
/interaction/greetermolly_interfaces/GreeterStatusinteraction_nodelatched
/interaction/conversationmolly_interfaces/Conversationconversation_nodeone per question
/control/statusdharma_interfaces/ControlStatuscontrol_mux_nodelatched: mode, remote source, e-stop and reasons, field state, speed scale
/control/nav_cmd_velgeometry_msgs/Twistpath_follower_node / obstacle_avoidance_nodeto the mux (AUTO)
/control/remote/handheld/cmd_vel, /control/remote/dashboard/cmd_velgeometry_msgs/Twistteleop_udp_node, the dashboardto the mux (REMOTE, the selected source only)
/control/estop_requeststd_msgs/Stringany nodeengages the e-stop with a reason
/docking/statusdharma_interfaces/DockingStatusdocking_nodelatched
/health/statusdharma_interfaces/HealthStatushealth_monitor_nodelatched: level, issues, sensors, speed scale, CPU, GPU, RAM
/<robot_ns>/cmd_velgeometry_msgs/Twistcontrol_mux_nodeonly the mux drives the robot
/<robot_ns>/odom, /battery, /imu, /joint_states, /diagnosticsrobot drivercontract

Services ​

ServiceTypeServer
/site/list, /site/loadListSites, LoadSitesite_manager_node
/site/save_poi, /site/delete_poimolly_interfaces/SavePoi, DeleteByIdsite_content_node
/site/save_tour, /site/delete_tourmolly_interfaces/SaveTour, DeleteByIdsite_content_node
/mapping/startdharma_interfaces/StartMappingsite_manager_node (drives grid_mapper_node and localization)
/mapping/stop, /mapping/savestd_srvs/Triggersite_manager_node: save writes the grid into the active site and reloads it
/localization/startstd_srvs/Triggerlocalization_node: localize from a visible tag
/localization/record_tagsstd_srvs/Triggerlocalization_node: save the visible tags into the site's tags.json
/localization/load_tagsdharma_interfaces/LoadFilelocalization_node (the site manager calls it)
/localization/assume_origin, /localization/resetstd_srvs/Triggerlocalization_node
/planner/go_todharma_interfaces/GoToplanner_node: plan to x, y, yaw, load, start
/planner/plan, /planner/cancelPlanPath, std_srvs/Triggerplanner_node
/navigation/load_pathdharma_interfaces/LoadPathpath_loader_node: a route CSV inside sites_dir
/navigation/set_pathdharma_interfaces/SetPathpath_follower_node
/navigation/start, /stop, /pause, /resumestd_srvs/Triggerpath_follower_node
/route/start, /route/stopstd_srvs/Triggerroute_recorder_node: teach a route
/route/mark_stop_pointdharma_interfaces/MarkStopPointroute_recorder_node
/control/set_modedharma_interfaces/SetModecontrol_mux_node: auto, or remote with a source
/control/estop/engage, /control/estop/releasestd_srvs/Triggercontrol_mux_node
/docking/dock, /docking/undock, /docking/cancelstd_srvs/Triggerdocking_node
/tour/controlmolly_interfaces/TourControlguide_node: START, PAUSE, RESUME, STOP, SKIP
/tour/get_statemolly_interfaces/GetTourStateguide_node
/guide/go_to_poimolly_interfaces/GoToPoiguide_node: walk to one POI (refused during a tour)
/interaction/say, /interaction/stop_speechmolly_interfaces/Say, Triggerspeech_node
/interaction/gesturemolly_interfaces/Gestureinteraction_node → /<robot_ns>/<name>
/interaction/greet, /interaction/set_greeterstd_srvs/Trigger, SetBoolinteraction_node: greet now, automatic greeting on / off
/interaction/askmolly_interfaces/Askconversation_node
/<robot_ns>/stand_up, /sit_down, /emergency_stop, gaits, gesturesstd_srvs/Triggerrobot driver

Behaviour ​

Mapping (start_mapping:=true site:=<name>, or mapping/start at runtime). mapping/start {site, reset}:

  1. creates map/<site>/ when new and makes it the active site;
  2. switches localization to map/<site>/tags.json (localization/load_tags);
  3. when localization has no source yet, takes the current pose as the map origin (localization/assume_origin);
  4. starts grid_mapper_node (reset: empty grid; otherwise it continues the saved map).

A site that already has a map keeps its frame: continuing it needs the robot localized on one of its tags first, or reset: true to start it over (its files, POIs and tours included, move to map/<site>/backup-<time>/). Loading another site (site/load) resets localization.

While mapping, drive the robot (handheld REMOTE) through the whole place, stand still in view of each AprilTag and localization/record_tags, and add POIs at the robot pose (site/save_poi with at_robot_pose). mapping/save writes map.pgm + map.yaml and reloads the site; mapping/stop ends the session.

Guiding. The active site's map is published on /map, its tags are loaded into localization (a tag in view localizes the robot), and:

  • guide/go_to_poi {poi_id} or planner/go_to {x, y, yaw}: A* on the costmap; the path goes to the follower, which walks it (obstacle avoidance steers around people) and turns to the goal's heading (planner/status reaches the goal).
  • /tour/control {START, tour_id} (AUTO and localized): for each POI the guide walks there (activity NAVIGATING, WAITING_VISITORS when nobody follows), plays the POI gesture (PERFORMING_MOTION), says the narration (NARRATING) and waits dwell_sec (DWELLING); then the next one, and walks to return_poi_id at the end (RETURNING).
  • REMOTE or an e-stop pauses navigation and the tour with it; back in AUTO the tour goes on to the same stop (after an e-stop only when told: RESUME).
  • Visitors in front of an idle robot are greeted (speech + gesture), questions typed on the dashboard are answered by the conversation model (optional).