Skip to content

Data Architecture

These pages document the data flow for the systems that are onboard the R/V David Packard.

Architecture

Starting with a very high level view of the architecture, you can think of the ship as a collection of data sources that we need to be able to route to other on-board systems, log, and make available to other clients that are not part of the core data management system.

Warning

This document is a work in progress and is updating as it is being built

--- title: High Level Overview --- flowchart LR subgraph restricted-access[Restricted Access Network] subgraph Ship Systems ship-datasources[Data Sources] ship-4d-nav[4D Nav
Ship] ship-time-zero[TimeZero] end subgraph ROV Systems rov-datasources[Data Sources] rov-4d-nav[4D Nav
ROV] telepresence-screen-grabber[Telepresence
Screen
Grabber] end subgraph Navproc Machine navproc[Navproc] logr[Logger] logr-files[*.dat] lcm-bridge[LCM Bridge] zmq[ZeroMQ] end end subgraph science-access[Science Network] subgraph api[API Server] zmq-proxy[ZeroMQ Proxy] end loaders[Timeseries
Database
Loaders] ship-timeseries-database[Timeseries
Database] ship-grafana[Grafana
Visualization
Dashboards] dataprobe[Dataprobe] telepresence[Telepresence] asset-tracking-consumer[Asset
Tracking
Consumer] ship-odss[ODSS] ship-to-odss[Ship
to
ODSS] time-zero-files[Timezero
Files] lava[Lava for
ArcGIS/MapNav] other-clients[Other
Data
clients] end subgraph Shore Systems shore-timeseries-database[Timeseries
Database] shore-grafana[Grafana
Visualization
Dashboards] shore-odss[ODSS] rabbitmq-server[RabbitMQ] expd[Expedition
Database] main-website[MBARI
Website] telepresence-server[Telepresence
Server] end ship-datasources -- serial
UDP --> navproc rov-datasources <-- serial
UDP --> navproc navproc -- LCM
msg_t --> logr navproc -- LCM
msg_t --> lcm-bridge lcm-bridge -- zmq
json --> zmq zmq -- zmq
json --> zmq-proxy zmq-proxy -- zmq
json --> loaders zmq-proxy -- zmq
json --> dataprobe zmq-proxy -- zmq
json --> telepresence zmq-proxy -- zmq
json --> ship-to-odss zmq-proxy -- zmq
json --> lava ship-to-odss -- amqp --> rabbitmq-server zmq-proxy -- zmq
json --> other-clients loaders --> ship-timeseries-database ship-timeseries-database --> ship-grafana logr --> logr-files -- copy --> expd ship-timeseries-database -- replication --> shore-timeseries-database rabbitmq-server -- amqp --> shore-odss rabbitmq-server -- amqp --> asset-tracking-consumer -- sql --> ship-odss asset-tracking-consumer -- ? --> ship-4d-nav asset-tracking-consumer -- ? --> rov-4d-nav shore-timeseries-database --> shore-grafana --> main-website ship-odss -- sql --> time-zero-files time-zero-files --> ship-time-zero telepresence-screen-grabber --> telepresence-server
--- title: Ship, ROV and Navproc System Details --- flowchart LR subgraph ROV vehicle[Ricketts] umbilical[Umbilical] rovinst1[DVL] rovinst2[CTD] rovinst3[Octans FOG] rovinst4[Port PnT] rovinst5[Stbd PnT] end subgraph ship-systems[Ship Systems] shipgps[Ship GPS] shipgyro[Ship Gyro] shipwind[Ship Wind] uhs[UHS] uhs-tcp-socket[UHS TCP Socket] end subgraph signal-distribution-box[Signal Distribution Box] ship-gps-splitter[Ship GPS Splitter] ship-gps-1pps-splitter[Ship GPS 1PPS Splitter] ship-gyro-splitter[Ship Gyro Splitter] ship-wind-splitter[Ship Wind Splitter] end subgraph ROV Control Room sonardyne[Sonardyne] sonardyne-sprint[Sonardyne
Sprint] ocean-imaging[Ocean
Imaging] subgraph terminal-server ts1[Port] ts2[Port] ts3[Port] end subgraph ROV Control focal[Focal
Mux] smd[SMD
Control
System] 4k-lapbox[4K Lapbox] overlay[Overlay] end subgraph navproc[Navproc PC] subgraph navproc-virtual-ports[Virtual Serial Ports] vp1[Port] vp2[Port] vp3[Port] end navproc-process-1[Navproc
Process1] navproc-process-2[Navproc
Process2] navproc-process-3[Navproc
Process3] navproc-process-4[Navproc
Process4] navproc-process-5[Navproc
Process5] logr-process-1[Logger 1] logr-process-2[Logger 2] logr-process-3[Logger 3] end end shipgps -- serial --> ship-gps-splitter shipgyro -- serial --> ship-gyro-splitter shipwind -- serial --> ship-wind-splitter uhs -- modbus --> uhs-tcp-socket shipgps -- bnc-coax --> ship-gps-1pps-splitter ship-gps-1pps-splitter -- bnc-coax --> sonardyne ship-gps-1pps-splitter -- bnc-coax --> sonardyne-sprint ship-gps-1pps-splitter -- bnc-coax --> ocean-imaging ship-gps-splitter -- serial --> sonardyne ship-gyro-splitter -- serial --> sonardyne ship-gps-splitter -- serial --> sonardyne-sprint ship-gps-splitter -- serial --> ocean-imaging ship-gps-splitter -- serial --> ts1 ship-gyro-splitter -- serial --> ts2 ship-wind-splitter -- serial --> ts3 rovinst1 --> vehicle rovinst2 --> vehicle rovinst3 --> vehicle rovinst4 --> vehicle rovinst5 --> vehicle vehicle --> umbilical umbilical --> focal focal --> smd ts1 --> vp1 ts2 --> vp2 ts3 --> vp3 vp1 --> navproc-process-1 vp2 --> navproc-process-2 vp3 --> navproc-process-3 uhs-tcp-socket --> navproc-process-4 smd <-- UDP --> navproc-process-5 navproc-process-1 -- LCM --> logr-process-1 navproc-process-2 -- LCM --> logr-process-2 navproc-process-3 -- LCM --> logr-process-2 navproc-process-3 -- LCM --> logr-process-3 navproc-process-4 -- LCM --> logr-process-3 navproc-process-5 -- LCM --> logr-process-3 navproc-process-4 <-- UDP --> smd navproc-process-5 --> sonardyne navproc-process-5 -- serial --> 4k-lapbox navproc-process-5 --> overlay

In order to build the above system, keep in mind the follow pieces need to be built still:

  1. The bridge software that grabs LCM messages, converts them to JSON and pushes them out over ZeroMQ
  2. The logr process management should be moved to Procman and the LCM messages from procman should then be routed through the bridge and made available to Dataprobe so it can monitor the logr and navproc processes
  3. A proxy should be set up on a machine on the science network that will act as a proxy for all ZeroMQ messages. This is so that the client interactions will happen on the science network and not on the restricted network.
  4. A process needs to be written to consume the JSON messages from the API and send ship and rov locations to the RabbitMQ queue for the tracking database.
  5. A process needs to be written to consume the JSON messages from the API and send data to RabbitMQ for telepresence.
  6. A process needs to be written to consume the JSON messages and insert them into a timeseries database
  7. The ArcMap Nav needs a version that can read from the JSON messages.
  8. Dataprobe need to be re-written to consume the ZeroMQ/JSON messages.
--- title: Data Flow Chart --- flowchart TB subgraph SMD smd-dvecs-2 end subgraph MBARI-SMD-Bridge-Processes socket-1 pmbanp-udp-receiver npf-publisher-1 npf-subscriber-2 pmbanp-udp-sender socket-2 npf-publisher-3 end subgraph Navproc-Processes npf-subscriber-1 navproc npf-publisher-2 npf-subscriber-3 end logr smd-dvecs-2 -- UDP:50002 --> socket-1 -- NMEA --> pmbanp-udp-receiver -- msg_t --> npf-publisher-1 -- LCM --> npf-subscriber-1 -- msg_t --> navproc navproc -- msg_t --> npf-publisher-2 -- LCM --> npf-subscriber-2 -- msg_t --> pmbanp-udp-sender -- NMEA --> socket-2 -- UDP:50001 --> smd-dvecs-2 pmbanp-udp-sender -- msg_t --> npf-publisher-3 -- LCM --> npf-subscriber-3 -- msg_t --> navproc
--- title: Class Diagram --- classDiagram log <|-- lcm_interface pmbanp_udp_receiver --o lcm_interface pmbanp_udp_receiver --o lcm_publisher lcm_interface "1" --o "0..*" lcm_publisher lcm_interface "1" --o "0..*" lcm_subscriber pmbanp_udp_sender --o lcm_interface pmbanp_udp_sender --o lcm_publisher pmbanp_udp_sender --o lcm_subscriber class log{ log(const std::string& class_name, const std::string& object_name) +info_msg(const std::string& msg, bool nl) +info_msg(const std::string& msg, bool nl) +warn_msg(const std::string& msg, bool nl) +err_msg(const std::string& msg, bool nl) } class lcm_interface { lcm_interface(const std::string& name) +initialize() +add_publisher(lcm_publisher& publisher) +add_subscriber(lcm_subscriber& subscriber) +start() +stop() } class lcm_publisher{ lcm_publisher(const std::string& name) +publish(const T& msg, const std::string& channel) } class lcm_subscriber { lcm_subscriber(const std::string& name) +get_lcm_msg(T& msg) } class pmbanp_udp_receiver { +main() } class navproc_msg_utils { +add_bool_to_msg(navproc::msg_t& msg, const std::string& s, bool b) +add_int64_to_msg(navproc::msg_t& msg, const std::string& s, int64_t l) +add_double_to_msg(navproc::msg_t& msg, const std::string& s, double d) +add_string_to_msg(navproc::msg_t& msg, const std::string& s1, const std::string& s2) +add_bytes_to_msg(navproc::msg_t& msg, const std::string& s, const std::vector~uint8_t~& b) +get_msg_XXXX() +set_msg_XXXX() } class pmbanp_udp_sender { +main() }

Notes

A helpful way to think about this architecture is that any time you want to read/write information from/to navproc, you will be dealing with a subscriber or publisher class. The data that is passed between these (via LCM) is all defined by one single LCM type and it is a structure that can hold any number of named items of various types.

When an entity wants to send data, it creates a publisher object and then uses the methods defined in the navproc_msg_utils file to add and set items of various types on the publisher. Then, when ready, the entity can call 'publish' which will then send the LCM message. It can then update or add items and resend by calling 'publish' again.

On the consumer side, the entity can instantiate a subscriber object and then call 'get_lcm_msg' which will return an object of msg_t and then the subscriber can query for items by calling

Components

SMD DVECS II

This is the control system for the Doc Ricketts ROV that both sends data out to clients as well as takes data and commands in from clients.

The job of navproc is to collect data from various sources and package that data up and route it to different destinations. These sources could be from UDP data messages or serial data streams.

SMD To/From Navproc UDP Senders/Receivers

There are a set of processes that exist to consume UDP messages from SMD and feed them to navproc as well as a set of processes that read from navproc and publish messages over UDP to the SMD DVECS II system.

Logger

The logging system is responsible for taking data flowing from Navproc and logging it to text files.