From f386255cf6ab614a02763f72d9f6a0281f7f4e26 Mon Sep 17 00:00:00 2001 From: Esten Date: Fri, 15 May 2026 13:20:43 +0200 Subject: [PATCH 1/2] Documetnation update --- check-internal-links.py | 7 +- docs/css/extra.css | 25 +- docs/dvl/axes.md | 31 +- docs/dvl/bluerov-integration-dvl-ugps.md | 37 +- docs/dvl/bluerov-integration.md | 134 +++--- docs/dvl/configuration.md | 90 ++++ docs/dvl/dead-reckoning.md | 34 +- docs/dvl/diagnostic-log.md | 37 ++ docs/dvl/dvl-a100.md | 76 +++ docs/dvl/dvl-a125.md | 24 +- docs/dvl/dvl-a250.md | 71 +++ docs/dvl/dvl-a250_a100-gui.md | 91 ++++ docs/dvl/dvl-a250_a100-json-protocol.md | 319 +++++++++++++ docs/dvl/dvl-a250_a100-serial-protocol.md | 435 +++++++++++++++++ docs/dvl/dvl-a50.md | 26 +- docs/dvl/dvl-a50_a125-gui.md | 99 ++++ docs/dvl/dvl-json-protocol.md | 333 +++++++++++++ docs/dvl/dvl-pd-formats.md | 191 ++++++++ docs/dvl/dvl-serial-protocol.md | 468 +++++++++++++++++++ docs/dvl/dvl-triggering.md | 34 ++ docs/dvl/electrical.md | 142 ++++++ docs/dvl/faq.md | 321 ++++++++++--- docs/dvl/how-to-diagnose.md | 163 +++++++ docs/dvl/installation.md | 122 +++++ docs/dvl/integration.md | 85 ++++ docs/dvl/networking.md | 57 ++- docs/dvl/overview.md | 93 ++++ docs/dvl/quickstart.md | 57 +++ docs/dvl/range-mode.md | 53 +++ docs/dvl/software-resources.md | 48 ++ docs/dvl/support-package-checklist.md | 46 ++ docs/dvl/sw-update.md | 58 +-- docs/dvl/water-tracking.md | 89 ++++ docs/img/dvl_a250_back_entry_drawing.png | Bin 0 -> 108042 bytes docs/img/dvl_a250_front_side_drawing.png | Bin 0 -> 54488 bytes docs/index.md | 53 +-- docs/io-interface-cards/io-interface-rev2.md | 15 + docs/io-interface-cards/io-interface-rev3.md | 12 + docs/modem-m64/modem-m64-protocol.md | 2 +- mkdocs.yml | 58 ++- 40 files changed, 3706 insertions(+), 330 deletions(-) create mode 100644 docs/dvl/configuration.md create mode 100644 docs/dvl/diagnostic-log.md create mode 100644 docs/dvl/dvl-a100.md create mode 100644 docs/dvl/dvl-a250.md create mode 100644 docs/dvl/dvl-a250_a100-gui.md create mode 100644 docs/dvl/dvl-a250_a100-json-protocol.md create mode 100644 docs/dvl/dvl-a250_a100-serial-protocol.md create mode 100644 docs/dvl/dvl-a50_a125-gui.md create mode 100644 docs/dvl/dvl-json-protocol.md create mode 100644 docs/dvl/dvl-pd-formats.md create mode 100644 docs/dvl/dvl-serial-protocol.md create mode 100644 docs/dvl/dvl-triggering.md create mode 100644 docs/dvl/electrical.md create mode 100644 docs/dvl/how-to-diagnose.md create mode 100644 docs/dvl/installation.md create mode 100644 docs/dvl/integration.md create mode 100644 docs/dvl/overview.md create mode 100644 docs/dvl/quickstart.md create mode 100644 docs/dvl/range-mode.md create mode 100644 docs/dvl/software-resources.md create mode 100644 docs/dvl/support-package-checklist.md create mode 100644 docs/dvl/water-tracking.md create mode 100644 docs/img/dvl_a250_back_entry_drawing.png create mode 100644 docs/img/dvl_a250_front_side_drawing.png create mode 100644 docs/io-interface-cards/io-interface-rev2.md create mode 100644 docs/io-interface-cards/io-interface-rev3.md diff --git a/check-internal-links.py b/check-internal-links.py index 85435422..5ae996d2 100644 --- a/check-internal-links.py +++ b/check-internal-links.py @@ -5,6 +5,7 @@ # Regex for Markdown links: [text](target) LINK_RE = re.compile(r"\[([^\]]+)\]\(([^)]+)\)") +HEADING_ATTR_ID_RE = re.compile(r"\s*\{[^}]*#([A-Za-z0-9_-]+)[^}]*\}\s*$") def slugify_heading(text: str) -> str: """Convert Markdown heading text to MkDocs anchor format.""" @@ -22,7 +23,11 @@ def extract_headings(md_file: Path): for line in md_file.read_text(encoding="utf-8").splitlines(): if line.startswith("#"): heading_text = line.lstrip("#").strip() - headings.add(slugify_heading(heading_text)) + attr_match = HEADING_ATTR_ID_RE.search(heading_text) + if attr_match: + headings.add(attr_match.group(1)) + else: + headings.add(slugify_heading(heading_text)) return headings def check_md_file(md_file: Path): diff --git a/docs/css/extra.css b/docs/css/extra.css index 1cef1ffd..fd7604f4 100644 --- a/docs/css/extra.css +++ b/docs/css/extra.css @@ -1,3 +1,7 @@ +html { + scrollbar-gutter: stable; +} + .md-header { height:3.7rem; background-color: #1d3556; @@ -24,14 +28,6 @@ width:auto; } -.md-container{ - margin-top: 2rem; -} - -.md-sidebar{ - margin-top:6rem; -} - .responsive-video { position: relative; width: 100%; @@ -65,16 +61,3 @@ a { color: #2B9C6A; } - - /* Hide the right hand Table of Contents sidebar */ -.md-sidebar--secondary, -.md-sidebar[data-md-type="toc"] { - display: none; -} - -/* Make the content span the full width when the secondary sidebar is gone */ -@media (min-width: 960px) { - .md-main__inner { - grid-template-columns: minmax(0, 1fr); - } -} \ No newline at end of file diff --git a/docs/dvl/axes.md b/docs/dvl/axes.md index b8f9f7eb..5f66450b 100644 --- a/docs/dvl/axes.md +++ b/docs/dvl/axes.md @@ -1,8 +1,6 @@ # Axes -For both the DVL-A50 and the DVL-A125. - -Velocities and dead reckoning output uses the vehicle frame. By default the vehicle frame is the same as the body frame, but can be adjusted to allow flexible mounting on the vehicle. +The axis convention is the same for all DVL models. Velocities and dead reckoning output use the vehicle frame. By default, the vehicle frame is the same as the body frame, but it can be adjusted to allow flexible mounting on the vehicle. @@ -41,23 +39,34 @@ Velocities and dead reckoning output uses the vehicle frame. By default the vehi The body frame axes of the DVL are as follows: -* X axis is pointing forward (LED is forward, cable backward) +* X axis is pointing forward (LED is forward (only for A50/A125), cable backward) * Y axis is pointing right -* Z axis is pointing down (mounting holes are up, transducers are down) -* Origin is the center of the DVL and 25mm/30mm from the backplate. See [A125](dvl-a125.md#dimensions) and [A50](dvl-a50.md#dimensions) for their dimensions. +* Z axis is pointing down (metal back plate is up, transducers are down, LED is pointing down only for A100/A250) +* Origin is the center of the DVL on the transducer side. + + + +By default, the body frame and vehicle frame are the same and align with the frame used for dead reckoning. -By default, the body frame and vehicle frame is the same and align with the DVL's [frame](dead-reckoning.md#frame) for dead reckoning. +## Transducer numbering and protocol IDs + +Mechanical/transducer diagrams number the transducers from 1 to 4. In protocol messages and diagnostic logs, the transducer `id` uses zero-based numbering from 0 to 3. The `id` is therefore the transducer number minus 1. ## Vehicle frame -The DVL can be mounted at an angle to the forward direction of a vehicle to which it is attached. +The DVL can be mounted at an angle to the forward direction of the vehicle (yaw). -To be precise, the clockwise angle θ in degrees around the Z axis (i.e. in the X-Y plane) from the forward axis of the vehicle to the forward axis of the DVL can be entered as a 'mounting rotation offset' in the [GUI](../dvl/gui/configuration.md), or via the TCP or serial [protocols](dvl-protocol.md). +The clockwise angle θ in degrees around the Z axis, in the X-Y plane, from the forward axis of the vehicle to the forward axis of the DVL can be entered as a mounting rotation offset in the [web GUI](configuration.md), or through the configuration method over the TCP JSON API or serial protocol. -The DVL will then output data in the vehicle frame obtained by rotating the [DVL body frame](#body-frame) anti-clockwise around the Z-axis by θ degrees: the X-axis of the velocities outputted by the DVL will be aligned with the forward axis of the vehicle, and, at time zero, the X-axis of the DVL's [frame](dead-reckoning.md#frame) for dead reckoning will be aligned with the forward axis of the vehicle. +The DVL will then output data in the vehicle frame obtained by rotating the [DVL body frame](#body-frame) anti-clockwise around the Z axis by θ degrees. The X axis of the velocity output will be aligned with the forward axis of the vehicle. At time zero, the X axis of the DVL's dead-reckoning frame will be aligned with the forward axis of the vehicle. For example: * If the DVL is mounted back-to-front (cable aligned with the forward axis of the vehicle), the mounting rotation offset should be set to 180 degrees. +* If the A50/A125 is mounted with the LED at 90 degrees clockwise from the forward axis of the vehicle, the mounting rotation offset should be set to 90 degrees. + +## Mounting offset in pitch and roll + +This is possible, but the translation will have to be done by the user as there are no internal functions to compensate for this. -* If the DVL is mounted with the LED at 90 degrees clockwise from the forward axis of the vehicle, the mounting rotation offset should be set to 90 degrees. +The DVL will always assume it is facing perpendicular to the surface. diff --git a/docs/dvl/bluerov-integration-dvl-ugps.md b/docs/dvl/bluerov-integration-dvl-ugps.md index 85edcb71..d9dec38d 100644 --- a/docs/dvl/bluerov-integration-dvl-ugps.md +++ b/docs/dvl/bluerov-integration-dvl-ugps.md @@ -1,10 +1,10 @@ -## Optimizing Performance when concurrently using our DVL and UGPS Systems +## Optimizing performance when using DVL and UGPS together ### Capabilities of the DVL as a Standalone System -The Water Linked DVL can provide accurate velocities relative to the seabed. It has a relatively high update rate and dynamic. +The Water Linked DVL can provide accurate velocities relative to the seabed. It has a relatively high update rate and dynamic response. For the calculation of an absolute position, the velocities have to be integrated over time with the help of inertial measurement unit (IMU) data. -Furthermore, the user has to specify a starting position of this dead-reckoning-algorithm. Alternatively a normal GPS can be used to initialize the position prior to a dive. +Furthermore, the user has to specify a starting position for this dead-reckoning algorithm. Alternatively, a normal GPS can be used to initialize the position before a dive. One advantage of using a DVL only is that no infrastructure outside the ROV (such as antennas, beacons, etc.) is needed. As a downside, small errors in sensor values accumulate over time and the position estimate drifts from the actual position. @@ -18,28 +18,28 @@ The characteristic of this combined position estimate is that it is global, with ### Enhanced Functionality with Combined DVL and UGPS Integration -When both sensor types are combined in a good manner they can compensate each other's weak sides. For instance the UGPS helps to compensate for the position drift of the DVL over time. The DVL on the other hand increases the update rate of the position, which is necessary for better control. This is particularly useful if you want to use the positioning not only for visualization during manual operation or position holding but longer autonomous missions (e.g. waypoint navigation). Below section "Mode DVL+UGPS" describes how to enable this in the BlueROV control system. +When both sensor types are combined well, they can compensate for each other's limitations. For instance, the UGPS helps compensate for DVL position drift over time. The DVL increases the position update rate, which is necessary for better control. This is particularly useful if you want to use the positioning not only for visualization during manual operation or position holding, but also for longer autonomous missions, such as waypoint navigation. The section "Mode DVL+UGPS" describes how to enable this in the BlueROV control system. ## Mode "DVL+UGPS": Fusing the data of Underwater GPS and DVL for a position estimate of the BlueROV The BlueROV uses a highly-customizable autopilot [Ardusub](https://www.ardusub.com/). One part of that autopilot is an Extended Kalman filter, which is able to combine inputs from all types of sensors (gyroscope, accelerometer, compass, pressure sensor, GPS, DVL, etc.) to calculate a position estimate. This is then used to either simply show the position on a map in manual mode or as part of a feedback loop to actively control the ROV. This data fusion algorithm is not part of a Water Linked product but is executed in the BlueROV control system. So the user is in full control of the parameters and used algorithm. -Before successful sensor fusion of Underwater GPS and DVL the following conditions must be met: +Before successful sensor fusion of Underwater GPS and DVL, the following conditions must be met: * A BlueROV running BlueOS with a version 1.1.0 (stable) or newer. -* The DVL is installed, configured and tested successfully. Guides can be found [here](bluerov-integration.md) and on the [Blue Robotics website](https://bluerobotics.com/learn/dvl-a50-integration/) +* The DVL is installed, configured, and tested successfully. Guides can be found [here](bluerov-integration.md) and on the [Blue Robotics website](https://bluerobotics.com/learn/dvl-a50-integration/) * Make sure you are running version 1.0.7 or newer of the [BlueOS Water Linked DVL extension](https://github.com/bluerobotics/BlueOS-Water-Linked-DVL). The extension version can be checked / updated in BlueOS by going to Extensions > Installed. The version is shown next to the extension name, see below figure. ![bluerov2_blueos_installed_extensions_ugps_dvl_version_marked](../img/bluerov2_blueos_installed_extensions_ugps_dvl_version_marked.png) -* The Underwater GPS is installed, configured and tested successfully. The latest UGPS integration-guide can be found [here](../underwater-gps/integration/bluerov-integration.md). +* The Underwater GPS is installed, configured, and tested successfully. The latest UGPS integration guide can be found [here](../underwater-gps/integration/bluerov-integration.md). * Make sure you are running version 1.0.7 or newer of the [BlueOS Water Linked UGPS extension](https://github.com/waterlinked/blueos-ugps-extension). * The accelerometer, gyroscope, compass and pressure sensor must be calibrated: Calibration of all sensors can be performed from QGroundControl. Detailed steps are described in the [BlueROV Software Setup](https://bluerobotics.com/learn/bluerov2-software-setup/#sensor-calibration) -* Make sure that the compass calibration was successful by comparing the ROV orientation shown in the map in QGroundControl to the actual ROV orientation. Land-marks like a coast-line or an analogue compass can help. +* Make sure that the compass calibration was successful by comparing the ROV orientation shown in the map in QGroundControl to the actual ROV orientation. Landmarks like a coastline or an analog compass can help. -!!! Note - When you want to use the position estimate for *control* of the ROV and the UGPS Topside is on land, it is highly recommended setting up the Underwater GPS to use static position and static heading mode. Alternatively when the UGPS Topside position is not static (on a boat or similar) you need to input heading and position data from an external GPS compass. [Details can be found here](../underwater-gps/ugps-sysconfig.md#topside-settings). +!!! note + When you want to use the position estimate for *control* of the ROV and the UGPS Topside is on land, it is highly recommended to set up the Underwater GPS to use static position and static heading mode. Alternatively, when the UGPS Topside position is not static (on a boat or similar), you need to input heading and position data from an external GPS compass. [Details can be found here](../underwater-gps/ugps-sysconfig.md#topside-settings). If you don't follow this advice, the position provided by the Underwater GPS will have more noise ("jump" too much) and also drift over time. This might cause the position hold mode to not work properly. @@ -47,7 +47,7 @@ Before successful sensor fusion of Underwater GPS and DVL the following conditio The steps to enable sensor fusion are: -* To enable fusion of Underwater GPS and DVL, enable both the "Water Linked DVL"-extension and "Water Linked UGPS"-extension in the extensions manager. You see that they are running when an uptime is shown. +* To enable fusion of Underwater GPS and DVL, enable both the "Water Linked DVL" extension and "Water Linked UGPS" extension in the extensions manager. You see that they are running when an uptime is shown. ![bluerov2_blueos_installed_extensions_ugps_dvl_running_marked](../img/bluerov2_blueos_installed_extensions_ugps_dvl_running_marked.png) @@ -65,18 +65,18 @@ Now both sensors should be considered for the position estimate of the ROV. You ## Alternative mode "DVL only": How to base the ROV position estimate only on the DVL while the Underwater GPS is running -This mode can be useful when you experience issues with sensor fusion (Mode "DVL+UGPS" above) or not all the described conditions in above section are met. Otherwise, we recommend using Mode "DVL+UGPS". +This mode can be useful when you experience issues with sensor fusion (Mode "DVL+UGPS" above), or when not all the described conditions in the section above are met. Otherwise, we recommend using Mode "DVL+UGPS". -In this configuration the BlueROV will base its position estimate *updates* on velocity input from the DVL as well as accelerometer, gyroscope, compass and pressure sensor but not the Underwater GPS. Although the Underwater GPS is connected and running it will only be used to *initialize* the global ROV position at the beginning. QGroundControl (or the new Cockpit) will show the ROV position estimate based on the DVL only while the [Underwater GPS GUI](../underwater-gps/interface/ugps-gui.md#position) will show the position based on the Underwater GPS. +In this configuration, the BlueROV will base its position estimate *updates* on velocity input from the DVL as well as accelerometer, gyroscope, compass, and pressure sensor data, but not the Underwater GPS. Although the Underwater GPS is connected and running, it will only be used to *initialize* the global ROV position at the beginning. QGroundControl (or the new Cockpit) will show the ROV position estimate based on the DVL only, while the [Underwater GPS GUI](../underwater-gps/interface/ugps-gui.md#position) will show the position based on the Underwater GPS. -!!! Note +!!! note The setup procedure below is very similar to when you only use the DVL without a running Underwater GPS. That case is described [here](bluerov-integration.md#software). -* Enable both the "Water Linked DVL"-extension and "Water Linked UGPS"-extension in the extensions manager. You see that they are running when an uptime is shown. Make sure you use the latest versions of both extensions. +* Enable both the "Water Linked DVL" extension and "Water Linked UGPS" extension in the extensions manager. You see that they are running when an uptime is shown. Make sure you use the latest versions of both extensions. ![bluerov2_blueos_installed_extensions_ugps_dvl_running_marked](../img/bluerov2_blueos_installed_extensions_ugps_dvl_running_marked.png) -* Open the interface of the DVL-extension and click the button "Load parameters for DVL". This will set parameters for the Kalman filter to ignore the Underwater GPS input. Those parameters are persistent over reboots, which means that this button only needs to be pressed once and not every time you restart the ROV. +* Open the interface of the DVL extension and click the button "Load parameters for DVL". This will set parameters for the Kalman filter to ignore the Underwater GPS input. Those parameters are persistent over reboots, which means that this button only needs to be pressed once and not every time you restart the ROV. ![bluerov2_blueos_dvl_extension_dvl_ugps_button_marked](../img/bluerov2_blueos_dvl_extension_buttons_marked.png) @@ -90,14 +90,14 @@ In this configuration the BlueROV will base its position estimate *updates* on v ### How do I start an autonomous mission? -Blue Robotics wrote a guide on [how to start an autonomous mission with the DVL only](https://bluerobotics.com/learn/dvl-a50-integration/#auto-mode). The steps are the same when you use DVL and Underwater GPS together after you followed above guide for Mode "DVL+UGPS". +Blue Robotics wrote a guide on [how to start an autonomous mission with the DVL only](https://bluerobotics.com/learn/dvl-a50-integration/#auto-mode). The steps are the same when you use DVL and Underwater GPS together after you have followed this guide for Mode "DVL+UGPS". At the time of writing (November 2024) QGroundControl is still more suited for advanced usage like missions compared to the new Cockpit. ### Which mode am I currently using? Is Underwater GPS input enabled for sensor fusion or not? You can check if the correct parameters are set by navigating to "Autopilot Parameters" in BlueOS. It shows a searchable list of all currently set parameters. -Below table lists both default values of the parameters for two Ardusub versions and which values the DVL extension sets when you click on the respective buttons. The parameter set by the Underwater GPS extension is listed, too. +The table below lists both default values of the parameters for two Ardusub versions and which values the DVL extension sets when you click on the respective buttons. The parameter set by the Underwater GPS extension is listed, too. Parameters can be "not set" which is shown as an empty cell in the table. @@ -155,4 +155,3 @@ This is an overview figure of the sent mavlink messages: * The main input from the Underwater GPS to the autopilot is the mavlink message GPS_INPUT. * The [GitHub README](https://github.com/waterlinked/blueos-ugps-extension) provides more details. - diff --git a/docs/dvl/bluerov-integration.md b/docs/dvl/bluerov-integration.md index 4db755b5..70c36b49 100644 --- a/docs/dvl/bluerov-integration.md +++ b/docs/dvl/bluerov-integration.md @@ -1,32 +1,32 @@ ## Introduction -The Water Linked [DVLs](https://www.waterlinked.com/dvl) are designed to integrate with most ROVs and AUVs through ethernet and/or a serial interface (UART). To minimize the time between receipt of a DVL and having it up and running, the DVLs are shipped with an attached I/O interface, providing ease of connectivity with power, ethernet and serial. However, for most ROVs and AUVs, the DVL has to be integrated with the on-board electronics through a penetrator or a subsea connector. +The Water Linked [DVLs](https://www.waterlinked.com/dvl) are designed to integrate with most ROVs and AUVs through Ethernet and/or a serial interface (UART). To minimize the time between receipt of a DVL and having it up and running, the DVLs are shipped with an attached I/O interface for power, Ethernet, and serial connectivity. However, for most ROVs and AUVs, the DVL has to be integrated with the on-board electronics through a penetrator or a subsea connector. -This guide details how the [DVL-A50](dvl-a50.md) can be integrated with the BlueROV2. Exactly the same procedure can be carried out for the [DVL-A125](dvl-a125.md). +This guide details how the [DVL A50](dvl-a50.md) can be integrated with the BlueROV2. The same procedure can be carried out for the [DVL A125](dvl-a125.md). ## Parts and tools -What parts and tools needed depends on whether you intend to permanently attach the DVL-A50 to the BlueROV2, have it semi-permanently attached, or use a subsea connector for quick installation/removal. +The parts and tools needed depend on whether you intend to permanently attach the DVL A50 to the BlueROV2, have it semi-permanently attached, or use a subsea connector for quick installation/removal. -This guide details how to permanently attach the DVL-A50 to a BlueROV2. +This guide details how to permanently attach the DVL A50 to a BlueROV2. ### You will need -dvl-a50 +dvl-a50 -* [DVL-A50](https://waterlinked.com/shop/dvl-a50-114#attr=8,53) +* [DVL A50](https://waterlinked.com/shop/dvl-a50-114#attr=8,53) ![bluerov2_front](../img/bluerov2_front_300x300.png) * [BlueROV2](https://bluerobotics.com/store/rov/bluerov2/bluerov2/) -ETHSWITCH-R1-RP +ETHSWITCH-R1-RP -* Small ethernet switch. The one pictured here is from [BlueRobotics](https://bluerobotics.com/store/comm-control-power/tether-interface/ethswitch/), and ideal for use in the BlueROV2. +* Small Ethernet switch. The one pictured here is from [Blue Robotics](https://bluerobotics.com/store/comm-control-power/tether-interface/ethswitch/), and is ideal for use in the BlueROV2. dvl-bracket -* [DVL-A50 Bracket](https://waterlinked.com/shop/dvl-a50-mounting-bracket-115#attr=). This is optional, but protects the DVL-A50 and allows for down to 0 cm minimum altitude. +* [DVL A50 bracket](https://waterlinked.com/shop/dvl-a50-mounting-bracket-115#attr=). This is optional, but protects the DVL A50 and allows for down to 0 cm minimum altitude. You will also need: @@ -47,34 +47,34 @@ You will also need: * Utility knife * Wire stripping tool * Zip ties -* 4 x 30 cm (12") wires (options discussed under [Connect DVL-A50 and BlueROV2](#attach-dvl-a50-to-bluerov2)). If possible, use 2 x red and 2 x black wires. -* 15 cm (6") ethernet cable +* 4 x 30 cm (12") wires (options discussed under [Connect DVL A50 and BlueROV2](#attach-dvl-a50-to-bluerov2)). If possible, use 2 x red and 2 x black wires. +* 15 cm (6") Ethernet cable ## Preparation -### Separate I/O Interface from DVL-A50 +### Separate I/O Interface from DVL A50 -The first thing you will have to do before going about any of the installation options is to cut the DVL-A50 cable, separating the I/O Interface board. We recommend you do so near the end where the I/O Interface board is to begin with. +First, cut the DVL A50 cable to separate the I/O Interface board. We recommend cutting near the I/O Interface board end of the cable. ![cut-io-interface-rev3](../img/cut-io-interface-rev3.jpeg) -!!! Warning - The DVL-A50 cable is permanently attached and non-replaceable inside the DVL-A50. If you cut the cable too short you will either have to splice the cable with another cable, or order a new DVL-A50. Measure twice, cut once! +!!! warning + The DVL A50 cable is permanently attached and non-replaceable inside the DVL A50. If you cut the cable too short, you will either have to splice the cable with another cable or order a new DVL A50. Measure twice, cut once! ### Attaching the BlueROV2 mounting bracket -* Attach the BlueROV2 mounting bracket to the DVL-A50 using the 4 x M3x6 screws provided with the DVL-A50 BlueROV2 Integration Kit. +* Attach the BlueROV2 mounting bracket to the DVL A50 using the 4 x M3x6 screws provided with the DVL A50 BlueROV2 Integration Kit. ![attaching-mounting-bracket-to-dvl](../img/screw_on_dvl_bracket_to_dvl.png) -The BlueROV2 mounting bracket can be attached to the BlueROV2 in one of the 2 places indicated in the image below (standard BlueROV2). +The BlueROV2 mounting bracket can be attached to the BlueROV2 in one of the two places indicated in the image below (standard BlueROV2). -!!! Note - In this configuration the DVL-A50 is pointing backwards meaning both the x-direction and the y-direction are flipped. Multiplying the velocity data in x- and y-direction with -1 will flip coordinates back again to the same perspective frame of the BlueROV2. +!!! note + In this configuration, the DVL A50 is pointing backwards, meaning both the x-direction and y-direction are flipped. Multiplying the velocity data in x- and y-direction by -1 will flip the coordinates back to the same perspective frame as the BlueROV2. ![attaching-mounting-bracket-to-bluerov-standard](../img/bluerov2-dvl-mounting-positions.png) -If your BlueROV2 has the Heavy Configuration upgrade, the BlueROV2 mounting bracket can be attached such that the DVL-A50 is within the BlueROV2 frame. This allows for a minimum working distance of 0 cm for the DVL-A50. +If your BlueROV2 has the Heavy Configuration upgrade, the BlueROV2 mounting bracket can be attached such that the DVL A50 is within the BlueROV2 frame. This allows for a minimum working distance of 0 cm for the DVL A50. ![attaching-mounting-bracket-to-bluerov-heavy](../img/bluerov2-heavy-dvl-mounting-positions.png) @@ -86,14 +86,14 @@ Check that the BlueROV2 mounting bracket will attach properly to the BlueROV2 fr ![check-a50-bracket-fit](../img/check-a50-bracket-fit.jpeg) -### Final cable lenght +### Final cable length -With the DVL-A50 now attached to the BlueROV2 frame, find the appropriate cable length needed by leading the cable back to the penetrator end cap of the BlueROV2 and add the length of the electronics enclosure (30 cm) to the cable. This is the *minimum* required cable length. +With the DVL A50 now attached to the BlueROV2 frame, find the appropriate cable length by leading the cable back to the penetrator end cap of the BlueROV2 and adding the length of the electronics enclosure (30 cm) to the cable. This is the *minimum* required cable length. ![measure-cable-length-of-a50](../img/measure-cable-length-of-a50.jpeg) -!!! Tip - We recommend adding at least another 30 cm to the cable to provide enough service loop in case the penetrator fails or the leads get damaged. +!!! tip + We recommend adding at least another 30 cm to the cable to provide enough service loop in case the penetrator fails or the leads get damaged. Cut the cable to the final length. @@ -101,7 +101,7 @@ Cut the cable to the final length. ## Installation -The DVL-A50 will be permanently installed on the BlueROV2 with the I/O Interface board (supplied with the DVL-A50). +The DVL A50 will be permanently installed on the BlueROV2 with the I/O Interface board supplied with the DVL A50. ### I/O Interface preparation @@ -124,8 +124,8 @@ Desolder all the cut wires. Use solder wick and/or a desoldering pump to remove ![desoldered-io-interface](../img/desoldered-io-interface.jpeg) -!!! Warning - Using too much force or heat may delaminate the I/O Interface PCB, rendering the I/O Interface board useless. +!!! warning + Using too much force or heat may delaminate the I/O Interface PCB, rendering the I/O Interface board useless. ### Adding a penetrator @@ -140,7 +140,7 @@ Strip off 25-30 cm of the cable jacket using a cable jacket stripper, a utility ![stripped-a50-cable](../img/stripped-a50-cable.jpeg) -Follow the [WetLink Penetrator Assembly Guide](https://bluerobotics.com/learn/wetlink-penetrator-installation-guide/) by BlueRobotics to add a penetrator on the DVL-A50 cable. +Follow the [WetLink Penetrator Assembly Guide](https://bluerobotics.com/learn/wetlink-penetrator-installation-guide/) by Blue Robotics to add a penetrator on the DVL A50 cable. ### Removing a blank penetrator @@ -165,19 +165,19 @@ Remove the Vent Plug from the Vent Penetrator Bolt on the electronics enclosure. ![bluerov2-remove-vent](../img/bluerov2-remove-vent-1024x1024.jpg) -Remove a blank penetrator, sush as the one pictured below, from the 4” End Cap with the penetrator wrench. +Remove a blank penetrator, such as the one pictured below, from the 4” End Cap with the penetrator wrench. ![bluerov2-end-cap-remove](../img/bluerov2-end-cap-remove-1024x576.jpg) -### Install DVL-A50 penetrator +### Install DVL A50 penetrator !!! note - The following images shows the old penetrator from BlueRobotics. The procedure is the same with the new WetLink penetrators. + The following images show the old penetrator from Blue Robotics. The procedure is the same with the new WetLink penetrators. -To install DVL-A50 into the end cap, you will need the following parts and tools: +To install the DVL A50 into the end cap, you will need the following parts and tools: -* DVL-A50 with installed cable penetrator +* DVL A50 with installed cable penetrator * Penetrator O-ring (included with [M10-7.5mm-HC WetLink Penetrator](https://bluerobotics.com/store/cables-connectors/penetrators/wlp-vp/?attribute_for-cable-diameter=WLP-M10-7.5MM-HC+%28for+7.0+mm+%C2%B1+0.3+mm+cable+diameter%29&attribute_package-quantity=1-Pack) from Blue Robotics) * [Bulkhead Wrench](https://bluerobotics.com/store/cables-connectors/tools/wlp-bulkhead-wrench/?attribute_bulkhead-size=M10) from Blue Robotics * Silicone Grease @@ -187,40 +187,40 @@ Wipe the exterior surface of the electronics enclosure end cap clean with isopro Remove the O-ring from the bag -Install the O-ring onto the DVL-A50 cable penetrator and apply silicone grease to it. +Install the O-ring onto the DVL A50 cable penetrator and apply silicone grease to it. ![grease-o-ring-on-a50-penetrator](../img/grease-o-ring-on-a50-penetrator.jpeg) ![o-ring-on-a50-penetrator](../img/o-ring-on-a50-penetrator.jpeg) -Push the wires throught the hole in the end cap where you previously removed a blank penetrator from. +Push the wires through the hole in the end cap where you previously removed a blank penetrator. ![a50-wires-through-bluerov2-end-cap](../img/a50-wires-through-bluerov2-end-cap.jpeg) -!!! Tip - Since the penetrator has to be screwed on, adding a bit of tape around the end of the wires helps them stay untangles while turning. Also twisting the DVL-A50 cable in a clock-wise direction will aid in screwing on the penetrator. +!!! tip + Since the penetrator has to be screwed on, adding a bit of tape around the end of the wires helps them stay untangled while turning. Twisting the DVL A50 cable clockwise will also help when screwing on the penetrator. -Screw on the DVL-A50 cable penetrator to the end cap. Tighten to finger tight, then use the penetrator wrench to tighten it an additional ~1/16 of a turn. If you can’t loosen it with your fingers, it is tight enough. +Screw the DVL A50 cable penetrator onto the end cap. Tighten to finger tight, then use the penetrator wrench to tighten it an additional ~1/16 of a turn. If you can’t loosen it with your fingers, it is tight enough. ![screwed-in-a50-penetrator](../img/screwed-in-a50-penetrator.jpeg) ![tightened-a50-penetrator](../img/tightened-a50-penetrator.jpeg) ### Reinstall I/O Interface Board -To reinstall the I/O Interface Board onto the DVL-A50 cable you will need: +To reinstall the I/O Interface board onto the DVL A50 cable, you will need: * Wire stripping tool * Soldering iron * Solder wire * Zip tie -With the DVL-A50 penetrator now through the 4" End Cap, strip off 2-3 mm of the ends of all the wires. Wire sizes are detailed in the table below. The blue pair can be removed as it is not used for the DVL-A50. +With the DVL A50 penetrator now through the 4" End Cap, strip off 2-3 mm of the ends of all the wires. Wire sizes are detailed in the table below. The blue pair can be removed because it is not used for the DVL A50. ![stripped-wires-a50](../img/stripped-wires-a50.jpeg) -!!! Warning - The two wires of a twisted wire pair are fully colored and fully white (the table below shows the white wires having a stripe of the complementing color, this is **not** the reality and only for reference). Keep track of which white wire is paired with which colored wire! Also note that the wiring in the images below differ from that of the table below. Please follow the table! +!!! warning + The two wires of a twisted wire pair are fully colored and fully white. The table below shows the white wires with a stripe of the complementing color, but this is only for reference. Keep track of which white wire is paired with which colored wire. The wiring in the images below also differs from the table below. Please follow the table. -Re-solder the leads of the DVL-A50 cable to the I/O Interface board following the table below: +Re-solder the leads of the DVL A50 cable to the I/O Interface board following the table below: -| DVL-A50 cable | I/O Interface pad | Function | Diameter (mm) | AWG\# | +| DVL A50 cable | I/O Interface pad | Function | Diameter (mm) | AWG\# | | -------------------------------------------------------------- | :--------------- | :------------- | :------------ | :---- | | ![4tp2p_black_lead](../img/4tp2p_black_lead.png) | GND | Power ground | 0.6 mm | 22 | | ![4tp2p_red_lead](../img/4tp2p_red_lead.png) | VIN | Power in | 0.6 mm | 22 | @@ -239,14 +239,14 @@ Zip tie the soldered wires to the I/O Interface board to protect the solder join ### Connect to BlueROV2 -To connect the DVL-A50 to the BlueROV2 you will need: +To connect the DVL A50 to the BlueROV2, you will need: -* 2 x 30 cm (12") wires for power to the DVL-A50 -* [BlueRobotics ethernet switch](https://bluerobotics.com/store/comm-control-power/tether-interface/ethswitch/) -* 6" ethernet cable +* 2 x 30 cm (12") wires for power to the DVL A50 +* [Blue Robotics Ethernet switch](https://bluerobotics.com/store/comm-control-power/tether-interface/ethswitch/) +* 6" Ethernet cable * Zip ties -To provide power to the DVL-A50 you can either use (A) a 2-pin [Molex MicroFit3.0 cable assembly](https://octopart.com/214751-2022-molex-109474124), (B) solder on a [Würth screw terminal](https://octopart.com/691137710002-w%C3%BCrth+elektronik-78871135), or (C) directly solder on 2 wires to the power pads. +To provide power to the DVL A50, you can either use (A) a 2-pin [Molex MicroFit3.0 cable assembly](https://octopart.com/214751-2022-molex-109474124), (B) solder on a [Würth screw terminal](https://octopart.com/691137710002-w%C3%BCrth+elektronik-78871135), or (C) directly solder on 2 wires to the power pads. ![io_interface_power](../img/io_interface_power.png) @@ -258,15 +258,15 @@ To provide power to the DVL-A50 you can either use (A) a 2-pin [Molex MicroFit3. ![power_terminal_negative](../img/power_terminal_negative.png) -!!! Warning - The Power Terminal Blocks are unregulated and directly connected to the battery. Any short may generate several amps which will fry most circuits. Check that the wires are secured properly in both ends. +!!! warning + The Power Terminal Blocks are unregulated and directly connected to the battery. Any short may generate several amps, which will damage most circuits. Check that the wires are secured properly at both ends. -Install the BlueRobotics ethernet switch following the [Ethernet Switch Installation Guide for the BlueROV2](https://bluerobotics.com/learn/ethernet-switch-installation-guide-for-the-bluerov2/) by BlueRobotics. +Install the Blue Robotics Ethernet switch following the [Ethernet Switch Installation Guide for the BlueROV2](https://bluerobotics.com/learn/ethernet-switch-installation-guide-for-the-bluerov2/) by Blue Robotics. -With power and ethernet switch now sorted, connect a 6" ethernet cable from the ethernet switch to the IO Interface board. +With power and the Ethernet switch now sorted, connect a 6" Ethernet cable from the Ethernet switch to the I/O Interface board. -!!! Tip - Some thick double-sided sticky tape and zip ties can be used to secure the I/O Interface to the electronics frame inside the BlueROV2. +!!! tip + Some thick double-sided sticky tape and zip ties can be used to secure the I/O Interface to the electronics frame inside the BlueROV2. ### Reassemble BlueROV2 electronics enclosure @@ -282,19 +282,19 @@ Reinstall 4” Watertight Enclosure onto ROV with the following steps: * Apply silicone grease to the two radial O-rings on the O-Ring Flange (4” Series) that is attached to the Electronics Tray. * Install the Watertight Enclosure (4” Series) with installed Dome End Cap to the O-Ring Flange (4” Series). -!!! Warning - Use caution when sliding the 4" Watertight Enclosure over the electronics as space may be tight (collides with electronics) and wires can get trapped between the 4" tube and the 4" end cap. +!!! warning + Use caution when sliding the 4" Watertight Enclosure over the electronics. Space may be tight, and wires can get trapped between the 4" tube and the 4" end cap. Mount the Electronics Enclosure to the frame using the M3x16 screws so that the dome is on the same side as the front center panels (the center panels without the 3 large holes). Install the M3x16 screws through the clips and into the Enclosure Cradle (4” Series). It is easier to install these screws if the clips are not fully tightened until all screws are through the clips and threading into the Enclosure Cradle (4” Series). This allows clips to rotate so you can find the threaded hole in the Enclosure Cradle (4” Series) easily. ![bluerov2-remove-electronic](../img/bluerov2-remove-electronic-1024x743.png) -### Attach DVL-A50 to BlueROV2 +### Attach DVL A50 to BlueROV2 !!! note - The following images show the old version of the DVL-A50 with steel housing. The new housing has the same dimensions as the old. + The following images show the old version of the DVL A50 with steel housing. The new housing has the same dimensions as the old. -Attach the DVL-A50 to the BlueROV2 using the 2 x M5x16 screws provided with the DVL-A50 BlueROV2 Integration Kit through the two holes you've made previously. +Attach the DVL A50 to the BlueROV2 using the 2 x M5x16 screws provided with the DVL A50 BlueROV2 Integration Kit through the two holes you made previously. ![dvl-attached-to-bluerov2](../img/dvl_attached_to_bluerov2.png) @@ -304,17 +304,17 @@ Excess cable can be bundled together and attached to the BlueROV2 frame using zi ## Software -The DVL-A50 requires an extension in BlueOS to be able to communicate with the autopilot (Pixhawk or Navigator flight controller). +The DVL A50 requires an extension in BlueOS to communicate with the autopilot (Pixhawk or Navigator flight controller). BlueOS has to be updated to **BlueOS 1.1.0** or newer to assure that extensions are supported sufficiently. -* After the update install the latest BlueOS-Water-Linked-DVL extension from the BlueOS extension manager. It is best to disable the BlueOS "Water Linked UGPS"-extension if you have that installed. +* After the update, install the latest BlueOS-Water-Linked-DVL extension from the BlueOS extension manager. It is best to disable the BlueOS "Water Linked UGPS" extension if you have that installed. -!!! Note - If you want to use both DVL and UGPS you can find a detailed guide [here](bluerov-integration-dvl-ugps.md) +!!! note + If you want to use both DVL and UGPS, see the [DVL with UGPS for BlueROV2 guide](bluerov-integration-dvl-ugps.md). ![bluerov2_blueos_extension_installation_01_extension_manager](../img/bluerov2_blueos_extension_installation_01_extension_manager.png) -* Open the interface of the DVL-extension and click the button "Load parameters for DVL". Those parameters are persistent over reboots, which means that this button only needs to be pressed once and not every time you restart the ROV. +* Open the interface of the DVL extension and click the button "Load parameters for DVL". Those parameters are persistent over reboots, which means that this button only needs to be pressed once and not every time you restart the ROV. ![bluerov2_blueos_dvl_extension_dvl_ugps_button_marked](../img/bluerov2_blueos_dvl_extension_buttons_marked.png) @@ -324,5 +324,5 @@ BlueOS has to be updated to **BlueOS 1.1.0** or newer to assure that extensions * Set the global vehicle position in the DVL extension every time you start the ROV. -!!! Note - There is a known bug where the I2C address of the pressure sensor is set wrong, and so depth is not received properly. This can be fixed by setting the parameter `BARO_PROBE_EXT` to `768` and then reboot the ROV. +!!! note + There is a known bug where the I2C address of the pressure sensor is set wrong, and so depth is not received properly. This can be fixed by setting the parameter `BARO_PROBE_EXT` to `768` and then rebooting the ROV. diff --git a/docs/dvl/configuration.md b/docs/dvl/configuration.md new file mode 100644 index 00000000..a280da26 --- /dev/null +++ b/docs/dvl/configuration.md @@ -0,0 +1,90 @@ +# Settings and configuration + +Use settings when the DVL installation, operating environment, or integration interface changes. Avoid changing settings during an operation unless you understand how the change affects velocity output, bottom lock, and dead reckoning. + +## Open settings + +Open the DVL web GUI and go to the settings or configuration page for your model family: + +* DVL A50/A125: [preview the configuration interface on the demo site](https://dvl.demo.waterlinked.com/#/config) +* DVL A100/A250: [preview the configuration interface on the demo site](https://dvl2.demo.waterlinked.com/#config) + +Configuration can also be performed by protocol: + +* [DVL A50/A125 TCP JSON API configuration](dvl-json-protocol.md#configuration-over-json) +* [DVL A50/A125 serial configuration](dvl-serial-protocol.md#configuration-over-serial) +* [DVL A100/A250 TCP JSON API configuration](dvl-a250_a100-json-protocol.md#configuration-over-json) +* [DVL A100/A250 serial configuration](dvl-a250_a100-serial-protocol.md#configuration-over-serial) + +For DVL A50/A125, output protocol settings are also available in a separate [preview of the output configuration on the demo site](https://dvl.demo.waterlinked.com/#/outputs). + +## Operating configurations + +| Setting | Use | +| --- | --- | +| Speed of sound | Set the speed of sound for the water conditions. | +| Mounting rotation offset | Align DVL output with the vehicle frame. See [Axes](axes.md). | +| Acoustic enabled | Enable or disable acoustic pinging. | +| Dark mode | Disable the LED to avoid interference with cameras. | +| Range mode | Limit the altitude range used when searching for bottom lock. See [Range mode](range-mode.md). | +| Periodic cycling | Periodically validate that the DVL is locked to the real bottom. See [Periodic cycling](#periodic-cycling). | +| Water tracking | Use velocity relative to the water column instead of the bottom when supported. See [Water tracking](water-tracking.md). | +| Hardware trigger | Activate [hardware triggering](dvl-triggering.md#hardware-triggering). Only for A100/A250. | + +!!! warning + Incorrect speed of sound, mounting rotation, range mode, tracking mode, or output protocol settings can cause the DVL data to appear incorrect, even when the hardware is functioning properly. + +## Periodic cycling + +Periodic cycling is available on all DVL models. + +When periodic cycling is enabled, the DVL checks every 10 seconds that the bottom it has locked onto is the actual bottom. The check verifies whether there are closer reflections that should be treated as the real bottom. + +Periodic cycling is enabled by default. It is useful in reflective environments with many multipath reflections, such as tanks or pools. + +The drawback is that some measurements are lost during the validation check. If you operate in open water with stable bottom conditions and need as many measurements as possible, consider turning periodic cycling off. If multipath or reflections are a concern, keeping periodic cycling on can improve bottom validation. + +To change periodic cycling: + +1. Open the settings or configuration page for your DVL model. +2. Find the periodic cycling setting. +3. Turn it on or off for the operating environment. +4. Save the configuration. + +You can also configure periodic cycling with the `periodic_cycling_enabled` parameter over the TCP JSON API or serial protocol. + +## Output settings + +Use output settings when an external system needs a specific serial protocol, TCP JSON API, or PD format. + +1. Choose the protocol required by the receiving system. +2. Configure serial settings if the integration uses the serial interface. +3. Save the configuration. +4. Reconnect or restart the receiving system if required by the integration. + +Electrical interfaces differ by model: + +* DVL A50 and DVL A125 use a 3.3 V UART interface that is 5 V tolerant. +* DVL A100 and DVL A250 use RS232. + +See [DVL electrical connection](electrical.md#terminal-serial-interface) and [Integration](integration.md) before connecting external equipment. + + +## Commands + +Actions that can be performed on the DVL. + +| Command | Use | +| --- | --- | +| Reset dead reckoning | Reset the origin and attitude from the current DVL position and attitude. See [Dead reckoning](dead-reckoning.md). | +| Calibrate gyro | Calibrate the gyro. Only for A50/A125. | +| Trigger ping | Tell the DVL to send a single ping. This has more latency than hardware triggering. | + +## Network and maintenance + +| Setting | Use | +| --- | --- | +| Network configuration | Use DHCP or a static IP address. See [Network Setup](networking.md). | +| System time configuration | Configure NTP or set time manually. | +| Factory reset | Reset all configuration. Reboot is required. | +| Reboot | Restart the DVL. | diff --git a/docs/dvl/dead-reckoning.md b/docs/dvl/dead-reckoning.md index 25cf6a68..f52e40d0 100644 --- a/docs/dvl/dead-reckoning.md +++ b/docs/dvl/dead-reckoning.md @@ -1,32 +1,43 @@ +# Dead reckoning + ## Introduction -The DVL-A50 and DVL-A125 run a dead reckoning algorithm which estimates the orientation and position of the DVL. This uses both the velocities which the DVL calculates and its integrated IMU (Inertial Measurement Unit). +All our DVLs run a dead-reckoning algorithm that estimates the orientation and position of the DVL. This uses the velocities calculated by the DVL and its integrated IMU/AHRS. ## Starting dead reckoning -1. Calibrate the gyroscope by pressing *More -> Calibrate gyro* in the [GUI](../dvl/gui/dashboard.md) whilst the DVL is stationary. -2. Click the 'Reset' button ![](../img/dvl_gui_icon_reset.png) in the [GUI](../dvl/gui/dashboard.md), or send a reset command over the TCP or serial [protocol](dvl-protocol.md). +Reset dead reckoning before using the local position estimate. + +For DVL A50/A125: + +1. Calibrate the gyroscope by pressing *More -> Calibrate gyro* in the [web GUI](dvl-a50_a125-gui.md) while the DVL is stationary. +2. Click the **Reset** button ![](../img/dvl_gui_icon_reset.png) in the [dashboard](dvl-a50_a125-gui.md#dashboard-live-data), or send a reset command over the [TCP JSON API](dvl-json-protocol.md#reset-dead-reckoning) or [serial protocol](dvl-serial-protocol.md#reset-dead-reckoning-wcr). -Failure to perform gyro calibration will result in less accurate dead reckoning. +For DVL A100/A250, gyro calibration is not needed. Reset commands over the [TCP JSON API](dvl-a250_a100-json-protocol.md#reset-dead-reckoning) or [serial protocol](dvl-a250_a100-serial-protocol.md#reset-dead-reckoning-wcr) are included for backward compatibility and do not affect dead reckoning on DVL A100/A250. ## Frame -The position, speed, and roll, pitch, and yaw angles outputted by the dead reckoning algorithm are with respect to the frame defined at time zero (the time of the last reset, or else at start up) by the axes of the [vehicle frame](axes.md#vehicle-frame). +The position, speed, roll, pitch, and yaw angles output by the dead-reckoning algorithm are relative to the frame defined at time zero: the time of the last reset, or startup if no reset has been performed. This frame is defined by the axes of the [vehicle frame](axes.md#vehicle-frame). ## Speed and position -The speed and position of the DVL are calculated by integration of its acceleration, corrected by the velocity it calculates by means of its acoustic signal processing. A Kalman filter is used; the [roll, pitch, and yaw angles](#orientation) outputted by the DVL are also part of the input. +The speed and position of the DVL are calculated by integrating its acceleration, corrected by the velocity it calculates with acoustic signal processing. A Kalman filter is used; the [roll, pitch, and yaw angles](#orientation) output by the DVL are also part of the input. -When the DVL fails in its determination of velocity, speed and position are predicted only by acceleration. This will result in large errors, indicated by an increase in the figure of merit (FOM), which is an estimated standard deviation of the position in the X-Y plane. +When the DVL cannot determine velocity, speed and position are predicted only from acceleration. This will result in large errors, indicated by an increase in the figure of merit (FOM), which is an estimated standard deviation of the position in the X-Y plane. !!! note When the DVL is powered on in the air, its position will drift significantly. This should be ignored, and dead reckoning should be [started](#starting-dead-reckoning) in water when ready. -The position of the DVL can be viewed in the GUI [dashboard](../dvl/gui/dashboard.md) or be fetched by [API](dvl-protocol.md#dead-reckoning-report). +The position of the DVL can be viewed in the web GUI dashboard or fetched by API: + +* [DVL A50/A125 web GUI dashboard](dvl-a50_a125-gui.md#dashboard-live-data) +* [DVL A100/A250 web GUI dashboard](dvl-a250_a100-gui.md#velocity-and-navigation) +* [DVL A50/A125 TCP JSON API](dvl-json-protocol.md#dead-reckoning-report) +* [DVL A100/A250 TCP JSON API](dvl-a250_a100-json-protocol.md#dead-reckoning-report) ## Orientation -The calculation of the orientation of the DVL is based upon the accelerometer and gyroscope measurements of its IMU. The orientation is represented by roll, pitch, and yaw angles, and can be viewed in the GUI [dashboard](../dvl/gui/dashboard.md) or be fetched by [API](dvl-protocol.md#dead-reckoning-report). +The orientation of the DVL is based on the accelerometer and gyroscope measurements from its IMU/AHRS. The orientation is represented by roll, pitch, and yaw angles, and can be viewed in the web GUI dashboard or fetched by API. - Roll is a rotation around the X axis of the DVL - Pitch is a rotation around the Y axis of the DVL @@ -35,12 +46,11 @@ The calculation of the orientation of the DVL is based upon the accelerometer an For orientation to function correctly, the DVL must be deployed in accordance with its [axis conventions](axes.md). !!! note - A small tilt in the DVL mounting, though it will result in almost no position error with respect to the X and Y axes, may lead a significant error with respect to the Z axis. This change will be a projection of the true horizontal position onto the Z axis. For example, when the DVL is mounted with 5° tilt and the horizontal displacement of the DVL is 100m since last reset, the total displayed distance in the X, Y plane will be 99.6 m, and the Z position will be ±9 m. + A small tilt in the DVL mounting, though it will result in almost no position error with respect to the X and Y axes, may lead to a significant error with respect to the Z axis. This change will be a projection of the true horizontal position onto the Z axis. For example, when the DVL is mounted with 5° tilt and the horizontal displacement of the DVL is 100 m since the last reset, the total displayed distance in the X, Y plane will be 99.6 m, and the Z position will be ±9 m. When dead reckoning is [reset](#starting-dead-reckoning), the roll, pitch, and yaw angles are set to zero. ## Yaw drift !!! note - The yaw angle may experience drift. This drift can be decreased to 0.1-0.3° per minute by [calibration](#starting-dead-reckoning) of the gyroscope. - + For DVL A50/A125, yaw drift can be decreased to 0.1-0.3° per minute by [calibration](#starting-dead-reckoning) of the gyroscope. For DVL A100/A250, gyro calibration is not needed. diff --git a/docs/dvl/diagnostic-log.md b/docs/dvl/diagnostic-log.md new file mode 100644 index 00000000..1e9d6e42 --- /dev/null +++ b/docs/dvl/diagnostic-log.md @@ -0,0 +1,37 @@ +# Diagnostic log + +A diagnostic log contains DVL logs and measurements that help Water Linked support investigate issues such as loss of bottom lock, invalid velocity, weak signal, communication problems, or unexpected behavior. + +## When to collect a diagnostic log + +Collect a diagnostic log when: + +* Water Linked support requests it. +* The DVL loses bottom lock unexpectedly. +* Velocity becomes invalid or drops out. +* Measurements are weak or noisy. +* You experience communication or web GUI issues. + +## How to collect a diagnostic log + +1. Put the DVL in the same environment where the issue occurs. +2. Open the DVL web GUI. +3. Open the diagnostic log or diagnostics page for your DVL model. +4. Follow the instructions in the web GUI to create and download the diagnostic log. +5. Send the diagnostic log to Water Linked support together with relevant installation and test information. + +## Demo GUI links + +* [DVL A50/A125 diagnostic log demo](https://dvl.demo.waterlinked.com/#/collect) +* [DVL A100/A250 diagnostics demo](https://dvl2.demo.waterlinked.com/#diagnostics) + +For more context on the web GUI pages, see [DVL A50/A125 web GUI](dvl-a50_a125-gui.md) and [DVL A100/A250 web GUI](dvl-a250_a100-gui.md). + +## What to include when contacting support + +Use the [support package checklist](support-package-checklist.md) when preparing a support request. + +See [How to diagnose](how-to-diagnose.md) for troubleshooting guidance before contacting support. + +!!! note "Transducer numbering and protocol IDs" + Mechanical/transducer diagrams number the transducers from 1 to 4. In protocol messages and diagnostic logs, the transducer `id` uses zero-based numbering from 0 to 3. The `id` is therefore the transducer number minus 1. diff --git a/docs/dvl/dvl-a100.md b/docs/dvl/dvl-a100.md new file mode 100644 index 00000000..9543cbbc --- /dev/null +++ b/docs/dvl/dvl-a100.md @@ -0,0 +1,76 @@ +# DVL A100 + +The DVL A100 is a compact, high-accuracy Doppler Velocity Log for lightweight and integration-friendly platforms. + +It is designed for close-range and mid-range operation up to 100 m altitude, with Ethernet and RS232 serial interfaces for vehicle and topside integrations. + +The DVL A100 is part of the same product family as the DVL A250. From a web GUI, configuration, protocol, and integration perspective, the two products are documented together where the behavior is shared. The main differences are operating range, frequency, speed limits, size, weight, depth rating, and physical configuration. + + + +## Key features + +* Altitude range from 5 cm to 100 m. +* 4-beam convex Janus transducer array. +* 625 kHz transducer frequency. +* Integrated AHRS for dead reckoning. +* Ethernet and RS232 serial communication. +* TCP JSON API, serial protocol, PD4, and PD6. PD0 is planned but not available yet. +* Side cable entry and rear O-ring interface versions. + +## Mechanical and installation overview + +Use the mechanical information together with the common [Installation](installation.md) guidance. Before final drawings are added, verify dimensions, mounting hole placement, cable routing, and line of sight against the latest product drawing or datasheet. + +### Dimensions + +* **Diameter**: 90 mm +* **Height**: 34 mm +* **Weight in air**: 0.2 kg +* **Weight in water**: 0.125 kg +* **Depth rating**: 1,000 m +* **Material**: PEEK (housing), Stainless Steel 316 (back plate) + + + +### Physical interface versions + +The DVL A100 is available in these physical interface versions: + +* Side cable entry version with 3 m shielded cable. +* Rear O-ring interface version with 1 m shielded cable. + + + +## Mounting holes + +Use a rigid mount so the DVL moves with the vehicle or boat. Avoid flexible poles, unsupported brackets, and mounts that can vibrate. + + + +## Transducer numbering + +Transducer numbering is useful when comparing web GUI or protocol diagnostics with the physical installation. + +Mechanical drawings number the transducers from 1 to 4. Protocol messages and diagnostic logs use zero-based transducer `id` values from 0 to 3. See [Transducer numbering and protocol IDs](axes.md#transducer-numbering-and-protocol-ids). + + + +## Transducer beam geometry + +Keep all beam paths unobstructed. Avoid mounting locations where brackets, frames, skids, cables, thrusters, propellers, or hull structures can intersect the beam paths. + +The DVL A100 beam angle is 22.5 degrees. + + + +## Line of sight + +The DVL needs a clear acoustic path to the seabed or another reflecting surface. Strong turbulence, bubbles, vibration, and operation very close to the surface can reduce signal quality or cause loss of bottom lock. + +For boat-mounted installations, consider the flow around the hull and avoid positions where bubbles or aerated water pass across the transducers. For ROV/AUV installations, avoid mounting directly in thruster wash or near moving parts. + + +## Datasheet + +[Datasheet](https://www.waterlinked.com/web/content/108663?unique=39e82f816d08f4d2270df5a9e9f8b6822e9790fe&download=true) diff --git a/docs/dvl/dvl-a125.md b/docs/dvl/dvl-a125.md index 0ee2aea2..73cddb0a 100644 --- a/docs/dvl/dvl-a125.md +++ b/docs/dvl/dvl-a125.md @@ -1,32 +1,29 @@ -# DVL-A125 +# DVL A125 -[Buy DVL-A125 here!](https://waterlinked.com/product/dvl-a125/) +[Buy DVL A125 here](https://waterlinked.com/product/dvl-a125/) ![dvl_A125](../img/WL-21037-2_DVL-A125_InHand_1600.jpg) ## Description -The [DVL-A125](https://www.waterlinked.com/dvl/dvl-a125) is the next step up from the [DVL-A50](https://www.waterlinked.com/dvl/dvl-a50), providing even better performance at greater distances while still keeping a small form factor relative to competing DVLs. +The [DVL A125](https://www.waterlinked.com/dvl/dvl-a125) is the next step up from the [DVL A50](https://www.waterlinked.com/dvl/dvl-a50), providing better performance at greater distances while still keeping a small form factor relative to competing DVLs. -The DVL-A125 builds on the already impressive feats of the DVL-A50 with its increased performance, small 4 beam setup, open interface protocol and mid-to-low cost. +The DVL A125 builds on the DVL A50 with increased performance, a small 4-beam setup, an open interface protocol, and mid-to-low cost. -The DVL estimates velocity relative to the sea bottom by sending acoustic waves from the four angled transducers and then measure the frequency shift (doppler effect) from the received echo. By combining the measurements of all four transducers and the time between each acoustic pulse, it is possible to very accurately estimate the speed and direction of movement. - - -!!! Tip - Keep the DVL-A125 in a bucket of water to ensure sufficient cooling when using the DVL on a workbench. +!!! tip + Keep the DVL A125 in a bucket of water to ensure sufficient cooling when using the DVL on a workbench. ## Dimensions ![dvl_A125_dimensions](../img/DVL-A125--Dimensions.png) -###Cable dimensions -Delivered cable length: 3.0m +### Cable dimensions +Delivered cable length: 3.0 m -Cable diameter: 7.8mm +/- 0.2mm +Cable diameter: 7.8 mm +/- 0.2 mm -## Mounting Holes +## Mounting holes ![dvl_A125_mounting_holes_drawing](../img/dvl-a125_mounting_holes_drawing.png) @@ -35,6 +32,7 @@ Cable diameter: 7.8mm +/- 0.2mm ![dvl_A125_transducer_numbering](../img/DVL-A125--Transducer-Numbering.png) +Mechanical drawings number the transducers from 1 to 4. Protocol messages and diagnostic logs use zero-based transducer `id` values from 0 to 3. See [Transducer numbering and protocol IDs](axes.md#transducer-numbering-and-protocol-ids). ## Transducer beam width diff --git a/docs/dvl/dvl-a250.md b/docs/dvl/dvl-a250.md new file mode 100644 index 00000000..4ddef552 --- /dev/null +++ b/docs/dvl/dvl-a250.md @@ -0,0 +1,71 @@ +# DVL A250 + +The [DVL A250](https://www.waterlinked.com/dvl/dvl-a250) is the most capable DVL in the lineup, delivering long-range performance while maintaining a compact and efficient design. + +Operating at lower frequency for extended reach, the A250 enables reliable velocity measurements at distances up to 250 m, making it suitable for demanding subsea operations. + +The DVL A250 combines high performance, a compact 4-beam setup, open interface protocol, and a competitive cost, making it a powerful solution for larger vehicles and deep-water applications. + + + +## Dimensions and FOV + +Use the mechanical information together with the common [Installation](installation.md) guidance. Verify dimensions, mounting hole placement, cable routing, and line of sight against the latest product drawing or datasheet. + +### Dimensions + +* **Diameter**: 149 mm +* **Height**: 40 mm +* **Weight in air**: 1.65 kg +* **Weight in water**: 0.75 kg +* **Depth rating**: 4,000 m for side-entry cable configuration; rear O-ring interface version rated to 1,000 m +* **Material**: PEEK (housing), Stainless Steel 316 (back plate) + +Use the drawings below as mechanical reference for the two A250 interface variants. + +### Rear O-ring interface version + +![DVL A250 rear O-ring interface mechanical drawing](../img/dvl_a250_back_entry_drawing.png) + +### Side cable entry version + +![DVL A250 side cable entry mechanical drawing](../img/dvl_a250_front_side_drawing.png) + +### Cable dimensions + + + +The DVL A250 is available with side-entry cable and rear O-ring interface options. A Seacon connector option is available for side-entry versions only. + +## Mounting holes + +Use a rigid mount so the DVL moves with the vehicle or boat. Avoid flexible poles, unsupported brackets, and mounts that can vibrate. + +Use the mechanical drawings above as the reference for mounting-hole placement. + +## Transducer numbering + +Transducer numbering is useful when comparing web GUI or protocol diagnostics with the physical installation. + +Mechanical drawings number the transducers from 1 to 4. Protocol messages and diagnostic logs use zero-based transducer `id` values from 0 to 3. See [Transducer numbering and protocol IDs](axes.md#transducer-numbering-and-protocol-ids). + + + +## Transducer beam geometry + +Keep all beam paths unobstructed. Avoid mounting locations where brackets, frames, skids, cables, thrusters, propellers, or hull structures can intersect the beam paths. + + +Half-power beam width is 22.5° + +## Line of sight + +The DVL needs a clear acoustic path to the seabed or another reflecting surface. Strong turbulence, bubbles, vibration, and operation very close to the surface can reduce signal quality or cause loss of bottom lock. + +For boat-mounted installations, consider the flow around the hull and avoid positions where bubbles or aerated water pass across the transducers. For ROV/AUV installations, avoid mounting directly in thruster wash or near moving parts. + + + +## Datasheet + +[Datasheet](https://www.waterlinked.com/web/content/108461?unique=7dbba77aaa00fa0f5a38e5d998abe18965f4ddbe&download=true) diff --git a/docs/dvl/dvl-a250_a100-gui.md b/docs/dvl/dvl-a250_a100-gui.md new file mode 100644 index 00000000..cd41b7b9 --- /dev/null +++ b/docs/dvl/dvl-a250_a100-gui.md @@ -0,0 +1,91 @@ +# DVL A100/A250 web GUI + +This page applies to DVL A100 and DVL A250. + +The DVL A100/A250 web GUI can be used to check live status, configure settings, view diagnostics, collect diagnostic logs, and view software and device information. + +## Open the web GUI + +1. Connect power and Ethernet to the DVL. +2. Make sure the DVL is submerged before normal operation. +3. Open a web browser and go to the DVL address: + * `http://waterlinked-dvl` when mDNS is available. + * `http://192.168.194.95` when using the fallback IP. +4. See [Network Setup](networking.md) if the web GUI does not open. + +## Demo GUI + +Use the public [DVL A100/A250 demo GUI](https://dvl2.demo.waterlinked.com/) to explore the interface without connecting to a DVL. + +The demo runs on simulated data. It does not replace testing with your own DVL in water. Hardware status, bottom lock, acoustic conditions, and output integrations must still be verified on the real installation. + +## Dashboard { #velocity-and-navigation } + +Use the dashboard to view the current DVL status, velocity data, bottom lock state, dead-reckoning information, and other live information. + +Open the public [dashboard demo page](https://dvl2.demo.waterlinked.com/). + +### Verify bottom lock + +1. Confirm that the DVL is submerged and the transducers have a clear line of sight to the bottom. +2. Open the dashboard. +3. Check that acoustics are enabled. +4. Check that velocity is valid. +5. Check that altitude and transducer distances are stable and reasonable for the test environment. +6. If you use the data stream for integration, compare the web GUI status with the TCP JSON API or serial output. + +!!! note + A DVL can be connected and healthy without having bottom lock. Bottom lock also depends on altitude, bottom conditions, acoustic noise, range mode, and vehicle motion. + +If velocity is invalid or bottom lock is unreliable, see [How to diagnose](how-to-diagnose.md). + +### View velocity and navigation + +1. Open the dashboard. +2. Check that velocity is valid before using the values. +3. Review horizontal velocity, vertical velocity, altitude, and transducer validity. +4. Use figure of merit or uncertainty indicators as a confidence check when they are available. +5. Use the local map/dead-reckoning view only after checking the dead reckoning limitations. + +See [Dead reckoning](dead-reckoning.md) for the reference frame and limitations. + +!!! warning + Dead reckoning will drift over time. Do not use the map view as an absolute position reference unless your system also provides an external position reference. + +## Configuration + +Use the configuration page to change DVL settings such as speed of sound, range mode, mounting rotation, network settings, and maintenance actions. + +Open the public [configuration demo page](https://dvl2.demo.waterlinked.com/#config). + +See [Settings and configuration](configuration.md), [Axes](axes.md), [Range mode](range-mode.md), and [Water tracking](water-tracking.md). + +Gyro calibration is not needed for DVL A100/A250. + + + + + + + +## Diagnostics and diagnostic log { #diagnostics-and-support } + +Use the diagnostics page to view live diagnostic information and collect a diagnostic log when troubleshooting or when requested by Water Linked support. + +Open the public [diagnostics demo page](https://dvl2.demo.waterlinked.com/#diagnostics). + +See [Diagnostic log](diagnostic-log.md) for collection guidance, [How to diagnose](how-to-diagnose.md) for symptom-based checks, and the [support package checklist](support-package-checklist.md) when preparing a support request. + +## About + +Use the About page to view software version, chip ID, product information, and software update actions if available. + +Open the public [About demo page](https://dvl2.demo.waterlinked.com/#about). + +Software updates are covered in [Software updates](sw-update.md). diff --git a/docs/dvl/dvl-a250_a100-json-protocol.md b/docs/dvl/dvl-a250_a100-json-protocol.md new file mode 100644 index 00000000..c62d6a22 --- /dev/null +++ b/docs/dvl/dvl-a250_a100-json-protocol.md @@ -0,0 +1,319 @@ +# DVL A100/A250 TCP JSON API + +The DVL TCP JSON API sends JSON messages over TCP on port 16171. This page applies to DVL A100 and DVL A250. + +## Terminology + +* DVL - Doppler Velocity Log - Uses hydro-acoustic beams to measure the velocity at which the DVL is moving across a surface (typically an unmoving one such as the sea bottom), and the distance to this surface. +* ACK - Acknowledgement. The command issued was successful. +* NAK - Negative acknowledgement. The command issued failed. +* Ping - A pulse of sound sent by the DVL +* Time of validity - Timestamp of the surface reflection ('center of ping') +* Time of transmission - Timestamp taken directly before sending data over the serial or TCP protocols. The difference between time of transmission and time of validity includes both the time for the acoustic wave to travel from the surface from which it was reflected back to the DVL, and the decoding and processing of this signal internally in the DVL. + +## Version + +This document describes TCP JSON API `json_v3.1` (major.minor): + +- MAJOR version increments represent incompatible API changes +- MINOR version increments represent additional backwards-compatible functionality + +### Version history overview + +| Software release | Ethernet protocol version | Main protocol improvements | +| -- | -- | -- | +| 2.7.1 | json_v4 | Hardware trigger capabilities added. +| 2.6.1 | json_v3.1 | Serial baud rate configurable. Add PD4 format support in serial 'wcp' command. Some serial protocol names [changed](dvl-a250_a100-serial-protocol.md#change-serial-output-protocol-wcp). | +| 2.5.2 | json_v3.1 | Add PD4 format support (experimental) +| 2.4.4 | json_v3.1 | Change gyro calibration to store persistently. Note: gyro calibration commands now take up to 15 seconds. +| 2.4.0 | json_v3.1 | Add ability to trigger pings (TCP JSON API/serial), add configuration for periodic cycling (TCP JSON API/serial) +| 2.2.1 | json_v3 | Add serial output protocol configuration, range mode configuration and calibrate gyro command, Fix missing line ending in configuration (TCP JSON API), fix dark mode enabled naming inconsistency (TCP JSON API), change speed of sound and mounting rotation offset from integer to float +| 2.1.0 | json_v3 | Add configuration, add time_of_validity/time_of_transmission, add covariance (TCP JSON API) +| 2.0.8 | json_v2 | Add position estimation, Add output of orientation angles +| 1.6.0 | - | Initial (velocity only) + + +## TCP JSON API { #json-protocol-tcp } + +### Overview + +The DVL supports sending velocity, transducer, and position updates using the Transmission Control Protocol (TCP). The DVL runs a TCP server on port 16171. + +The format of each packet is JSON. + +In our measurements, TCP JSON message latency was typically around 4 ms average, with 2 ms standard deviation and an observed maximum of 13 ms. This is not a hard real-time guarantee; actual latency can depend on network setup, host system, load, and integration method. See [Integration](integration.md#ethernet-jsontcp). + +### PD formats over TCP + +PD4 and PD6 are also supported over TCP for all DVL models. PD0 is planned for DVL A100 and DVL A250 over TCP and serial, but is not available yet. See [PD formats](dvl-pd-formats.md) for the canonical PD format descriptions. + +### Velocity-and-transducer report + +A velocity-and-transducer report is sent for each velocity calculation of the DVL. The rate depends on the model, altitude, and configuration. See the model page and [Range mode](range-mode.md) for product-specific operating limits. + +The X, Y, and Z axes are with respect to the [body frame](axes.md#body-frame) of the DVL, or the [vehicle frame](axes.md#vehicle-frame) if the DVL is mounted on a vehicle at an angle, specified as a mounting rotation offset, from the forward axis of the vehicle. + +The messages are delimited by newline. + +| Variable | Description | +|----------|-------------| +| time | Milliseconds since last velocity report (ms) | +| vx | Velocity in x direction (m/s) | +| vy | Velocity in y direction (m/s) | +| vz | Velocity in z direction (m/s) | +| fom | Figure of merit, a measure of the accuracy of the velocities (m/s) | +| covariance | Covariance matrix for the velocities. The figure of merit is calculated from this (entries in (m/s)^2) | +| altitude | Distance to the reflecting surface along the Z axis (m) | +| transducers | Is a list containing information from each transducer: [`id`, velocity (m/s), distance (m), rssi (dBm), nsd (dBm), `beam_valid` (True/False)] | +| velocity_valid | If true, the DVL has a lock on the reflecting surface, and the altitude and velocities are valid (True/False) | +| status | 8 bit status mask. Bit 0 is set to 1 for high temperature and DVL will soon enter thermal shutdown. Remaining bits are reserved for future use. | +| time_of_validity | Timestamp of the surface reflection, aka 'center of ping' (Unix timestamp in microseconds) | +| time_of_transmission | Timestamp from immediately before sending of the report over TCP (Unix timestamp in microseconds) | +| format | Format type and version for this report: `json_v3.1` | +| type | Report type: `velocity` | + +!!! note "Transducer numbering and protocol IDs" + Mechanical/transducer diagrams number the transducers from 1 to 4. In protocol messages and diagnostic logs, the transducer `id` uses zero-based numbering from 0 to 3. The `id` is therefore the transducer number minus 1. + +Example of TCP report (indented for legibility) + +``` +{ + "time": 106.3935775756836, + "vx": -3.713480691658333e-05, + "vy": 5.703703573090024e-05, + "vz": 2.4990416932269e-05, + "fom": 0.00016016385052353144, + "covariance": [ + [ + 2.4471841442164077e-08, + -3.3937477272871774e-09, + -1.6659699175747278e-09 + ], + [ + -3.3937477272871774e-09, + 1.4654466085062268e-08, + 4.0409570134514183e-10 + ], + [ + -1.6659699175747278e-09, + 4.0409570134514183e-10, + 1.5971971523143225e-09 + ] + ], + "altitude": 0.4949815273284912, + "transducers": [ + { + "id": 0, + "velocity": 0.00010825289791682735, + "distance": 0.5568000078201294, + "rssi": -30.494251251220703, + "nsd": -88.73271179199219, + "beam_valid": true + }, + { + "id": 1, + "velocity": -1.4719001228513662e-05, + "distance": 0.5663999915122986, + "rssi": -31.095735549926758, + "nsd": -89.5116958618164, + "beam_valid": true + }, + { + "id": 2, + "velocity": 2.7863150535267778e-05, + "distance": 0.537600040435791, + "rssi": -27.180519104003906, + "nsd": -96.98075103759766, + "beam_valid": true + }, + { + "id": 3, + "velocity": 1.9419496311456896e-05, + "distance": 0.5472000241279602, + "rssi": -28.006759643554688, + "nsd": -88.32147216796875, + "beam_valid": true + } + ], + "velocity_valid": true, + "status": 0, + "format": "json_v3.1", + "type": "velocity", + "time_of_validity": 1638191471563017, + "time_of_transmission": 1638191471752336 +} +``` + +### Dead reckoning report + +A dead reckoning report outputs the current speed, position, and orientation of the DVL as calculated by [dead reckoning](dead-reckoning.md), with respect to a [frame](dead-reckoning.md#frame) defined by the axes of the DVL's [body frame](axes.md#body-frame), or [vehicle frame](axes.md#vehicle-frame) if a mounting rotation offset is set, at the start of the dead reckoning run. The expected update rate is 5 Hz. + + + +Variable | Description +------------|------------- +ts | Time stamp of report (Unix timestamp in seconds) +x | Distance in X direction (m) +y | Distance in Y direction (m) +z | Distance in downward direction (m) +std | Standard deviation (figure of merit) for position (m) +roll | Rotation around X axis (degrees) +pitch | Rotation around Y axis (degrees) +yaw | Rotation around Z axis, i.e. heading (degrees) +type | Report type: `position_local` +status | Reports if there are any issues with the DVL (0 if no errors, 1 otherwise) +format | Format type and version for this report: `json_v3` + + +Example of a dead reckoning report. + +``` +{ + "ts": 49056.809, + "x": 12.43563613697886467, + "y": 64.617631152402609587, + "z": 1.767641898933798075, + "std": 0.001959984190762043, + "roll": 0.6173566579818726, + "pitch": 0.6173566579818726, + "yaw": 0.6173566579818726, + "type": "position_local", + "status": 0, + "format": "json_v3.1" +} + +``` + +### Reset dead reckoning + +Dead reckoning can be reset by issuing the `reset_dead_reckoning` command: + +``` +{"command": "reset_dead_reckoning"} +``` + +If the request is successfully received the response will have 'success' set to 'true'. The dead reckoning will have a delay of approximately 50ms until the positioning values being zeroed out. If the response is unsuccessful, the 'success' will be 'false' and a non-empty describing text will be returned in 'error_message'. + +``` +{ + "response_to":"reset_dead_reckoning", + "success": true, + "error_message": "", + "result": null, + "format": "json_v3.1", + "type": "response" +} +``` + +### Calibrate gyro + +Gyro calibration is not needed as a normal setup step for DVL A100/A250. + +The gyro can be calibrated by issuing the `calibrate_gyro` command: + +``` +{"command":"calibrate_gyro"} +``` + +The response will be as follows if the calibration is successful. If unsuccessful, `success` will be `false`, and a non-empty `error_message` will be provided. + +``` +{ + "response_to": "calibrate_gyro", + "success": true, + "error_message": "", + "result": null, + "format": "json_v3.1", + "type": "response" +} +``` + +### Trigger ping + +In setups where multiple acoustic sensors are used it can be useful to control the pinging of each acoustic sensor individually. By setting the configuration `acoustic_enabled = false` the pinging of the DVL can be externally controlled. Up to 15 external trigger commands can be queued by issuing the `trigger_ping` command. The DVL will execute each ping in quick succession until no more commands are in the queue. + +See [Integration](integration.md#triggering-and-synchronization) for guidance on using triggering with other acoustic instruments. + +``` +{"command":"trigger_ping"} +``` + +The response will be as follows if the command is accepted. If the queue is full, `success` will be `false`, and a non-empty `error_message` will be provided. + +``` +{ + "response_to": "trigger_ping", + "success": true, + "error_message": "", + "result": null, + "format": "json_v3.1", + "type": "response" +} +``` + +### Configuration over TCP JSON API { #configuration-over-json } + +#### Configuration parameters + +| Variable | Description | +|----------|-------------| +| speed_of_sound | Speed of sound (1000-2000 m/s). Integer | +| mounting_rotation_offset | See the definition of the [vehicle frame](axes.md#vehicle-frame) of the DVL. Typically 0, but can be set to be non-zero if the forward axis of the DVL is not aligned with the forward axis of a vehicle on which it is mounted (0-360 degrees). Integer | +| acoustic_enabled | `true` for normal operation of the DVL,`false` when the sending of acoustic waves from the DVL is disabled (e.g. to save power or slow down its heating up in air) | +| dark_mode_enabled | `false` when the LED operates as [normal](electrical.md#led-signals), `true` for no blinking of the LED (e.g. if the LED is interfering with a camera) | +| range_mode | `auto` when operating as normal, otherwise see [range mode configuration](range-mode.md) | +| periodic_cycling_enabled | `true` to enable [periodic cycling](configuration.md#periodic-cycling), `false` to disable it | +| hardware_trigger_enabled | `true` to enable [hardware triggering](dvl-triggering.md#hardware-triggering), `false` to disable | + + +#### Fetching current configuration + +The current configuration of the DVL can be obtained by issuing the `get_config` command: + +``` +{"command": "get_config"} +``` + +If the configuration is successfully fetched, the response will be in the following format. If not, `success` will be false, a non-empty `error_message` string will be provided, and `result` will be `null`. + + +``` +{ + "response_to":"get_config", + "success":true, + "error_message":"", + "result":{ + "speed_of_sound":1475.00, + "acoustic_enabled":true, + "dark_mode_enabled":false, + "mounting_rotation_offset":20.00, + "range_mode":"auto", + "periodic_cycling_enabled":true + }, + "format":"json_v3.1", + "type":"response" +} +``` + +#### Setting configuration parameters + +Setting of configuration parameters can be carried out by issuing a `set_config` in the following format, including those parameters which are to be set: + +``` +{"command":"set_config","parameters":{"speed_of_sound":1480}} +``` + +If the parameters are successfully set, the response will be in the following format. If not, `success` will be false, and a non-empty `error_message` string will be provided. + + +``` +{ + "response_to": "set_config", + "success": true, + "error_message": "", + "result" :null, + "format": "json_v3.1", + "type": "response" +} +``` diff --git a/docs/dvl/dvl-a250_a100-serial-protocol.md b/docs/dvl/dvl-a250_a100-serial-protocol.md new file mode 100644 index 00000000..0d476f87 --- /dev/null +++ b/docs/dvl/dvl-a250_a100-serial-protocol.md @@ -0,0 +1,435 @@ +# DVL A100/A250 serial protocol + +Describes the Water Linked DVL serial protocol for DVL A100 and DVL A250. For PD0, PD4, and PD6 output formats, see [PD formats](dvl-pd-formats.md). + +## Terminology + +* DVL - Doppler Velocity Log - Uses hydro-acoustic beams to measure the velocity at which the DVL is moving across a surface (typically an unmoving one such as the sea bottom), and the distance to this surface. +* ACK - Acknowledgement. The command issued was successful. +* NAK - Negative acknowledgement. The command issued failed. +* Ping - A pulse of sound sent by the DVL +* Time of validity - Timestamp of the surface reflection ('center of ping') +* Time of transmission - Timestamp taken directly before sending data over the serial or TCP protocols. The difference between time of transmission and time of validity includes both the time for the acoustic wave to travel from the surface from which it was reflected back to the DVL, and the decoding and processing of this signal internally in the DVL. + +## Version + +This document describes serial protocol version `2.6.x` (major.minor.patch): + +- MAJOR version increments represent incompatible API changes +- MINOR version increments represent additional backwards-compatible functionality +- PATCH version increments represent backwards-compatible bug fixes + +### Version history overview + +| Software release | Serial protocol version | Main protocol improvements | +| -- | -- | -- | +| 2.7.1 | 3.0.0 | Hardware trigger capabilities added. +| 2.6.1 | 2.6.0 | Serial baud rate configurable. Add PD4 format support in serial 'wcp' command. Some serial protocol names [changed](#change-serial-output-protocol-wcp). | +| 2.5.2 | 2.5.0 | Add PD4 format support (experimental) +| 2.4.4 | 2.5.0 | Change gyro calibration to store persistently. Note: gyro calibration commands now take up to 15 seconds. +| 2.4.0 | 2.5.0 | Add ability to trigger pings (TCP JSON API/serial), add configuration for periodic cycling (TCP JSON API/serial) +| 2.2.1 | 2.4.0 | Add serial output protocol configuration, range mode configuration and calibrate gyro command, Fix missing line ending in configuration (TCP JSON API), fix dark mode enabled naming inconsistency (TCP JSON API), change speed of sound and mounting rotation offset from integer to float +| 2.1.0 | 2.3.0 | Add configuration, add time_of_validity/time_of_transmission, add covariance (TCP JSON API) +| 2.0.8 | 2.2.0 | Add position estimation, Add output of orientation angles +| 1.6.0 | 2.1.0 | Initial (velocity only) + + +## Serial protocol + +### Overview + +The default serial communication format is 115200 8-N-1 (no hardware flow control). Release 2.6.1 and later allow different baud rates through web GUI configuration. + +DVL A100 and DVL A250 use RS232. See [DVL A100/A250 serial interface](electrical.md#dvl-a100-and-dvl-a250-serial-interface). + +Packets sent to and received from the DVL start with a `w` and end with LF, CR+LF, or CR. The packet format is: + +| Start byte | Direction | Command | Options (0 to many) | Checksum | End byte | +|------------|------------------|----------|----------------------|----------|----------------| +| `w` | `c` or `r` | `x` | `,[option]` | `*xx` | `\n`, `\r\n`, or `\r` | + +`Direction` is `c` (short for 'command') for packets sent to the DVL, and `r` (short for 'response') for packets sent from the DVL. +The commands can be sent from a terminal program that supports sending a full line at a time. The timeout between characters is approximately 10 ms. + +!!!note + Please verify the baud rate configuration in the web GUI if you are unable to communicate with the default baud rate. + + +!!!note + The checksum is optional when sending commands to the DVL. The DVL always returns a checksum. The checksum algorithm + is CRC-8 and it is formatted as a hexadecimal number using 2 lower-case characters (ex: `*c3`). See [below](#checksum) for details. + +### Command overview + +The commands in the table are shown without the checksum and without the mandatory line ending (any of `\n`, `\r\n`, or `\r`) for readability. In all cases, the response to a submitted command may be `wrn`, `wr?`, or `wr!` (see below for details), but only the format of a successful response is listed. + +| Command | Description | Response | Description | +|---------|-------------|----------|-------------| +| `wcv` | Get protocol version | `wrv,`*[major],[minor],[patch]* | Protocol version. eg: `wrv,2.5.0` | +| `wcw` | Get product detail | `wrw,`*[name]*,*[version]*,*[chipID]*,*[IP address]* | Where type is dvl, name is product name, version is software version, chip ID is the chip ID and _optionally_ the IP address if connected to DHCP server: eg: `wrw,dvl-a50,2.2.1,0xfedcba98765432` or `wrw,dvl-a50,2.2.1,0xfedcba98765432,10.11.12.140` | +| `wcs,`*[configuration parameters]* | Set configuration parameters | `wra` | Successfully set the specified configuration parameters. See [Configuration](#configuration-over-serial) for details | +| `wcc` | Get current configuration | `wrc,`*[configuration parameters]* | Entire current configuration. See [Configuration](#configuration-over-serial) for details | +| `wcr` | Reset dead reckoning | `wra` | Successfully started a new [dead reckoning](dead-reckoning.md#starting-dead-reckoning) run | +| `wcx` | Trigger ping | `wra` | Successfully queued a ping | +| `wcg` | Calibrate gyro | `wra` | Successfully calibrated gyro | +| `wcp` | Change serial output protocol | `wra` | Successfully changed output protocol | +| | | `wrz,`*[details below]* | Velocities calculated | +| | | `wru,`*[details below]* | Transducer information | +| | | `wrp,`*[details below]* | [Dead reckoning](dead-reckoning.md) report | +| | | `wrx,`*[details below]* | DEPRECATED: Velocities calculated (old format) | +| | | `wrt,`*[details below]* | DEPRECATED: Transducer information (old format) | +| | | `wr?` | Malformed request: packet cannot be understood or no newline received before timeout | +| | | `wr!` | Malformed request: packet does not match the given checksum | +| | | `wrn` | Not acknowledged (nack): an error occurred when handling the packet | + + + +### Velocity report (wrz) + +A velocity report is output for each velocity calculation of the DVL. The rate depends on the model, altitude, and configuration. See the model page and [Range mode](range-mode.md) for product-specific operating limits. + +The X, Y, and Z axes are with respect to the [body frame](axes.md#body-frame) of the DVL, or the [vehicle frame](axes.md#vehicle-frame) if the DVL is mounted on a vehicle at an angle, specified as a mounting rotation offset, from the forward axis of the vehicle. + +The report has the following format: +`wrz,`*[vx],[vy],[vz],[valid],[altitude],[fom],[covariance],[time_of_validity],[time_of_transmission],[time],[status]* + + +| Variable | Description | +|----------|-------------| +| vx | Velocity in x direction (m/s) | +| vy | Velocity in y direction (m/s) | +| vz | Velocity in z direction (m/s) | +| valid | If `y`, the DVL has a lock on the reflecting surface, and the altitude and velocities are valid (y/n) | +| altitude | Measured altitude to the bottom (m) | +| fom | Figure of merit, a measure of the accuracy of the velocities (m/s) | +| covariance | Covariance matrix for the velocities. The figure of merit is calculated from this. 9 entries ((m/s)^2) separated by ; | +| time_of_validity | Timestamp of the surface reflection, aka 'center of ping' (Unix timestamp in microseconds) | +| time_of_transmission | Timestamp from immediately before sending of the report over TCP (Unix timestamp in microseconds) | +| time | Milliseconds since last velocity report (ms) | +| status | 8 bit status mask. Bit 0 is set to 1 for high temperature and DVL will soon enter thermal shutdown. Remaining bits are reserved for future use. | + +Example where all velocities are valid: + +``` +wrz,0.120,-0.400,2.000,y,1.30,1.855,1e-07;0;1.4;0;1.2;0;0.2;0;1e+09,7,14,123.00,1*50 +``` + +### Transducer report (wru) + +A transducer report is output for each of the four transducers of the DVL for each velocity calculation of the DVL. The rate will be the same as that of the velocity report. If the transducer did not receive a signal that could be successfully decoded, `distance` will be set to -1, and `velocity` will be set to 0. RSSI and NSD will be output in all cases. + +The report has the following format: +`wru,`*[id],[velocity],[distance],[rssi],[nsd]* + + +| Variable | Description | +|----------|-------------| +| id | Zero-based transducer `id`, from 0 to 3 | +| velocity | Velocity in the direction of the transducer (m/s) | +| distance | Distance (parallel to the transducer beam, i.e. not the vertical distance) to the reflecting surface from this transducer (m) | +| rssi | Received signal strength indicator: strength of the signal received by this transducer (dBm) | +| nsd | Noise spectral density: strength of the background noise received by this transducer (dBm) | + +!!! note "Transducer numbering and protocol IDs" + Mechanical/transducer diagrams number the transducers from 1 to 4. In protocol messages and diagnostic logs, the transducer `id` uses zero-based numbering from 0 to 3. The `id` is therefore the transducer number minus 1. + +Example where all data is valid: + +``` +wru,0,0.070,1.10,-40,-95*9c +wru,1,-0.500,1.25,-62,-104*f0 +wru,2,2.200,1.40,-56,-98*18 +wru,3,1.800,1.35,-58,-96*a3 +``` + + +### Dead reckoning report (wrp) + +A dead reckoning report outputs the current speed, position, and orientation of the DVL as calculated by [dead reckoning](dead-reckoning.md), with respect to a [frame](dead-reckoning.md#frame) defined by the axes of the DVL's [body frame](axes.md#body-frame), or [vehicle frame](axes.md#vehicle-frame) if a mounting rotation offset is set, at the start of the dead reckoning run. The expected update rate is 5 Hz. + +The format is: +`wrp,`*[time_stamp],[x],[y],[z],[pos_std],[roll],[pitch],[yaw],[status]* + +Variable | Description +------------|------------- +time_stamp | Time stamp of report (Unix timestamp in seconds) +x | Distance in X direction (m) +y | Distance in Y direction (m) +z | Distance in downward direction (m) +pos_std | Standard deviation (Figure of merit) for position (m) +roll | Rotation around X axis (degrees) +pitch | Rotation around Y axis (degrees) +yaw | Rotation around Z axis, i.e. heading (degrees) +status | Reports if there are any issues with the DVL (0 if no errors, 1 otherwise) | + +Example: + +``` +wrp,49056.809,0.41,0.15,1.23,0.4,53.9,13.0,19.3,0*de +wrp,49057.269,0.39,0.18,1.23,0.4,53.9,13.0,19.3,0*e2 +``` + + +### Reset dead reckoning (wcr) + +Dead reckoning can be reset by issuing the `wcr` command. The reply will be an ack (`wra`) if the reset is successful, and a nak (`wrn`) if not. + +### Calibrate gyro (wcg) + +Gyro calibration is not needed as a normal setup step for DVL A100/A250. + +The gyro can be calibrated by issuing the `wcg` command. The reply will be an ack (`wra`) if the reset is successful, and a nak (`wrn`) if not. + +### Trigger ping (wcx) + +In setups where multiple acoustic sensors are used it can be useful to control the pinging of each acoustic sensor individually. By setting the configuration `acoustic_enabled = n` the pinging of the DVL can be externally controlled. Up to 15 external trigger commands can be queued by issuing the `wcx` command. The DVL will execute each ping in quick succession until no more commands are in the queue. + +See [Integration](integration.md#triggering-and-synchronization) for guidance on using triggering with other acoustic instruments. + +For DVL A100 and DVL A250 hardware triggering, sending a NULL character over the RS232 RX line triggers a pulse on the falling edge. + + + +The reply will be an ack (`wra`) if the command is successful, and a nak (`wrn`) if queue is full. + +### Change serial output protocol (wcp) + +The serial output protocol in use can be configured by issuing the `wcp` command. The selected protocol is persistent over reboots. + +``` +wcp,[protocol number] +``` + +The supported protocols are: + +| Protocol number | Name | Description | +| --------------- | ---- | ----------- | +| 0 | Output disabled | No output on serial. Recommended if serial port is not used to lower latency on Ethernet protocols. | +| 1 | WL - Serial V1 and V2 | All output including the deprecated `wrx` and `wrt` sentences. | +| 2 | PD6 | PD6 format output. See [PD6 format description](dvl-pd-formats.md#pd6-protocol-tcpserial) | +| 3 | WL - Serial V2 | All output excluding the deprecated `wrx` and `wrt` sentences. | +| 4 | Not used | Not used | +| 5 | Not used | Not used | +| 6 | PD4 | PD4 format output. See [PD4 format description](dvl-pd-formats.md#pd4-protocol-tcpserial) | + +The reply will be an ack (`wra`) if the protocol change is successful, and a nak (`wrn`) if not. + +Example setting configuring output to use protocol number 3: + +``` +wcp,3 +``` + +!!!note + Prior to release 2.6.1 protocol number 1 was named `Backward compatible` and protocol number 3 was named `Latest`. There is no change in functionality. + +### Configuration over serial + +#### Configuration parameters + +| Variable | Description | +|----------|-------------| +| speed_of_sound | Speed of sound (1000-2000 m/s). Float | +| mounting_rotation_offset | See the definition of the [vehicle frame](axes.md#vehicle-frame) of the DVL. Typically 0, but can be set to be non-zero if the forward axis of the DVL is not aligned with the forward axis of a vehicle on which it is mounted (0-360 degrees). Float | +| acoustic_enabled | `y` for normal operation of the DVL,`n` when the sending of acoustic waves from the DVL is disabled (e.g. to save power or slow down its heating up in air) | +| dark_mode_enabled | `n` when the LED operates as [normal](electrical.md#led-signals). `y` for no blinking of LED (e.g. if the LED is interfering with a camera) | +| range_mode |`auto` when operating as normal, otherwise see [range mode configuration](range-mode.md) | +| periodic_cycling_enabled | `y` to enable [periodic cycling](configuration.md#periodic-cycling), `n` to disable it. See [Configuration over TCP JSON API](dvl-a250_a100-json-protocol.md#configuration-over-json) for details | +| hardware_trigger_enabled | `true` to enable [hardware triggering](dvl-triggering.md#hardware-triggering), `false` to disable | + +!!!note + For backward compatibility the `range_mode` and `periodic_cycling_enabled` parameters are optional when setting the configuration. They will always be returned when reading the configuration (`wcc`). + Speed of sound and mounting rotation was changed from integer to float in serial protocol 2.4.0 + +#### Fetching current configuration + +The current configuration of the DVL can be obtained by issuing the `wcc` command. + + +If the configuration is successfully fetched, the response will be in the following format. If not, a nak `wrn` will be returned. + +``` +wrc,[speed_of_sound],[mounting_rotation_offset],[acoustic_enabled],[dark_mode_enabled],[range_mode],[periodic_cycling_enabled],[hardware_trigger_enabled] +``` + +#### Setting configuration parameters + +Setting of configuration parameters can be carried out by issuing the `wcs` command in the following format. + + +``` +wcs,[speed_of_sound],[mounting_rotation_offset],[acoustic_enabled],[dark_mode_enabled],[range_mode],[periodic_cycling_enabled],[hardware_trigger_enabled] +``` + +Those parameters which are not to be set can be left blank. + +Example for setting dark mode without changing the other parameters: + +``` +wcs,,,,y,,, +``` + +Example for setting speed of sound to 1450 m/s and disabling acoustics, without changing the other parameters: + +``` +wcs,1450,,n,,,, +``` + +The response will be an ack `wra` if the parameters are successfully set, a nak `wrn` if the command was successfully parsed but the parameters were not successfully set, and a malformed request `wr?` if the command was not successfully parsed, e.g. if the wrong number of parameters was used, or either `speed_of_sound` or `mounting_rotation_offset` was not an integer. + +The new configuration will not be returned in the response, but can be obtained by issuing a `wcc` command as above. + + +### Velocity report, old format (wrx) [Deprecated] + +Same purpose as the [velocity report](#velocity-report-wrz), but in an older format: + +`wrx,`*[time],[vx],[vy],[vz],[fom],[altitude],[valid],[status]* + +| Variable | Description | +|----------|-------------| +| time | Milliseconds since last velocity report (ms) | +| vx | Velocity in x direction (m/s) | +| vy | Velocity in y direction (m/s) | +| vz | Velocity in z direction (m/s) | +| fom | Figure of merit, a measure of the accuracy of the velocities (m/s) | +| altitude | Distance to the reflecting surface along Z axis (m) | +| valid | If `y`, the DVL has lock on the reflecting surface, and the altitude and velocities are valid (y/n) | +| status | 8 bit status mask. Bit 0 is set to 1 for high temperature and DVL will soon enter thermal shutdown. Remaining bits are reserved for future use. | + +Example where velocities are valid: + +``` +wrx,112.83,0.007,0.017,0.006,0.000,0.93,y,0*d2 +wrx,140.43,0.008,0.021,0.012,0.000,0.92,y,0*b7 +wrx,118.47,0.009,0.020,0.013,0.000,0.92,y,0*54 +``` + +Example where velocities and altitude are not valid and a high temperature warning occurs: + +``` +wrx,1075.51,0.000,0.000,0.000,2.707,-1.00,n,1*04 +wrx,1249.29,0.000,0.000,0.000,2.707,-1.00,n,1*6a +wrx,1164.94,0.000,0.000,0.000,2.707,-1.00,n,1*39 +``` + +### Transducer report, old format (wrt) [Deprecated] + +Same purpose as the [transducer report](#transducer-report-wru), but in an older format, and combining the data of all four transducers: + +`wrt,`*[dist_1],[dist_2],[dist_3],[dist_4]* + +| Variable | Description | +|----------|-------------| +| dist_1 | Distance (parallel to the transducer beam, i.e. not the vertical distance) to reflecting surface from transducer 1 (m) | +| dist_2 | Distance to reflecting surface from transducer 2 (m) | +| dist_3 | Distance to reflecting surface from transducer 3 (m) | +| dist_4 | Distance to reflecting surface from transducer 4 (m) | + +Example where all distances are valid: + +``` +wrt,15.00,15.20,14.90,14.20*b1 +wrt,14.90,15.10,14.80,14.10*ac +``` + +Example where distance is not valid for transducer 4: + +``` +wrt,14.90,15.10,14.80,-1.00*53 +wrt,15.00,15.20,14.90,-1.00*71 +``` + + +### Checksum + +The checksum algorithm is CRC-8 (Polynomal: 0x07, Init: 0x00, RefIn/RefOut: false, XorOut: 0x00, Check: 0xf4). +Checksum is formatted as a hexadecimal number using 2 lower-case characters (ex: `*c3`). + +Compatible implementations: + +* Python 3: [crcmod](https://pypi.org/project/crcmod/) `crcmod.predefined.mkPredefinedCrcFun("crc-8")` +* Golang: [github.com/sigurn/crc8](https://github.com/sigurn/crc8) `crc8.MakeTable(crc8.CRC8)` + +Example for how to verify checksum using Python 3 and [crcmod](https://pypi.org/project/crcmod/): + +``` +crc = crcmod.predefined.mkPredefinedCrcFun("crc-8") +sentence = b"wrx,1164.94,0.000,0.000,0.000,2.707,-1.00,n,1*39" +data, checksum = sentence.split(b"*") + +if crc(data) == int(checksum, 16): + print("CRC valid") +else: + print("CRC invalid") +``` + +The [crcmod](https://pypi.org/project/crcmod/) python package can generate code in other languages. Here is an example (subject to the [MIT License](https://opensource.org/licenses/MIT)) for C which should be straightforward to adapt to other languages. + +``` +static const uint8_t lookup_table[256] = { + 0x00U,0x07U,0x0EU,0x09U,0x1CU,0x1BU,0x12U,0x15U, + 0x38U,0x3FU,0x36U,0x31U,0x24U,0x23U,0x2AU,0x2DU, + 0x70U,0x77U,0x7EU,0x79U,0x6CU,0x6BU,0x62U,0x65U, + 0x48U,0x4FU,0x46U,0x41U,0x54U,0x53U,0x5AU,0x5DU, + 0xE0U,0xE7U,0xEEU,0xE9U,0xFCU,0xFBU,0xF2U,0xF5U, + 0xD8U,0xDFU,0xD6U,0xD1U,0xC4U,0xC3U,0xCAU,0xCDU, + 0x90U,0x97U,0x9EU,0x99U,0x8CU,0x8BU,0x82U,0x85U, + 0xA8U,0xAFU,0xA6U,0xA1U,0xB4U,0xB3U,0xBAU,0xBDU, + 0xC7U,0xC0U,0xC9U,0xCEU,0xDBU,0xDCU,0xD5U,0xD2U, + 0xFFU,0xF8U,0xF1U,0xF6U,0xE3U,0xE4U,0xEDU,0xEAU, + 0xB7U,0xB0U,0xB9U,0xBEU,0xABU,0xACU,0xA5U,0xA2U, + 0x8FU,0x88U,0x81U,0x86U,0x93U,0x94U,0x9DU,0x9AU, + 0x27U,0x20U,0x29U,0x2EU,0x3BU,0x3CU,0x35U,0x32U, + 0x1FU,0x18U,0x11U,0x16U,0x03U,0x04U,0x0DU,0x0AU, + 0x57U,0x50U,0x59U,0x5EU,0x4BU,0x4CU,0x45U,0x42U, + 0x6FU,0x68U,0x61U,0x66U,0x73U,0x74U,0x7DU,0x7AU, + 0x89U,0x8EU,0x87U,0x80U,0x95U,0x92U,0x9BU,0x9CU, + 0xB1U,0xB6U,0xBFU,0xB8U,0xADU,0xAAU,0xA3U,0xA4U, + 0xF9U,0xFEU,0xF7U,0xF0U,0xE5U,0xE2U,0xEBU,0xECU, + 0xC1U,0xC6U,0xCFU,0xC8U,0xDDU,0xDAU,0xD3U,0xD4U, + 0x69U,0x6EU,0x67U,0x60U,0x75U,0x72U,0x7BU,0x7CU, + 0x51U,0x56U,0x5FU,0x58U,0x4DU,0x4AU,0x43U,0x44U, + 0x19U,0x1EU,0x17U,0x10U,0x05U,0x02U,0x0BU,0x0CU, + 0x21U,0x26U,0x2FU,0x28U,0x3DU,0x3AU,0x33U,0x34U, + 0x4EU,0x49U,0x40U,0x47U,0x52U,0x55U,0x5CU,0x5BU, + 0x76U,0x71U,0x78U,0x7FU,0x6AU,0x6DU,0x64U,0x63U, + 0x3EU,0x39U,0x30U,0x37U,0x22U,0x25U,0x2CU,0x2BU, + 0x06U,0x01U,0x08U,0x0FU,0x1AU,0x1DU,0x14U,0x13U, + 0xAEU,0xA9U,0xA0U,0xA7U,0xB2U,0xB5U,0xBCU,0xBBU, + 0x96U,0x91U,0x98U,0x9FU,0x8AU,0x8DU,0x84U,0x83U, + 0xDEU,0xD9U,0xD0U,0xD7U,0xC2U,0xC5U,0xCCU,0xCBU, + 0xE6U,0xE1U,0xE8U,0xEFU,0xFAU,0xFDU,0xF4U,0xF3U, +}; + +uint8_t crc8(uint8_t *message, int message_length) { + uint8_t checksum = 0; + while (message_length > 0) { + checksum = lookup_table[*message ^ checksum]; + message++; + message_length--; + } + return checksum; +} +``` + +## PD0 format { #pd0-protocol } + +PD0 is planned for DVL A100 and DVL A250. It is not available yet. + +When ready, PD0 is planned for both TCP and serial output. + +See [PD formats](dvl-pd-formats.md#pd0-protocol). + +## PD6 format (TCP/Serial) { #pd6-protocol-tcpserial } + +PD6 is supported over serial and TCP for all DVL models. + +See the canonical [PD6 format description](dvl-pd-formats.md#pd6-protocol-tcpserial). + + +## PD4 format (TCP/Serial) { #pd4-protocol-tcpserial } + +PD4 is supported over serial and TCP for all DVL models. + +See the canonical [PD4 format description](dvl-pd-formats.md#pd4-protocol-tcpserial). diff --git a/docs/dvl/dvl-a50.md b/docs/dvl/dvl-a50.md index 6ba22625..8d3d7051 100644 --- a/docs/dvl/dvl-a50.md +++ b/docs/dvl/dvl-a50.md @@ -1,33 +1,16 @@ -# DVL-A50 - -[Buy DVL-A50 here!](https://waterlinked.com/product/dvl-a50/) - -![dvl_a50](../img/WL-21035-3_DVL-A50_Side4_1600_crop.jpg) - -## Description -The [DVL-A50](https://www.waterlinked.com/dvl/dvl-a50) is – by far – the world’s smallest commercially available Doppler Velocity Log. - -The A50 is establishing a new market standard with its high performance, ultra-small 4 beam setup, open interface protocol and low cost. - -The DVL estimates velocity relative to the sea bottom by sending acoustic waves from the four angled transducers and then measure the frequency shift (doppler effect) from the received echo. By combining the measurements of all four transducers and the time between each acoustic pulse, it is possible to very accurately estimate the speed and direction of movement. - -!!! Note - The DVL-A50 uses a constant speed of sound equal to 1500 m/s (Release 1.3.1). This is configurable for the Performance edition. - -!!! Tip - Keep the DVL-A50 in a bucket of water to ensure sufficient cooling when using the DVL on a workbench. +# DVL A50 ## Dimensions ![dvl_a50_dimensions](../img/WL-21035-3_DVL-A50_Side3_1600_dimension_crop.jpg) ### Cable dimensions -Delivered cable length: 3.0m +Delivered cable length: 3.0 m -Cable diameter: 6.8mm +/- 0.2mm +Cable diameter: 6.8 mm +/- 0.2 mm -## Mounting Holes +## Mounting holes ![dvl_a50_mounting_holes_drawing](../img/dvl_mounting_holes_drawing.png) @@ -36,6 +19,7 @@ Cable diameter: 6.8mm +/- 0.2mm ![dvl_a50_transducer_numbering](../img/WL-21035-3_DVL-A50_Front_1600_transducers_crop.jpg) +Mechanical drawings number the transducers from 1 to 4. Protocol messages and diagnostic logs use zero-based transducer `id` values from 0 to 3. See [Transducer numbering and protocol IDs](axes.md#transducer-numbering-and-protocol-ids). ## Transducer beam width diff --git a/docs/dvl/dvl-a50_a125-gui.md b/docs/dvl/dvl-a50_a125-gui.md new file mode 100644 index 00000000..6d638b92 --- /dev/null +++ b/docs/dvl/dvl-a50_a125-gui.md @@ -0,0 +1,99 @@ +# DVL A50/A125 web GUI + +This page applies to DVL A50 and DVL A125. + +The DVL A50/A125 web GUI can be used to check live status, configure settings, select outputs, collect diagnostic logs, and view software and device information. + +## Open the web GUI + +1. Connect power and Ethernet to the DVL. +2. Make sure the DVL is submerged before normal operation. +3. Open a web browser and go to the DVL address. +4. See [Network Setup](networking.md) if the web GUI does not open. + +## Demo GUI + +Use the public [DVL A50/A125 demo GUI](https://dvl.demo.waterlinked.com/#/) to explore the interface without connecting to a DVL. + +The demo runs on simulated data. It does not replace testing with your own DVL in water. Hardware status, bottom lock, acoustic conditions, and output integrations must still be verified on the real installation. + +## Dashboard { #dashboard-live-data } + +Use the dashboard to view the current DVL status, velocity data, bottom lock state, altitude, dead-reckoning information, and other live information. + +Open the public [dashboard demo page](https://dvl.demo.waterlinked.com/#/). + +### Verify bottom lock + +1. Confirm that the DVL is submerged and the transducers have a clear line of sight to the bottom. +2. Open the dashboard. +3. Check that acoustics are enabled. +4. Check that velocity is valid. +5. Check that altitude is stable and reasonable for the test environment. +6. Check the figure of merit (FOM) or uncertainty indicator if shown. + +!!! note + Figure of merit is a confidence indicator for the velocity estimate. A high value means the velocity measurement is less certain. + +If velocity is invalid or bottom lock is unreliable, see [How to diagnose](how-to-diagnose.md). + +### View velocity and navigation + +1. Open the dashboard. +2. Check that velocity is valid before using the values. +3. Review speed, altitude, ping rate, and FOM. +4. Use the horizontal and vertical velocity views to confirm the movement direction. +5. Use the map view only after checking the dead reckoning limitations. + +See [Dead reckoning](dead-reckoning.md) for the reference frame and limitations. + +!!! warning + Dead reckoning will drift over time. Do not use the map view as an absolute position reference unless your system also provides an external position reference. + +## Outputs + +Use the outputs page to configure which data outputs are enabled and how data is sent from the DVL. + +Open the public [outputs demo page](https://dvl.demo.waterlinked.com/#/outputs). + +1. Open the outputs page. +2. Select the output protocol required by your integration. +3. Configure serial settings if you use the UART interface. +4. Save the configuration. +5. Reconnect or restart the receiving system if required by the integration. + +See [Settings and configuration](configuration.md#output-settings), [Integration](integration.md), [DVL A50/A125 TCP JSON API](dvl-json-protocol.md), and [DVL A50/A125 serial protocol](dvl-serial-protocol.md). + +## Configuration + +Use the configuration page to change DVL settings such as speed of sound, range mode, mounting rotation, water tracking, network settings, and maintenance actions. + +Open the public [configuration demo page](https://dvl.demo.waterlinked.com/#/config). + +See [Settings and configuration](configuration.md), [Axes](axes.md), [Range mode](range-mode.md), and [Water tracking](water-tracking.md). + +## Diagnostics + +Use the diagnostics page to view live diagnostic information while the DVL is operating. This can help you see whether status, signal quality, transducer distances, or validity changes when the vehicle moves, thrusters run, or the environment changes. + +Open the public [diagnostics demo page](https://dvl.demo.waterlinked.com/#/diagnostic). + +See [How to diagnose](how-to-diagnose.md) for symptom-based checks. + +## Diagnostic log + +The DVL A50/A125 web GUI has a separate diagnostic log page. + +Use the diagnostic log page to collect a diagnostic log when troubleshooting or when requested by Water Linked support. + +Open the public [diagnostic log demo page](https://dvl.demo.waterlinked.com/#/collect). + +See [Diagnostic log](diagnostic-log.md) for collection guidance and the [support package checklist](support-package-checklist.md) before contacting Water Linked support. + +## About + +Use the About page to view software version, chip ID, product information, release notes, and software update actions if available. + +Open the public [About demo page](https://dvl.demo.waterlinked.com/#/about). + +Software updates are covered in [Software updates](sw-update.md). diff --git a/docs/dvl/dvl-json-protocol.md b/docs/dvl/dvl-json-protocol.md new file mode 100644 index 00000000..6082f433 --- /dev/null +++ b/docs/dvl/dvl-json-protocol.md @@ -0,0 +1,333 @@ +# DVL A50/A125 TCP JSON API + +The DVL TCP JSON API sends JSON messages over TCP on port 16171. This page applies to DVL A50 and DVL A125. + +## Terminology + +* DVL - Doppler Velocity Log - Uses hydro-acoustic beams to measure the velocity at which the DVL is moving across a surface (typically an unmoving one such as the sea bottom), and the distance to this surface. +* ACK - Acknowledgement. The command issued was successful. +* NAK - Negative acknowledgement. The command issued failed. +* Ping - A pulse of sound sent by the DVL +* Time of validity - Timestamp of the surface reflection ('center of ping') +* Time of transmission - Timestamp taken directly before sending data over the serial or TCP protocols. The difference between time of transmission and time of validity includes both the time for the acoustic wave to travel from the surface from which it was reflected back to the DVL, and the decoding and processing of this signal internally in the DVL. + +## Version + +This document describes TCP JSON API versions `json_v3.1` and `json_v3.2` (major.minor): + +- MAJOR version increments represent incompatible API changes +- MINOR version increments represent additional backwards-compatible functionality + +### Version history overview + +| Software release | Ethernet protocol version | Main protocol improvements | +| -- | -- | -- | +| 2.7.1 | json_v3.2 | Add water tracking mode and tracking mode field in velocity reports | +| 2.6.1 | json_v3.1 | Serial baud rate configurable. Add PD4 format support in serial 'wcp' command. Some serial protocol names [changed](dvl-serial-protocol.md#change-serial-output-protocol-wcp). | +| 2.5.2 | json_v3.1 | Add PD4 format support (experimental) +| 2.4.4 | json_v3.1 | Change gyro calibration to store persistently. Note: gyro calibration commands now take up to 15 seconds. +| 2.4.0 | json_v3.1 | Add ability to trigger pings (TCP JSON API/serial), add configuration for periodic cycling (TCP JSON API/serial) +| 2.2.1 | json_v3 | Add serial output protocol configuration, range mode configuration and calibrate gyro command, Fix missing line ending in configuration (TCP JSON API), fix dark mode enabled naming inconsistency (TCP JSON API), change speed of sound and mounting rotation offset from integer to float +| 2.1.0 | json_v3 | Add configuration, add time_of_validity/time_of_transmission, add covariance (TCP JSON API) +| 2.0.8 | json_v2 | Add position estimation, Add output of orientation angles +| 1.6.0 | - | Initial (velocity only) + + +## TCP JSON API { #json-protocol-tcp } + +### Overview + +The DVL supports sending velocity, transducer, and position updates using the Transmission Control Protocol (TCP). The DVL runs a TCP server on port 16171. + +The format of each packet is JSON. + +In our measurements, TCP JSON message latency was typically around 4 ms average, with 2 ms standard deviation and an observed maximum of 13 ms. This is not a hard real-time guarantee; actual latency can depend on network setup, host system, load, and integration method. See [Integration](integration.md#ethernet-jsontcp). + +### PD formats over TCP + +PD4 and PD6 are also supported over TCP for all DVL models. See [PD formats](dvl-pd-formats.md) for the canonical PD format descriptions. + +### Velocity-and-transducer report + +A velocity-and-transducer report is sent for each velocity calculation of the DVL. The rate depends on the altitude of the DVL (distance to the sea bottom or other reflecting surface), but will be in the range 2-15 Hz. + +The X, Y, and Z axes are with respect to [body frame](axes.md#body-frame) of the DVL, or the [vehicle frame](axes.md#vehicle-frame) if the DVL is mounted on a vehicle at an angle, specified as a 'mounting rotation offset', from the forward axis of the vehicle. + +The messages are delimited by newline. + +| Variable | Description | +|----------|-------------| +| time | Milliseconds since last velocity report (ms) | +| vx | Velocity in x direction (m/s) | +| vy | Velocity in y direction (m/s) | +| vz | Velocity in z direction (m/s) | +| fom | Figure of merit, a measure of the accuracy of the velocities (m/s) | +| covariance | Covariance matrix for the velocities. The figure of merit is calculated from this (entries in (m/s)^2) | +| altitude | Distance to the reflecting surface along the Z axis (m) | +| transducers | Is a list containing information from each transducer: [`id`, velocity (m/s), distance (m), rssi (dBm), nsd (dBm), `beam_valid` (True/False)] | +| velocity_valid | If true, the DVL has a lock on the reflecting surface, and the altitude and velocities are valid (True/False) | +| status | 8 bit status mask. Bit 0 is set to 1 for high temperature and DVL will soon enter thermal shutdown. Remaining bits are reserved for future use. | +| time_of_validity | Timestamp of the surface reflection, aka 'center of ping' (Unix timestamp in microseconds) | +| time_of_transmission | Timestamp from immediately before sending of the report over TCP (Unix timestamp in microseconds) | +| tracking_mode | Active tracking mode. `bottom` for bottom tracking, `water` for [water tracking](water-tracking.md). Added in `json_v3.2` | +| format | Format type and version for this report: `json_v3.1` | +| type | Report type: `velocity` or `velocity_water` | + +!!! note "Transducer numbering and protocol IDs" + Mechanical/transducer diagrams number the transducers from 1 to 4. In protocol messages and diagnostic logs, the transducer `id` uses zero-based numbering from 0 to 3. The `id` is therefore the transducer number minus 1. + +Example of TCP report (indented for legibility) + +``` +{ + "time": 106.3935775756836, + "vx": -3.713480691658333e-05, + "vy": 5.703703573090024e-05, + "vz": 2.4990416932269e-05, + "fom": 0.00016016385052353144, + "covariance": [ + [ + 2.4471841442164077e-08, + -3.3937477272871774e-09, + -1.6659699175747278e-09 + ], + [ + -3.3937477272871774e-09, + 1.4654466085062268e-08, + 4.0409570134514183e-10 + ], + [ + -1.6659699175747278e-09, + 4.0409570134514183e-10, + 1.5971971523143225e-09 + ] + ], + "altitude": 0.4949815273284912, + "transducers": [ + { + "id": 0, + "velocity": 0.00010825289791682735, + "distance": 0.5568000078201294, + "rssi": -30.494251251220703, + "nsd": -88.73271179199219, + "beam_valid": true + }, + { + "id": 1, + "velocity": -1.4719001228513662e-05, + "distance": 0.5663999915122986, + "rssi": -31.095735549926758, + "nsd": -89.5116958618164, + "beam_valid": true + }, + { + "id": 2, + "velocity": 2.7863150535267778e-05, + "distance": 0.537600040435791, + "rssi": -27.180519104003906, + "nsd": -96.98075103759766, + "beam_valid": true + }, + { + "id": 3, + "velocity": 1.9419496311456896e-05, + "distance": 0.5472000241279602, + "rssi": -28.006759643554688, + "nsd": -88.32147216796875, + "beam_valid": true + } + ], + "velocity_valid": true, + "status": 0, + "tracking_mode": "bottom", + "format": "json_v3.2", + "type": "velocity", + "time_of_validity": 1638191471563017, + "time_of_transmission": 1638191471752336 +} +``` + +### Dead reckoning report + +A dead reckoning report outputs the current speed, position, and orientation of the DVL as calculated by [dead reckoning](dead-reckoning.md), with respect to a [frame](dead-reckoning.md#frame) defined by the axes of the DVL's [body frame](axes.md#body-frame), or [vehicle frame](axes.md#vehicle-frame) if a mounting rotation offset is set, at the start of the dead reckoning run. The expected update rate is 5 Hz. + + + +Variable | Description +------------|------------- +ts | Time stamp of report (Unix timestamp in seconds) +x | Distance in X direction (m) +y | Distance in Y direction (m) +z | Distance in downward direction (m) +std | Standard deviation (figure of merit) for position (m) +roll | Rotation around X axis (degrees) +pitch | Rotation around Y axis (degrees) +yaw | Rotation around Z axis, i.e. heading (degrees) +type | Report type: `position_local` +status | Reports if there are any issues with the DVL (0 if no errors, 1 otherwise) +format | Format type and version for this report: `json_v3` + + +Example of a dead reckoning report. + +``` +{ + "ts": 49056.809, + "x": 12.43563613697886467, + "y": 64.617631152402609587, + "z": 1.767641898933798075, + "std": 0.001959984190762043, + "roll": 0.6173566579818726, + "pitch": 0.6173566579818726, + "yaw": 0.6173566579818726, + "type": "position_local", + "status": 0, + "format": "json_v3.1" +} + +``` + +### Reset dead reckoning + +Dead reckoning can be reset by issuing the `reset_dead_reckoning` command: + +``` +{"command": "reset_dead_reckoning"} +``` + +If the request is successfully received the response will have 'success' set to 'true'. The dead reckoning will have a delay of approximately 50ms until the positioning values being zeroed out. If the response is unsuccessful, the 'success' will be 'false' and a non-empty describing text will be returned in 'error_message'. + +``` +{ + "response_to":"reset_dead_reckoning", + "success": true, + "error_message": "", + "result": null, + "format": "json_v3.1", + "type": "response" +} +``` + +### Calibrate gyro + +The gyro can be calibrated by issuing the `calibrate_gyro` command: + +``` +{"command":"calibrate_gyro"} +``` + +The response will be as follows if the calibration is successful. If unsuccessful, `success` will be `false`, and a non-empty `error_message` will be provided. + +``` +{ + "response_to": "calibrate_gyro", + "success": true, + "error_message": "", + "result": null, + "format": "json_v3.1", + "type": "response" +} +``` + +### Trigger ping + +In setups where multiple acoustic sensors are used it can be useful to control the pinging of each acoustic sensor individually. By setting the configuration `acoustic_enabled = false` the pinging of the DVL can be externally controlled. Up to 15 external trigger commands can be queued by issuing the `trigger_ping` command. The DVL will execute each ping in quick succession until no more commands are in the queue. + +See [Integration](integration.md#triggering-and-synchronization) for guidance on using triggering with other acoustic instruments. + +``` +{"command":"trigger_ping"} +``` + +The response will be as follows if the command is accepted. If the queue is full, `success` will be `false`, and a non-empty `error_message` will be provided. + +``` +{ + "response_to": "trigger_ping", + "success": true, + "error_message": "", + "result": null, + "format": "json_v3.1", + "type": "response" +} +``` + +### Configuration over TCP JSON API { #configuration-over-json } + +#### Configuration parameters + +| Variable | Description | +|----------|-------------| +| speed_of_sound | Speed of sound (1000-2000 m/s). Integer | +| mounting_rotation_offset | See the definition of the [vehicle frame](axes.md#vehicle-frame) of the DVL. Typically 0, but can be set to be non-zero if the forward axis of the DVL is not aligned with the forward axis of a vehicle on which it is mounted (0-360 degrees). Integer | +| acoustic_enabled | `true` for normal operation of the DVL,`false` when the sending of acoustic waves from the DVL is disabled (e.g. to save power or slow down its heating up in air) | +| dark_mode_enabled | `false` when the LED operates as [normal](electrical.md#led-signals), `true` for no blinking of the LED (e.g. if the LED is interfering with a camera) | +| range_mode | `auto` when operating as normal, otherwise see [range mode configuration](range-mode.md) or activate water tracking | +| periodic_cycling_enabled | `true` to enable [periodic cycling](configuration.md#periodic-cycling), `false` to disable it | + +#### Fetching current configuration + +The current configuration of the DVL can be obtained by issuing the `get_config` command: + +``` +{"command": "get_config"} +``` + +If the configuration is successfully fetched, the response will be in the following format. If not, `success` will be false, a non-empty `error_message` string will be provided, and `result` will be `null`. + + +``` +{ + "response_to":"get_config", + "success":true, + "error_message":"", + "result":{ + "speed_of_sound":1475.00, + "acoustic_enabled":true, + "dark_mode_enabled":false, + "mounting_rotation_offset":20.00, + "range_mode":"auto", + "periodic_cycling_enabled":true + }, + "format":"json_v3.1", + "type":"response" +} +``` + +#### Setting configuration parameters + +Setting of configuration parameters can be carried out by issuing a `set_config` in the following format, including those parameters which are to be set: + +``` +{"command":"set_config","parameters":{"speed_of_sound":1480}} +``` + +If the parameters are successfully set, the response will be in the following format. If not, `success` will be false, and a non-empty `error_message` string will be provided. + + +``` +{ + "response_to": "set_config", + "success": true, + "error_message": "", + "result" :null, + "format": "json_v3.1", + "type": "response" +} +``` + +#### Activating water tracking + +Water tracking is enabled by setting `range_mode` to `wt`: + +```json +{"command":"set_config","parameters":{"range_mode":"wt"}} +``` + +#### Deactivate water tracking + +Water tracking is deactivated by setting `range_mode` to `auto`: + +```json +{"command":"set_config","parameters":{"range_mode":"auto"}} +``` diff --git a/docs/dvl/dvl-pd-formats.md b/docs/dvl/dvl-pd-formats.md new file mode 100644 index 00000000..7d47df24 --- /dev/null +++ b/docs/dvl/dvl-pd-formats.md @@ -0,0 +1,191 @@ +# PD formats + +The DVL can output PD-compatible formats for integration with systems that already support these formats. + +PD formats are data formats. They can be available over different transports depending on model, software version, and configuration. + +For new integrations, the TCP JSON API is usually the easiest starting point: + +* [DVL A50/A125 TCP JSON API](dvl-json-protocol.md) +* [DVL A100/A250 TCP JSON API](dvl-a250_a100-json-protocol.md) + +## Supported formats + +| Format | Status | Notes | +| --- | --- | --- | +| PD4 | Supported | Supported over TCP and serial for DVL A50, DVL A125, DVL A100, and DVL A250. | +| PD6 | Supported | Supported over TCP and serial for DVL A50, DVL A125, DVL A100, and DVL A250. | +| PD0 | Planned for DVL A100/A250 | Not available yet. Planned over TCP and serial when ready. | + +## Transport support + +| Format | TCP | Serial | Models | +| --- | --- | --- | --- | +| PD4 | Yes | Yes | DVL A50, DVL A125, DVL A100, DVL A250 | +| PD6 | Yes | Yes | DVL A50, DVL A125, DVL A100, DVL A250 | +| PD0 | Planned | Planned | DVL A100, DVL A250 | + +PD4 and PD6 over TCP are always enabled. The TCP port is configurable in the web GUI. + +Serial PD output is configured through the serial output protocol setting: + +* [DVL A50/A125 serial protocol](dvl-serial-protocol.md#change-serial-output-protocol-wcp) +* [DVL A100/A250 serial protocol](dvl-a250_a100-serial-protocol.md#change-serial-output-protocol-wcp) + +## When to use PD formats + +Use PD formats when integrating with software or systems that already expect PD0, PD4, or PD6 output. + +For custom software integrations, use the TCP JSON API unless the receiving system specifically requires a PD format: + +* [DVL A50/A125 TCP JSON API](dvl-json-protocol.md) +* [DVL A100/A250 TCP JSON API](dvl-a250_a100-json-protocol.md) + +## PD6 { #pd6-protocol-tcpserial } + +PD6 support allows integration with equipment that already has a PD6-compatible interface, reducing the need to create a driver based on the Water Linked serial protocol. + +PD6 is supported for output over serial and Ethernet. PD6 over TCP is always enabled. The port in use is configurable in the web GUI. The default port is TCP 1037. + +The serial output can be configured to output PD6 using the serial output protocol setting. + +### Command overview + +Sentences TS, BI, and BD are filled with relevant numbers. All other sentences are set to zero values. + +#### Timing and scaling data (TS) + +`:TS,YYMMDDHHmmsshh,SS.S,+TT.T,DDDD.D,CCCC.C,BBB ` + +| Field | Explanation | Value | +| --- | --- | --- | +| YYMMDDHHmmsshh | Year, month, day, hour, minute, second, hundredths of seconds | Report timestamp | +| SS.S | Salinity in parts per thousand (ppt). | Always 0 | +| DDDD.D | Depth of transducer face in meters. | Always 0 | +| CCCC.C | Speed of sound in meters per second. | Configured speed of sound | +| BBB | Built-in Test (BIT) result code. | Always 0 | + +#### Bottom track, instrument referenced velocity data (BI) + +`:BI,±XXXXX,±YYYYY,±ZZZZZ,±EEEEE,S ` + +| Field | Explanation | Value | +| --- | --- | --- | +| ±XXXXX | X-axis velocity data in mm/s | Current speed | +| ±YYYYY | Y-axis velocity data in mm/s | Current speed | +| ±ZZZZZ | Z-axis velocity data in mm/s | Current speed | +| ±EEEEE | Error in velocity data in mm/s | Current error | +| S | Status of velocity | A = good. V = bad | + +!!! note + Axis used in the BI sentence is the [vehicle frame](axes.md#vehicle-frame). + +#### Bottom track, earth referenced distance data (BD) + +`:BD,±EEEEEEEE.EE,±NNNNNNNN.NN,±UUUUUUUU.UU,DDDD.DD,TTT.TT ` + +| Field | Explanation | Value | +| --- | --- | --- | +| ±EEEEEEEE.EE | East distance in meters. | Always 0 | +| ±NNNNNNNN.NN | North distance in meters. | Always 0 | +| ±UUUUUUUU.UU | Upward distance in meters. | Always 0 | +| DDDD.DD | Range to bottom in meters | Current altitude | +| TTT.TT | Time since last good velocity estimate in seconds. | Always 0 | + +#### Bottom track, ship referenced distance data (BS) + +* In the 2.4.0 software release, the BS values are always zero. +* As of the 2.4.4 software release, the BS values are given by the actual velocity. + +`:BS,±TTTTTTTT.TT,±LLLLLLLL.LL,±NNNNNNN.NN,S ` + +| Field | Explanation | Value | +| --- | --- | --- | +| ±TTTTTTTT.TT | Transverse movement, (+ = Port to Starboard velocity relative to bottom) in mm/s | Y axis velocity | +| ±LLLLLLLL.LL | Longitudinal movement, (+ = Aft to Forward velocity relative to bottom) in mm/s | X axis velocity | +| ±NNNNNNN.NN | Ship velocity away from bottom in mm/s | Z axis velocity | +| S | Status of velocity | A = good. V = bad | + +#### Example output + + + +```text +:SA, +0.00, +0.00, 0.00 +:TS,22020812061800, 0.0, +0.0, 0.0,1475.0, 0 +:WI, +0, +0, +0, +0,V +:WS, +0, +0, +0,V +:WE, +0, +0, +0,V +:WD, +0.00, +0.00, +0.00, 0.00, 0.00 +:BI, +123, -420, +2000, +0,A +:BS, -420, +123, +2000,A +:BE, +0, +0, +0,V +:BD, +0.00, +0.00, +0.00, 5.32, 0.00 +``` + +## PD4 { #pd4-protocol-tcpserial } + +The PD4 string is intended for use with equipment that already has a PD4-compatible interface, reducing the need to create a driver based on the Water Linked serial protocol. + +PD4 is supported for output over serial and Ethernet. PD4 over TCP is always enabled. The port in use is configurable in the web GUI. The default port is TCP 1038. + +!!! note + PD4 format support was added in software release 2.5.2 and is experimental. Please give feedback on this feature. + +### Data format + +PD4 is a binary format where fields are defined by their position in one message. +Data fields which use more than one byte are LittleEndian encoded. + +| Byte(s) | Data type | Used | Unit | +| --- | --- | --- | --- | +| 0 | DVL Data ID 7Dh | y | | +| 1 | Data structure (always equal to 0) | y | | +| 2,3 | Number of bytes | y | | +| 4 | System Config (0x10100011[^pd4_system_config]) | y | | +| 5,6 | X velocity bottom | y | mm/s | +| 7,8 | Y velocity bottom | y | mm/s | +| 9,10 | Z velocity bottom | y | mm/s | +| 11,12 | E velocity bottom | y | mm/s | +| 13,14 | BM1 range to bottom | y | cm | +| 15,16 | BM2 range to bottom | y | cm | +| 17,18 | BM3 range to bottom | y | cm | +| 19,20 | BM4 range to bottom | y | cm | +| 21 | Bottom status | y | bool | +| 22,23 | X-Velocity reference layer | n | | +| 24,25 | Y-Velocity reference layer | n | | +| 26,27 | Z-Velocity reference layer | n | | +| 28,29 | E-Velocity reference layer | n | | +| 30,31 | Reference layer start | n | | +| 32,33 | Reference layer end | n | | +| 34 | Reference layer status | n | | +| 35 | Time of first ping - hour | y | hours | +| 36 | Time of first ping - minute | y | minutes | +| 37 | Time of first ping - second | y | seconds | +| 38 | Time of first ping - hundredths | y | centi-seconds | +| 39,40 | Bit result | n | | +| 41,42 | Speed of Sound | y | m/s | +| 43,44 | Temperature | n | | +| 45,46 | Checksum | y | N/A | + +### BM1-BM4 mapping + +To use BM1-BM4 correctly, use this translation. The numbering comes from the transducer numbering shown in the image below. + +* **BM1** is transducer 3. +* **BM2** is transducer 1. +* **BM3** is transducer 4. +* **BM4** is transducer 2. + +!!! note "Transducer numbering and protocol IDs" + Mechanical/transducer diagrams number the transducers from 1 to 4. In protocol messages and diagnostic logs, the transducer `id` uses zero-based numbering from 0 to 3. The `id` is therefore the transducer number minus 1. + +![dvl_a50_transducer_numbering](../img/WL-21035-3_DVL-A50_Front_1600_transducers_crop.jpg) + +[^pd4_system_config]: Indicates that the velocities are in ship coordinates, tilt is used, three-beam is not computed, and the frequency is 600 kHz. + +## PD0 { #pd0-protocol } + +PD0 is planned for DVL A100 and DVL A250. It is not available yet. + +When ready, PD0 is planned for both TCP and serial output. diff --git a/docs/dvl/dvl-serial-protocol.md b/docs/dvl/dvl-serial-protocol.md new file mode 100644 index 00000000..6aca5826 --- /dev/null +++ b/docs/dvl/dvl-serial-protocol.md @@ -0,0 +1,468 @@ +# DVL A50/A125 serial protocol + +Describes the Water Linked DVL serial protocol for DVL A50 and DVL A125. For PD4 and PD6 output formats, see [PD formats](dvl-pd-formats.md). + +## Terminology + +* DVL - Doppler Velocity Log - Uses hydro-acoustic beams to measure the velocity at which the DVL is moving across a surface (typically an unmoving one such as the sea bottom), and the distance to this surface. +* ACK - Acknowledgement. The command issued was successful. +* NAK - Negative acknowledgement. The command issued failed. +* Ping - A pulse of sound sent by the DVL +* Time of validity - Timestamp of the surface reflection ('center of ping') +* Time of transmission - Timestamp taken directly before sending data over the serial or TCP protocols. The difference between time of transmission and time of validity includes both the time for the acoustic wave to travel from the surface from which it was reflected back to the DVL, and the decoding and processing of this signal internally in the DVL. + +## Version + +This document describes serial protocol versions `2.6.x` and `2.7.x` (major.minor.patch): + +- MAJOR version increments represent incompatible API changes +- MINOR version increments represent additional backwards-compatible functionality +- PATCH version increments represent backwards-compatible bug fixes + +### Version history overview + +| Software release | Serial protocol version | Main protocol improvements | +| -- | -- | -- | +| 2.7.1 | 2.7.0 | Add water tracking mode and tracking mode field in velocity reports | +| 2.6.1 | 2.6.0 | Serial baud rate configurable. Add PD4 format support in serial 'wcp' command. Some serial protocol names [changed](#change-serial-output-protocol-wcp). | +| 2.5.2 | 2.5.0 | Add PD4 format support (experimental) +| 2.4.4 | 2.5.0 | Change gyro calibration to store persistently. Note: gyro calibration commands now take up to 15 seconds. +| 2.4.0 | 2.5.0 | Add ability to trigger pings (TCP JSON API/serial), add configuration for periodic cycling (TCP JSON API/serial) +| 2.2.1 | 2.4.0 | Add serial output protocol configuration, range mode configuration and calibrate gyro command, Fix missing line ending in configuration (TCP JSON API), fix dark mode enabled naming inconsistency (TCP JSON API), change speed of sound and mounting rotation offset from integer to float +| 2.1.0 | 2.3.0 | Add configuration, add time_of_validity/time_of_transmission, add covariance (TCP JSON API) +| 2.0.8 | 2.2.0 | Add position estimation, Add output of orientation angles +| 1.6.0 | 2.1.0 | Initial (velocity only) + + +## Serial protocol + +### Overview + +The default serial communication format is 115200 8-N-1 (no hardware flow control). Release 2.6.1 and later allow different baud rates through web GUI configuration. + +DVL A50 and DVL A125 use a 3.3 V UART interface that is 5 V tolerant. See [DVL A50/A125 serial interface](electrical.md#dvl-a50-and-dvl-a125-serial-interface). + +Packets sent to and received from the DVL start with a `w` and end with LF, CR+LF, or CR. The packet format is: + +| Start byte | Direction | Command | Options (0 to many) | Checksum | End byte | +|------------|------------------|----------|----------------------|----------|----------------| +| `w` | `c` or `r` | `x` | `,[option]` | `*xx` | `\n`, `\r\n`, or `\r` | + +`Direction` is `c` (short for 'command') for packets sent to the DVL, and `r` (short for 'response') for packets sent from the DVL. +The commands can be sent from a terminal program that supports sending a full line at a time. The timeout between characters is approximately 10 ms. + +!!!note + Please verify the baud rate configuration in the web GUI if you are unable to communicate with the default baud rate. + + +!!!note + The checksum is optional when sending commands to the DVL. The DVL always returns a checksum. The checksum algorithm + is CRC-8 and it is formatted as a hexadecimal number using 2 lower-case characters (ex: `*c3`). See [below](#checksum) for details. + +### Command overview + +The commands in the table are shown without the checksum and without the mandatory line ending (any of `\n`, `\r\n`, or `\r`) for readability. In all cases, the response to a submitted command may be `wrn`, `wr?`, or `wr!` (see below for details), but only the format of a successful response is listed. + +| Command | Description | Response | Description | +|---------|-------------|----------|-------------| +| `wcv` | Get protocol version | `wrv,`*[major],[minor],[patch]* | Protocol version. eg: `wrv,2.5.0` | +| `wcw` | Get product detail | `wrw,`*[name]*,*[version]*,*[chipID]*,*[IP address]* | Where type is dvl, name is product name, version is software version, chip ID is the chip ID and _optionally_ the IP address if connected to DHCP server: eg: `wrw,dvl-a50,2.2.1,0xfedcba98765432` or `wrw,dvl-a50,2.2.1,0xfedcba98765432,10.11.12.140` | +| `wcs,`*[configuration parameters]* | Set configuration parameters | `wra` | Successfully set the specified configuration parameters. See [Configuration](#configuration-over-serial) for details | +| `wcc` | Get current configuration | `wrc,`*[configuration parameters]* | Entire current configuration. See [Configuration](#configuration-over-serial) for details | +| `wcr` | Reset dead reckoning | `wra` | Successfully started a new [dead reckoning](dead-reckoning.md#starting-dead-reckoning) run | +| `wcx` | Trigger ping | `wra` | Successfully queued a ping | +| `wcg` | Calibrate gyro | `wra` | Successfully calibrated gyro | +| `wcp` | Change serial output protocol | `wra` | Successfully changed output protocol | +| | | `wrz,`*[details below]* | Velocities calculated | +| | | `wrs,`*[details below]* | Velocities calculated during water tracking | +| | | `wru,`*[details below]* | Transducer information | +| | | `wrp,`*[details below]* | [Dead reckoning](dead-reckoning.md) report | +| | | `wrx,`*[details below]* | DEPRECATED: Velocities calculated (old format) | +| | | `wrt,`*[details below]* | DEPRECATED: Transducer information (old format) | +| | | `wr?` | Malformed request: packet cannot be understood or no newline received before timeout | +| | | `wr!` | Malformed request: packet does not match the given checksum | +| | | `wrn` | Not acknowledged (nack): an error occurred when handling the packet | + + + +### Velocity report (wrz) + +A velocity report is output for each velocity calculation of the DVL. The rate depends on the altitude of the DVL (distance to the sea bottom or other reflecting surface), but will be in the range 2-15 Hz. + +The X, Y, and Z axes are with respect to [body frame](axes.md#body-frame) of the DVL, or the [vehicle frame](axes.md#vehicle-frame) if the DVL is mounted on a vehicle at an angle, specified as a 'mounting rotation offset', from the forward axis of the vehicle. + +The report has the following format: +`wrz,`*[vx],[vy],[vz],[valid],[altitude],[fom],[covariance],[time_of_validity],[time_of_transmission],[time],[status] + + +| Variable | Description | +|----------|-------------| +| vx | Velocity in x direction (m/s) | +| vy | Velocity in y direction (m/s) | +| vz | Velocity in z direction (m/s) | +| valid | If `y`, the DVL has a lock on the reflecting surface, and the altitude and velocities are valid (y/n) | +| altitude | Measured altitude to the bottom (m) | +| fom | Figure of merit, a measure of the accuracy of the velocities (m/s) | +| covariance | Covariance matrix for the velocities. The figure of merit is calculated from this. 9 entries ((m/s)^2) separated by ; | +| time_of_validity | Timestamp of the surface reflection, aka 'center of ping' (Unix timestamp in microseconds) | +| time_of_transmission | Timestamp from immediately before sending of the report over TCP (Unix timestamp in microseconds) | +| time | Milliseconds since last velocity report (ms) | +| status | 8 bit status mask. Bit 0 is set to 1 for high temperature and DVL will soon enter thermal shutdown. Remaining bits are reserved for future use. | + + +Example where all velocities are valid: + +``` +wrz,0.120,-0.400,2.000,y,1.30,1.855,1e-07;0;1.4;0;1.2;0;0.2;0;1e+09,7,14,123.00,1*50 +``` + +### Velocity report (wrs) + +A velocity report is output for each velocity calculation of the DVL in this format when water tracking is activated. The update rate will be 2 Hz. + +The X, Y, and Z axes are with respect to [body frame](axes.md#body-frame) of the DVL, or the [vehicle frame](axes.md#vehicle-frame) if the DVL is mounted on a vehicle at an angle, specified as a 'mounting rotation offset', from the forward axis of the vehicle. + +The report has the following format: +`wrz,`*[vx],[vy],[vz],[valid],[fom],[covariance],[time_of_validity],[time_of_transmission],[time],[status] + + +| Variable | Description | +|----------|-------------| +| vx | Velocity in x direction (m/s) | +| vy | Velocity in y direction (m/s) | +| vz | Velocity in z direction (m/s) | +| valid | If `y`, the DVL has a lock on the reflecting surface, and the altitude and velocities are valid (y/n) | +| fom | Figure of merit, a measure of the accuracy of the velocities (m/s) | +| covariance | Covariance matrix for the velocities. The figure of merit is calculated from this. 9 entries ((m/s)^2) separated by ; | +| time_of_validity | Timestamp of the surface reflection, aka 'center of ping' (Unix timestamp in microseconds) | +| time_of_transmission | Timestamp from immediately before sending of the report over TCP (Unix timestamp in microseconds) | +| time | Milliseconds since last velocity report (ms) | +| status | 8 bit status mask. Bit 0 is set to 1 for high temperature and DVL will soon enter thermal shutdown. Remaining bits are reserved for future use. | + + +Example where all velocities are valid: + +``` +wrs,0.120,-0.400,2.000,y,1.855,1e-07;0;1.4;0;1.2;0;0.2;0;1e+09,7,14,123.00,1*50 +``` + +Water tracking is enabled by setting `range_mode` to `wt`: + +```text +wcs,,,,,wt, +``` + +### Transducer report (wru) + +A transducer report is output for each of the four transducers of the DVL for each velocity calculation of the DVL. The rate will be the same as that of the velocity report. If the transducer did not receive a signal that could be successfully decoded, `distance` will be set to -1, and `velocity` will be set to 0. RSSI and NSD will be output in all cases. + +The report has the following format: +`wru,`*[id],[velocity],[distance],[rssi],[nsd]* + + +| Variable | Description | +|----------|-------------| +| id | Zero-based transducer `id`, from 0 to 3 | +| velocity | Velocity in the direction of the transducer (m/s) | +| distance | Distance (parallel to the transducer beam, i.e. not the vertical distance) to the reflecting surface from this transducer (m) | +| rssi | Received signal strength indicator: strength of the signal received by this transducer (dBm) | +| nsd | Noise spectral density: strength of the background noise received by this transducer (dBm) | + +!!! note "Transducer numbering and protocol IDs" + Mechanical/transducer diagrams number the transducers from 1 to 4. In protocol messages and diagnostic logs, the transducer `id` uses zero-based numbering from 0 to 3. The `id` is therefore the transducer number minus 1. + +Example where all data is valid: + +``` +wru,0,0.070,1.10,-40,-95*9c +wru,1,-0.500,1.25,-62,-104*f0 +wru,2,2.200,1.40,-56,-98*18 +wru,3,1.800,1.35,-58,-96*a3 +``` + + +### Dead reckoning report (wrp) + +A dead reckoning report outputs the current speed, position, and orientation of the DVL as calculated by [dead reckoning](dead-reckoning.md), with respect to a [frame](dead-reckoning.md#frame) defined by the axes of the DVL's [body frame](axes.md#body-frame), or [vehicle frame](axes.md#vehicle-frame) if a mounting rotation offset is set, at the start of the dead reckoning run. The expected update rate is 5 Hz. + +The format is: +`wrp,`*[time_stamp],[x],[y],[z],[pos_std],[roll],[pitch],[yaw],[status]* + +Variable | Description +------------|------------- +time_stamp | Time stamp of report (Unix timestamp in seconds) +x | Distance in X direction (m) +y | Distance in Y direction (m) +z | Distance in downward direction (m) +pos_std | Standard deviation (Figure of merit) for position (m) +roll | Rotation around X axis (degrees) +pitch | Rotation around Y axis (degrees) +yaw | Rotation around Z axis, i.e. heading (degrees) +status | Reports if there are any issues with the DVL (0 if no errors, 1 otherwise) | + +Example: + +``` +wrp,49056.809,0.41,0.15,1.23,0.4,53.9,13.0,19.3,0*de +wrp,49057.269,0.39,0.18,1.23,0.4,53.9,13.0,19.3,0*e2 +``` + + +### Reset dead reckoning (wcr) + +Dead reckoning can be reset by issuing the `wcr` command. The reply will be an ack (`wra`) if the reset is successful, and a nak (`wrn`) if not. + +### Calibrate gyro (wcg) + +The gyro can be calibrated by issuing the `wcg` command. The reply will be an ack (`wra`) if the reset is successful, and a nak (`wrn`) if not. + +### Trigger ping (wcx) + +In setups where multiple acoustic sensors are used it can be useful to control the pinging of each acoustic sensor individually. By setting the configuration `acoustic_enabled = n` the pinging of the DVL can be externally controlled. Up to 15 external trigger commands can be queued by issuing the `wcx` command. The DVL will execute each ping in quick succession until no more commands are in the queue. + +See [Integration](integration.md#triggering-and-synchronization) for guidance on using triggering with other acoustic instruments. + +For DVL A100/A250 RX-line hardware triggering, see [Integration](integration.md#rx-line-trigger). + +The reply will be an ack (`wra`) if the command is successful, and a nak (`wrn`) if queue is full. + +### Change serial output protocol (wcp) + +The serial output protocol in use can be configured by issuing the `wcp` command. The selected protocol is persistent over reboots. + +``` +wcp,[protocol number] +``` + +The supported protocols are: + +| Protocol number | Name | Description | +| --------------- | ---- | ----------- | +| 0 | Output disabled | No output on serial. Recommended if serial port is not used to lower latency on Ethernet protocols. | +| 1 | WL - Serial V1 and V2 | All output including the deprecated `wrx` and `wrt` sentences. | +| 2 | PD6 | PD6 format output. See [PD6 format description](dvl-pd-formats.md#pd6-protocol-tcpserial) | +| 3 | WL - Serial V2 | All output excluding the deprecated `wrx` and `wrt` sentences. | +| 4 | Not used | Not used | +| 5 | Not used | Not used | +| 6 | PD4 | PD4 format output. See [PD4 format description](dvl-pd-formats.md#pd4-protocol-tcpserial) | + +The reply will be an ack (`wra`) if the protocol change is successful, and a nak (`wrn`) if not. + +Example setting configuring output to use protocol number 3: + +``` +wcp,3 +``` + +!!!note + Prior to release 2.6.1 protocol number 1 was named `Backward compatible` and protocol number 3 was named `Latest`. There is no change in functionality. + +### Configuration over serial + +#### Configuration parameters + +| Variable | Description | +|----------|-------------| +| speed_of_sound | Speed of sound (1000-2000 m/s). Float | +| mounting_rotation_offset | See the definition of the [vehicle frame](axes.md#vehicle-frame) of the DVL. Typically 0, but can be set to be non-zero if the forward axis of the DVL is not aligned with the forward axis of a vehicle on which it is mounted (0-360 degrees). Float | +| acoustic_enabled | `y` for normal operation of the DVL,`n` when the sending of acoustic waves from the DVL is disabled (e.g. to save power or slow down its heating up in air) | +| dark_mode_enabled | `n` when the LED operates as [normal](electrical.md#led-signals). `y` for no blinking of LED (e.g. if the LED is interfering with a camera) | +| range_mode |`auto` when operating as normal, otherwise see [range mode configuration](range-mode.md) | +| periodic_cycling_enabled | `y` to enable [periodic cycling](configuration.md#periodic-cycling), `n` to disable it. See [Configuration over TCP JSON API](dvl-json-protocol.md#configuration-over-json) for details | + +!!!note + For backward compatibility the `range_mode` and `periodic_cycling_enabled` parameters are optional when setting the configuration. They will always be returned when reading the configuration (`wcc`). + Speed of sound and mounting rotation was changed from integer to float in serial protocol 2.4.0 + +#### Fetching current configuration + +The current configuration of the DVL can be obtained by issuing the `wcc` command. + + +If the configuration is successfully fetched, the response will be in the following format. If not, a nak `wrn` will be returned. + +``` +wrc,[speed_of_sound],[mounting_rotation_offset],[acoustic_enabled],[dark_mode_enabled],[range_mode],[periodic_cycling_enabled] +``` + +#### Setting configuration parameters + +Setting of configuration parameters can be carried out by issuing the `wcs` command in the following format. + + +``` +wcs,[speed_of_sound],[mounting_rotation_offset],[acoustic_enabled],[dark_mode_enabled],[range_mode],[periodic_cycling_enabled] +``` + +Those parameters which are not to be set can be left blank. + +Example for setting dark mode without changing the other parameters: + +``` +wcs,,,,y,, +``` + +Example of setting water tracking: + +Water tracking is enabled by setting `range_mode` to `wt`: + +```text +wcs,,,,,wt, +``` + +Example for setting speed of sound to 1450 m/s and disabling acoustics, without changing the other parameters: + +``` +wcs,1450,,n,,, +``` + +The response will be an ack `wra` if the parameters are successfully set, a nak `wrn` if the command was successfully parsed but the parameters were not successfully set, and a malformed request `wr?` if the command was not successfully parsed, e.g. if the wrong number of parameters was used, or either `speed_of_sound` or `mounting_rotation_offset` was not an integer. + +The new configuration will not be returned in the response, but can be obtained by issuing a `wcc` command as above. + + +### Velocity report, old format (wrx) [Deprecated] + +Same purpose as the [velocity report](#velocity-report-wrz), but in an older format: + +`wrx,`*[time],[vx],[vy],[vz],[fom],[altitude],[valid],[status]* + +| Variable | Description | +|----------|-------------| +| time | Milliseconds since last velocity report (ms) | +| vx | Velocity in x direction (m/s) | +| vy | Velocity in y direction (m/s) | +| vz | Velocity in z direction (m/s) | +| fom | Figure of merit, a measure of the accuracy of the velocities (m/s) | +| altitude | Distance to the reflecting surface along Z axis (m) | +| valid | If `y`, the DVL has lock on the reflecting surface, and the altitude and velocities are valid (y/n) | +| status | 8 bit status mask. Bit 0 is set to 1 for high temperature and DVL will soon enter thermal shutdown. Remaining bits are reserved for future use. | + +Example where velocities are valid: + +``` +wrx,112.83,0.007,0.017,0.006,0.000,0.93,y,0*d2 +wrx,140.43,0.008,0.021,0.012,0.000,0.92,y,0*b7 +wrx,118.47,0.009,0.020,0.013,0.000,0.92,y,0*54 +``` + +Example where velocities and altitude are not valid and a high temperature warning occurs: + +``` +wrx,1075.51,0.000,0.000,0.000,2.707,-1.00,n,1*04 +wrx,1249.29,0.000,0.000,0.000,2.707,-1.00,n,1*6a +wrx,1164.94,0.000,0.000,0.000,2.707,-1.00,n,1*39 +``` + +### Transducer report, old format (wrt) [Deprecated] + +Same purpose as the [transducer report](#transducer-report-wru), but in an older format, and combining the data of all four transducers: + +`wrt,`*[dist_1],[dist_2],[dist_3],[dist_4]* + +| Variable | Description | +|----------|-------------| +| dist_1 | Distance (parallel to the transducer beam, i.e. not the vertical distance) to reflecting surface from transducer 1 (m) | +| dist_2 | Distance to reflecting surface from transducer 2 (m) | +| dist_3 | Distance to reflecting surface from transducer 3 (m) | +| dist_4 | Distance to reflecting surface from transducer 4 (m) | + +Example where all distances are valid: + +``` +wrt,15.00,15.20,14.90,14.20*b1 +wrt,14.90,15.10,14.80,14.10*ac +``` + +Example where distance is not valid for transducer 4: + +``` +wrt,14.90,15.10,14.80,-1.00*53 +wrt,15.00,15.20,14.90,-1.00*71 +``` + + +### Checksum + +The checksum algorithm is CRC-8 (Polynomal: 0x07, Init: 0x00, RefIn/RefOut: false, XorOut: 0x00, Check: 0xf4). +Checksum is formatted as a hexadecimal number using 2 lower-case characters (ex: `*c3`). + +Compatible implementations: + +* Python 3: [crcmod](https://pypi.org/project/crcmod/) `crcmod.predefined.mkPredefinedCrcFun("crc-8")` +* Golang: [github.com/sigurn/crc8](https://github.com/sigurn/crc8) `crc8.MakeTable(crc8.CRC8)` + +Example for how to verify checksum using Python 3 and [crcmod](https://pypi.org/project/crcmod/): + +``` +crc = crcmod.predefined.mkPredefinedCrcFun("crc-8") +sentence = b"wrx,1164.94,0.000,0.000,0.000,2.707,-1.00,n,1*39" +data, checksum = sentence.split(b"*") + +if crc(data) == int(checksum, 16): + print("CRC valid") +else: + print("CRC invalid") +``` + +The [crcmod](https://pypi.org/project/crcmod/) python package can generate code in other languages. Here is an example (subject to the [MIT License](https://opensource.org/licenses/MIT)) for C which should be straightforward to adapt to other languages. + +``` +static const uint8_t lookup_table[256] = { + 0x00U,0x07U,0x0EU,0x09U,0x1CU,0x1BU,0x12U,0x15U, + 0x38U,0x3FU,0x36U,0x31U,0x24U,0x23U,0x2AU,0x2DU, + 0x70U,0x77U,0x7EU,0x79U,0x6CU,0x6BU,0x62U,0x65U, + 0x48U,0x4FU,0x46U,0x41U,0x54U,0x53U,0x5AU,0x5DU, + 0xE0U,0xE7U,0xEEU,0xE9U,0xFCU,0xFBU,0xF2U,0xF5U, + 0xD8U,0xDFU,0xD6U,0xD1U,0xC4U,0xC3U,0xCAU,0xCDU, + 0x90U,0x97U,0x9EU,0x99U,0x8CU,0x8BU,0x82U,0x85U, + 0xA8U,0xAFU,0xA6U,0xA1U,0xB4U,0xB3U,0xBAU,0xBDU, + 0xC7U,0xC0U,0xC9U,0xCEU,0xDBU,0xDCU,0xD5U,0xD2U, + 0xFFU,0xF8U,0xF1U,0xF6U,0xE3U,0xE4U,0xEDU,0xEAU, + 0xB7U,0xB0U,0xB9U,0xBEU,0xABU,0xACU,0xA5U,0xA2U, + 0x8FU,0x88U,0x81U,0x86U,0x93U,0x94U,0x9DU,0x9AU, + 0x27U,0x20U,0x29U,0x2EU,0x3BU,0x3CU,0x35U,0x32U, + 0x1FU,0x18U,0x11U,0x16U,0x03U,0x04U,0x0DU,0x0AU, + 0x57U,0x50U,0x59U,0x5EU,0x4BU,0x4CU,0x45U,0x42U, + 0x6FU,0x68U,0x61U,0x66U,0x73U,0x74U,0x7DU,0x7AU, + 0x89U,0x8EU,0x87U,0x80U,0x95U,0x92U,0x9BU,0x9CU, + 0xB1U,0xB6U,0xBFU,0xB8U,0xADU,0xAAU,0xA3U,0xA4U, + 0xF9U,0xFEU,0xF7U,0xF0U,0xE5U,0xE2U,0xEBU,0xECU, + 0xC1U,0xC6U,0xCFU,0xC8U,0xDDU,0xDAU,0xD3U,0xD4U, + 0x69U,0x6EU,0x67U,0x60U,0x75U,0x72U,0x7BU,0x7CU, + 0x51U,0x56U,0x5FU,0x58U,0x4DU,0x4AU,0x43U,0x44U, + 0x19U,0x1EU,0x17U,0x10U,0x05U,0x02U,0x0BU,0x0CU, + 0x21U,0x26U,0x2FU,0x28U,0x3DU,0x3AU,0x33U,0x34U, + 0x4EU,0x49U,0x40U,0x47U,0x52U,0x55U,0x5CU,0x5BU, + 0x76U,0x71U,0x78U,0x7FU,0x6AU,0x6DU,0x64U,0x63U, + 0x3EU,0x39U,0x30U,0x37U,0x22U,0x25U,0x2CU,0x2BU, + 0x06U,0x01U,0x08U,0x0FU,0x1AU,0x1DU,0x14U,0x13U, + 0xAEU,0xA9U,0xA0U,0xA7U,0xB2U,0xB5U,0xBCU,0xBBU, + 0x96U,0x91U,0x98U,0x9FU,0x8AU,0x8DU,0x84U,0x83U, + 0xDEU,0xD9U,0xD0U,0xD7U,0xC2U,0xC5U,0xCCU,0xCBU, + 0xE6U,0xE1U,0xE8U,0xEFU,0xFAU,0xFDU,0xF4U,0xF3U, +}; + +uint8_t crc8(uint8_t *message, int message_length) { + uint8_t checksum = 0; + while (message_length > 0) { + checksum = lookup_table[*message ^ checksum]; + message++; + message_length--; + } + return checksum; +} +``` + +## PD6 format (TCP/Serial) { #pd6-protocol-tcpserial } + +PD6 is supported over serial and TCP for all DVL models. + +See the canonical [PD6 format description](dvl-pd-formats.md#pd6-protocol-tcpserial). + + +## PD4 format (TCP/Serial) { #pd4-protocol-tcpserial } + +PD4 is supported over serial and TCP for all DVL models. + +See the canonical [PD4 format description](dvl-pd-formats.md#pd4-protocol-tcpserial). diff --git a/docs/dvl/dvl-triggering.md b/docs/dvl/dvl-triggering.md new file mode 100644 index 00000000..cef87dbb --- /dev/null +++ b/docs/dvl/dvl-triggering.md @@ -0,0 +1,34 @@ +# DVL triggering + +The DVL has different options for triggering acoustic pings to perform a velocity measurement. Triggering can be useful when you need to synchronize the DVL with other sensors. + +| Model | Software triggering | Hardware triggering | +| ---- | ---- | ---- | +| A50/A125 | Yes | No | +| A100/A250 | Yes | Yes | + +## Hardware triggering + +Use the RS232 RX line of the DVL to send a trigger command after enabling hardware triggering in the [configuration](configuration.md#operating-configurations). + +Once hardware triggering is enabled, transmit a "NUL" ASCII character (Ctrl + @) to send a ping. The trigger is detected on the falling edge of the signal. + + + +You can send this trigger signal as often as needed. If the DVL is already transmitting, it discards the signal. + +!!! warning + Acoustics must be enabled. If acoustics are disabled, hardware triggering will not work. + +## Software triggering + +Software triggering is available for all DVL models. It triggers a ping over the TCP JSON API or serial protocol. Acoustics must be disabled for this to work. + +Software triggering differs from hardware triggering because it is sent as a request to the DVL and placed in a ping queue. The queue can store up to 15 requests, which are executed one after another until the queue is empty. + +See the software ping command in [Commands](configuration.md#commands). + +Because this method depends on the internal state of the DVL, the ping queue, and Ethernet jitter if Ethernet is used, the exact ping time is less predictable than with hardware triggering. + +!!! warning + Disable acoustics before using software triggering. This is different from hardware triggering. diff --git a/docs/dvl/electrical.md b/docs/dvl/electrical.md new file mode 100644 index 00000000..a22938b9 --- /dev/null +++ b/docs/dvl/electrical.md @@ -0,0 +1,142 @@ +# Electrical connection + +This page covers electrical connection, LED signals, wiring, shielding, and serial interface for all DVLs. + +Most wiring is common across the DVL models. The serial electrical interface differs: + +* DVL A50 and DVL A125 use 3.3 V UART, 5 V tolerant. +* DVL A100 and DVL A250 use RS232. + +## LED signals + +| Visualization | LED signal | Description | +| :---: | :--- | :--- | +| ⚫ | **No green light** | Power is off. | +| 🟢 | **Fixed green light** | The DVL is powering on. Depending on configuration it can take ~30-60 seconds to power on. | +| 🟢⚫⚫⚫ | **Flashing green light** (mostly off, slow) | DVL looking for bottom lock. | +| 🟢🟢🟢⚫ | **Flashing green light** (mostly on, slow) | DVL has bottom lock. | +| 🟢⚫🟢⚫ | **Flashing green light** (fast) | DVL is in [thermal shutdown](how-to-diagnose.md#thermal-shutdown). | + +## Wiring interface + +Power and Ethernet wiring are common. The brown and brown/white serial pair depends on the DVL model. + +### Common power and Ethernet wires + +| Interface | Color | Visual | +| :--- | :--- | :---: | +| Negative/Ground | Black | ⬛ | +| Positive (10–30 Vdc) | Red | 🟥 | +| ETH RX+ | Green/White | 🟩⬜ | +| ETH RX- | Green | 🟩 | +| ETH TX- | Orange | 🟧 | +| ETH TX+ | Orange/White | 🟧⬜ | +| Shielded wire | Naked/silver | ⚪ | + +### Model-specific serial wires + +| Model | Interface | Color | Visual | +| :--- | :--- | :--- | :---: | +| DVL A50/A125 | UART TX | Brown/White | 🟫⬜ | +| DVL A50/A125 | UART RX | Brown | 🟫 | +| DVL A100/A250 | Serial (RS232) TX | Brown/White | 🟫⬜ | +| DVL A100/A250 | Serial (RS232) RX | Brown | 🟫 | + +!!! note + Power must be applied to the power terminals before applying voltage to the serial pins. + +## Seacon connector option + +The Seacon connector option is available for: + +* DVL A50. +* DVL A100 side-entry versions only. +* DVL A250 side-entry versions only. + + + +### DVL A50/A100/A250 Seacon MCOM8M connector + +The table below shows the pinout for the DVL A50/A100/A250 Seacon MCOM8M connector. + +| Interface | Pin | Color | Visual | +| :--- | :--- | :--- | :---: | +| Negative/Ground | 1 | Black | ⬛ | +| Positive (10–30 Vdc) | 2 | Red | 🟥 | +| ETH RX+ | 3 | Green/White | 🟩⬜ | +| ETH RX- | 4 | Green | 🟩 | +| ETH TX- | 5 | Orange | 🟧 | +| ETH TX+ | 6 | Orange/White | 🟧⬜ | +| UART TX | 7 | Brown/White | 🟫⬜ | +| UART RX | 8 | Brown | 🟫 | + + + +## Power specifications + +| Specification | DVL A50 | DVL A100 | DVL A125 | DVL A250 | +| :--- | :--- | :--- |:--- |:--- | +| Input voltage | 10–30 Vdc | 10–30 Vdc | 10–30 Vdc | 10–30 Vdc | +| Power consumption, average | 4 W | 8 W | 4 W | 8 W | +| Power-on current surge | 35 W | 30 W | 35 W | 30 W | + + + +## Shielded cable information + +Shielded DVL cable helps protect the communication and power lines from external electromagnetic interference (EMI) and radio frequency interference (RFI). The DVL electronics are not internally connected to the shield; it is up to the user to decide whether and how to connect the shield. + +!!! note + For DVL A50, shielded cables were introduced autumn 2024. + + All DVLs with Seacon MCOM8M connector are delivered with unshielded cable that can be grounded. + + All DVL A125 units are delivered with shielded cable. + + + +For DVL A100, the side cable entry version has a 3 m shielded cable, and the rear O-ring interface version has a 1 m shielded cable. + +### Connecting the shield + +For optimal performance, especially when mounted on an ROV (Remotely Operated Vehicle) or AUV (Autonomous Underwater Vehicle), connect the shield to reduce the impact of interference on communication and power signals. The most common connection methods are: + +1. **Chassis ground**: Connect the shield to the chassis of the ROV/AUV. This gives the shield a path to ground for noise and interference, and the vehicle chassis often acts as a common grounding reference. +2. **Common ground**: Connect the shield to the common electrical ground of the ROV/AUV. This may be used when the electrical and signal systems are designed to share a common ground. + +### Recommendation + +We recommend connecting the shield to the **chassis ground** of the ROV or AUV if possible. If your system design uses a common electrical ground, that option can also be considered. + +Ground the shield at one end only to avoid ground loops, unless your system design requires grounding at both ends. + +## Terminal / serial interface + +### DVL A50 and DVL A125 serial interface { #dvl-a50-and-dvl-a125-serial-interface } + +DVL A50 and DVL A125 use the same 3.3 V UART interface, 5 V tolerant. + +| Setting | Value | +| :--- | :--- | +| Interface | 3.3 V UART, 5 V tolerant | +| Baud rate | 115200 | +| Data/parity/stop | 8N1 | +| Flow control | None | + +!!! warning + There can be a momentary (<10 us) power spike (~5 V) on the UART lines when power is applied to the DVL, which may damage equipment that is not 5 V tolerant. + +See the [DVL A50/A125 serial protocol](dvl-serial-protocol.md#serial-protocol). + +### DVL A100 and DVL A250 serial interface { #dvl-a100-and-dvl-a250-serial-interface } + +DVL A100 and DVL A250 use a standard RS232 serial interface. + +| Setting | Value | +| :--- | :--- | +| Interface | RS232 | +| Baud rate | 115200 | +| Data/parity/stop | 8N1 | +| Flow control | None | + +See the [DVL A100/A250 serial protocol](dvl-a250_a100-serial-protocol.md#serial-protocol). diff --git a/docs/dvl/faq.md b/docs/dvl/faq.md index 4d2d88a0..30229a71 100644 --- a/docs/dvl/faq.md +++ b/docs/dvl/faq.md @@ -1,132 +1,343 @@ -# DVL FAQ +# FAQ -Below are some frequently asked questions about the DVL. Click on a question in the table of contents to the right or simply scroll down to read the FAQs. +This FAQ applies to DVL A50, DVL A100, DVL A125, and DVL A250 unless a question states otherwise. + +## 1. How do I access the web GUI? { #how-do-i-access-the-gui } + +Applies to: all DVL models + +Connect power and Ethernet, then open the DVL address in a web browser. Ethernet is recommended for first setup because it gives access to the web GUI, diagnostics, configuration, software updates, and the TCP data stream. + +See [Network setup](networking.md) for mDNS, fallback IP, direct Ethernet connection, and TCP data stream information. + +--- + +## 2. What should I check if I cannot connect to the web GUI? { #what-should-i-check-if-i-cannot-connect-to-the-gui } + +Applies to: all DVL models + +Check: + +* Power and LED status. +* Ethernet cable and connector condition. +* Computer network configuration. +* Whether mDNS is available on the network. +* The fallback IP address if mDNS does not resolve. +* Whether the DVL is in thermal shutdown. + +See [Network setup](networking.md), [DVL electrical connection](electrical.md), and [How to diagnose](how-to-diagnose.md). --- -## 1. Do I need to calibrate the IMU each time I power on the DVL? +## 3. Why does the DVL lose connection? { #why-does-the-dvl-lose-connection } + +Applies to: all DVL models -No. If you use the software version 2.4.5 or later, the calibration is saved in memory. +Common causes include insufficient power, poor cable or connector contact, thermal shutdown, and network configuration issues. + +Check [Network setup](networking.md), [DVL electrical connection](electrical.md), and [How to diagnose](how-to-diagnose.md). --- -## 2. Will the temperature affect the IMU? +## 4. Why does the DVL lose bottom lock? { #why-does-the-dvl-lose-bottom-lock } + +Applies to: all DVL models -Yes. The IMU will perform differently under temperatures that differ significantly from the conditions at which it was calibrated. +Bottom lock depends on altitude, bottom conditions, line of sight, acoustic noise, vehicle motion, and range mode. If bottom lock is lost, check that the bottom is within the selected range, all beams have a clear path, and the DVL is not operating in bubbles or disturbed water. + +See [Loss of bottom lock](how-to-diagnose.md#loss-of-bottom-lock) and [Installation](installation.md). --- -## 3. Why does the yaw angle change rapidly? +## 5. Why does the DVL velocity become invalid or drop to zero? { #why-does-the-dvl-velocity-become-invalid-or-drop-to-zero } + +Applies to: all DVL models -Yaw angle in the DVL GUI may increase or otherwise change rapidly if the DVL’s gyro has not been calibrated or temperature changes. -Please see the following for more on calibration: [Calibrate the IMU](dead-reckoning.md#starting-dead-reckoning) +Velocity can become invalid when the DVL cannot form a valid velocity estimate. Common causes include loss of bottom lock, wrong range mode for the current altitude, blocked beam paths, bubbles, vibration, acoustic interference, or operation outside the conditions where the DVL can track reliably. -!!! Note - If only the velocity output of the DVL is required, you can ignore changes in yaw angle. The yaw angle is only relevant (and thus calibration is needed) if the DVL’s dead reckoning functionality is used. +See [Invalid velocity](how-to-diagnose.md#invalid-velocity). --- -## 4. Can we test/operate the DVL in air? +## 6. How do I download a diagnostic log? { #how-do-i-download-diagnostics } -You will **not** be able to get valid velocity measurements in air. -It is possible to power the DVL out of the water for a short time, but the DVL warms up quickly. If possible, we recommend avoiding this. +Applies to: all DVL models -A great setup for lab work is to keep the DVL submerged in a small bucket of water. +Open the web GUI diagnostics or diagnostic log page, put the DVL in the same environment where the issue occurs, enter a short issue description, create the log, and download it. -We realize it may be impractical to avoid air usage altogether when the DVL is mounted. One option is to disable the DVL’s acoustics while it is out of water to reduce heating. This option is available under **Configuration** in the DVL GUI. +See [Diagnostic log](diagnostic-log.md) and [Download diagnostic log](how-to-diagnose.md#download-diagnostics). -!!! Note - If you do use the DVL in air, we strongly recommend running software version 2.0.8 or higher so the DVL can shut down safely if it overheats. See [FAQ #9](#9-can-the-dvl-overheat) for shutdown behavior. +--- + +## 7. What information should I send to Water Linked support? { #what-information-should-i-send-to-water-linked-support } + +Applies to: all DVL models + +Use the [Support package checklist](support-package-checklist.md). The most useful items are the diagnostic log, DVL model, serial number if available, software version, failure description, mounting description, installation photos, operating altitude, speed, range mode, tracking mode, environment, active acoustic instruments, and relevant web GUI screenshots. --- -## 5. What is the connector on the DVL? +## 8. How do I choose range mode? { #how-do-i-choose-range-mode } -The DVL A50/A125 is supplied with a cable tail that includes an interface board containing: +Applies to: all DVL models -- An Ethernet connector, allowing a direct plug-and-play link to your computer. -- A Micro-USB port (Revision 4 I/O card), enabling USB output. Simply plug a USB cable from the DVL to your computer. +Use automatic range mode unless you know that the DVL should only search within a limited altitude range. If bottom lock is unreliable, make sure the selected range mode includes the actual altitude. -Earlier revisions have a UART interface on the board, which can be soldered to for serial connections. +See [Range mode](range-mode.md). -The interface board can be removed for permanent mounting on a vehicle. Refer to the wiring interface documentation for setting up Ethernet and/or serial connections as needed. Water Linked does not provide a specific connector for this purpose. + --- -## 6. Can the DVL be used as an ADCP? +## 9. What is periodic cycling? { #what-is-periodic-cycling } -No. The DVL’s algorithms are specifically designed to track reflections from the seafloor. An ADCP requires measuring reflections from water-borne particles at various depths, which uses a different processing approach. +Applies to: all DVL models + +Periodic cycling is a setting that is enabled by default. Every 10 seconds, the DVL checks that the bottom it has locked onto is the actual bottom and that there are no closer reflections that should be treated as the real bottom. + +It is useful in reflective environments with many multipath reflections, such as tanks or pools. Some measurements are lost during the validation check. If you operate in open water with stable bottom conditions and need as many measurements as possible, consider turning periodic cycling off. + +See [Periodic cycling](configuration.md#periodic-cycling). --- -## 7. Why does the DVL lose connection? +## 10. What is the difference between bottom tracking and water tracking? { #what-is-the-difference-between-bottom-tracking-and-water-tracking } + +Applies to: model-specific -If you notice periodic data dropouts or lost connections, there are a few common causes to consider: +Bottom tracking estimates velocity relative to the seabed or another reflecting surface. Water tracking estimates velocity relative to the water column. -1. **Insufficient Power** +Water tracking can be useful when bottom lock is not available or when velocity relative to the water column is required. It should not be treated as bottom-relative velocity. - If the DVL is not receiving enough power, you may see periodic dropouts. +See [Water tracking](water-tracking.md). - - Try using a power supply with higher voltage/current (for instance, 18V at up to 2A or 24V at up to 1.5A). +--- -2. **Poor Physical Connection** +## 11. Can air bubbles affect DVL performance? { #can-air-bubbles-affect-dvl-performance } - - If the DVL was previously functioning but suddenly loses connection, inspect cables, connectors, and any terminations on the ROV or topside computer. +Applies to: all DVL models -3. **Thermal Shutdown** +Yes. Air bubbles can scatter or block the acoustic signal and cause weak signal, noisy measurements, invalid velocity, or loss of bottom lock. - - If the DVL overheats it will shut down and drop the link until it cools and restarts. See [FAQ #9](#9-can-the-dvl-overheat) for details on thresholds and restarts. +Check for bubbles from thrusters, propellers, pumps, hull turbulence, waves, or the DVL moving in and out of the water. See [Air bubbles](how-to-diagnose.md#air-bubbles) and [Installation](installation.md#thrusters-propellers-hulls-and-bubbles). --- -## 8. What is the Source level (dB re 1 μPa @ 1 m)? +## 12. Can thrusters or propellers affect DVL performance? { #can-thrusters-or-propellers-affect-dvl-performance } + +Applies to: all DVL models -The maximum transmit source level is 200 dB. +Yes. Thrusters, propellers, hull edges, pumps, and other moving water sources can create turbulence and bubbles in the beam paths. Compare DVL performance with thrusters or propellers off and on, and consider moving the DVL away from disturbed flow if performance changes. + +See [Thrusters, propellers, and hull turbulence](how-to-diagnose.md#thrusters-propellers-and-hull-turbulence). --- -## 9. Can the DVL overheat? +## 13. Can mechanical vibration affect DVL performance? { #can-mechanical-vibration-affect-dvl-performance } + +Applies to: all DVL models -Yes. The DVL has a thermal shutdown to avoid damage. It will issue a warning before shutting down at 55℃. Once it cools below 50℃, it automatically restarts. If the overheating issue is not addressed, it may repeat this shutdown/restart cycle. To avoid this always keep the DVL in water when powered on. +Yes. Loose brackets, flexible poles, or vibrating mounts can make measurements noisy because the DVL moves relative to the vehicle or boat. + +Use a rigid mount and check whether motors, pumps, or thrusters excite the bracket. See [Mechanical vibration and flexible mounts](how-to-diagnose.md#mechanical-vibration-and-flexible-mounts) and [Rigid mounting and vibration](installation.md#rigid-mounting-and-vibration). --- -## 10. What is the latency when using the API over Ethernet? +## 14. Can the DVL be used on a boat? { #can-the-dvl-be-used-on-a-boat } + +Applies to: all DVL models -When sending commands over TCP, the average latency is around 4 ms, with a standard deviation of 2 ms. The maximum observed latency is 13 ms. +Yes, but the installation should keep the DVL rigidly mounted, fully submerged, and away from aerated or turbulent flow. Verify bottom lock and velocity at the intended boat speed before relying on the data. + +See [Boat-mounted installations](how-to-diagnose.md#boat-mounted-installations) and [Boat-mounted use](installation.md#boat-mounted-use). --- -## 11. Does the DVL have an RS-232 interface? +## 15. How close to the water surface can the DVL be mounted? { #how-close-to-the-water-surface-can-the-dvl-be-mounted } + +Applies to: all DVL models -No. The DVL does **not** support RS-232. It only provides a TTL (3.3V) UART interface, which is inherently incompatible with RS-232. If RS-232 is required, you will need an external level converter. +The DVL should stay fully submerged during operation. Near the surface, waves, air ingestion, turbulence, and bubbles can affect the acoustic signal. Exact surface-clearance limits depend on the installation and operating conditions. + +See [Operation close to the water surface](how-to-diagnose.md#operation-close-to-the-water-surface) and [Operation close to the surface](installation.md#operation-close-to-the-surface). + +--- + +## 16. Can other acoustic instruments interfere with the DVL? { #can-other-acoustic-instruments-interfere-with-the-dvl } + +Applies to: all DVL models + +Yes. Other acoustic instruments can interfere if they transmit at overlapping times or create strong acoustic noise in the DVL operating environment. + +Test the DVL with the other instruments off, then on. If performance changes, consider physical separation, beam geometry, or trigger/synchronization. See [Active acoustic interference from other sensors](how-to-diagnose.md#active-acoustic-interference-from-other-sensors) and [Triggering and synchronization](integration.md#triggering-and-synchronization). --- -## 12. What is the velocity output frequency? +## 17. Which interface should I use: Ethernet, serial, PD0, PD4, or PD6? { #which-interface-should-i-use-ethernet-serial-pd0-pd4-or-pd6 } + +Applies to: all DVL models -The velocity output frequency varies with altitude. -- At lower altitudes (close to the seafloor), the DVL can reach an update frequency of **15 Hz**. -- At higher altitudes, it typically operates between **2–4 Hz**. +Use Ethernet and the web GUI for first setup, diagnostics, configuration, and testing. Use the Water Linked TCP JSON API over Ethernet for custom software integrations. Use the Water Linked serial protocol for direct vehicle integration over the serial interface. -For more details, see [Range mode](dvl-protocol.md#range-mode-configuration). In **Auto mode**, the DVL automatically selects the range mode it deems optimal. +Use PD4 or PD6 only when the receiving system already supports that format. PD0 is planned for DVL A100 and DVL A250, but is not available yet. + +See [Integration overview](integration.md), [PD formats](dvl-pd-formats.md), [DVL electrical connection](electrical.md), and the protocol pages for your model. --- -## 13. Will the DVL work over a soft seabed, such as sand? +## 18. Does the DVL have an RS232 interface? { #does-the-dvl-have-an-rs232-interface } + +Applies to: model-specific + +DVL A50 and DVL A125 do not use RS232. They use a 3.3 V UART electrical interface that is 5 V tolerant. + +DVL A100 and DVL A250 use RS232. -Yes, the DVL can operate over soft bottoms. However, softer seabeds absorb more acoustic energy, which reduces the maximum altitude at which the DVL can reliably track. The degree of range reduction varies from environment to environment and may require on-site testing to determine. +The serial data protocol is separate from the electrical interface. See [DVL electrical connection](electrical.md#terminal-serial-interface), [DVL A50/A125 serial protocol](dvl-serial-protocol.md), and [DVL A100/A250 serial protocol](dvl-a250_a100-serial-protocol.md). --- -## 14. I get an error when updating my DVL? +## 19. What is the latency when using the API over Ethernet? { #what-is-the-latency-when-using-the-api-over-ethernet } -Most likely your DVL is running an older software version that requires you to set the time before you can update. This is not and issue when updating from version 2.6.5 -For more software update details please see [DVL Software Updates.](sw-update.md) +Applies to: all DVL models + +In our measurements, TCP JSON message latency was typically around 4 ms average, with 2 ms standard deviation and an observed maximum of 13 ms. + +This is not a hard real-time guarantee. Actual latency can depend on network setup, host system, load, and integration method. + +See [Integration](integration.md#ethernet-jsontcp), [DVL A50/A125 TCP JSON API](dvl-json-protocol.md), and [DVL A100/A250 TCP JSON API](dvl-a250_a100-json-protocol.md). --- -## 15. How should I maintain the DVL? -After operating in seawater, brackish water, chlorinated pools, or any medium other than freshwater, rinse the DVL thoroughly with fresh water to remove residues and salt deposits. Once dry, wipe the exterior with a clean, dry cloth. Avoid solvents or abrasive cleaners. +## 20. How does triggering and synchronization work? { #how-does-triggering-and-synchronization-work } + +Applies to: model-specific + +Triggering lets an external system control DVL pinging. This can be useful when several acoustic instruments are installed on the same vehicle and should avoid transmitting at the same time. + +Triggering and synchronization are handled through the integration interface, not as a web GUI workflow. See [Integration overview](integration.md#triggering-and-synchronization) and the protocol page for your model. + + + +--- + +## 21. What is the operating range? { #what-is-the-operating-range } + +Applies to: all DVL models + +See [Overview](overview.md#dvl-comparison) for model comparison and [Range mode](range-mode.md) for range-mode configuration notes. + +--- + +## 22. What is the velocity output frequency? { #what-is-the-velocity-output-frequency } + +Applies to: all DVL models + +Velocity output frequency varies with altitude and range mode. See [Range mode](range-mode.md) for the common range-mode concept and model applicability notes. + + --- + +## 23. What is the source level or SPL? { #what-is-the-source-level-or-spl } + +Applies to: all DVL models + +See the product comparison table in [Overview](overview.md). The FAQ does not repeat these values so that specifications are maintained in one place. + + + +--- + +## 24. Can I test or operate the DVL in air? { #can-i-test-or-operate-the-dvl-in-air } + +Applies to: all DVL models + +You will not get valid velocity measurements in air. It is possible to power the DVL out of water for a short time, but it warms up quickly. If possible, keep the DVL submerged when powered. + +A practical lab setup is to keep the DVL submerged in a small bucket of water. + +If the DVL must be powered out of water for a short time, disable acoustics in the web GUI to reduce heating. + +--- + +## 25. Can the DVL overheat? { #can-the-dvl-overheat } + +Applies to: all DVL models + +Yes. The DVL has thermal shutdown to avoid damage. It issues a warning before shutting down at 55℃. Once it cools below 50℃, it automatically restarts. If the overheating issue is not addressed, it may repeat this shutdown/restart cycle. + +Keep the DVL in water when powered for normal operation. + +--- + +## 26. Do I need to calibrate the IMU each time I power on the DVL? { #do-i-need-to-calibrate-the-imu-each-time-i-power-on-the-dvl } + +Applies to: all DVL models + +No. The calibration is saved in memory. + +--- + +## 27. Will temperature affect the IMU? { #will-temperature-affect-the-imu } + +Applies to: all DVL models + +Yes. The IMU can perform differently under temperatures that differ significantly from the conditions where it was calibrated. + +--- + +## 28. Why does the yaw angle change rapidly? { #why-does-the-yaw-angle-change-rapidly } + +Applies to: all DVL models + +Yaw angle in the web GUI may increase or otherwise change rapidly if the gyro has not been calibrated or if the temperature changes. + +See: + +* [Dead reckoning](dead-reckoning.md#starting-dead-reckoning) + +!!! note + If only velocity output is required, you can ignore yaw drift. Yaw is only relevant if dead reckoning is used. + +--- + +## 29. Can the DVL be used as an ADCP? { #can-the-dvl-be-used-as-an-adcp } + +Applies to: all DVL models + +No. The DVL algorithms are designed to track reflections from the seafloor or another reflecting surface. An ADCP measures reflections from water-borne particles at various depths, which uses a different processing approach. + +--- + +## 30. Will the DVL work over a soft seabed, such as sand? { #will-the-dvl-work-over-a-soft-seabed-such-as-sand } + +Applies to: all DVL models + +Yes, the DVL can operate over soft bottoms. Softer seabeds can absorb more acoustic energy, which may reduce the maximum altitude where the DVL can reliably track. The effect varies by environment and may require testing. + +--- + +## 31. How do I update software or firmware? { #how-do-i-update-software-or-firmware } + +Applies to: all DVL models + +Use the common [Software updates](sw-update.md) page for all DVL models. + +--- + +## 32. Which DVL model should I choose? { #which-dvl-model-should-i-choose } + +Applies to: all DVL models + +Choose the DVL model based on required altitude range, platform size, depth rating, velocity range, physical interface, and integration requirements. + +See [Overview](overview.md#dvl-comparison) for the product comparison table and the model pages for mechanical details. + +--- + +## 33. How should I maintain the DVL? { #how-should-i-maintain-the-dvl } + +Applies to: all DVL models + +After operating in seawater, brackish water, chlorinated pools, or any medium other than freshwater, rinse the DVL thoroughly with fresh water to remove residues and salt deposits. Once dry, wipe the exterior with a clean, dry cloth. Avoid solvents or abrasive cleaners. diff --git a/docs/dvl/how-to-diagnose.md b/docs/dvl/how-to-diagnose.md new file mode 100644 index 00000000..d602d968 --- /dev/null +++ b/docs/dvl/how-to-diagnose.md @@ -0,0 +1,163 @@ +# How to diagnose + +This page applies to all our DVLs unless otherwise noted. + +Use this guide when the DVL is not performing as expected, cannot get bottom lock, reports invalid velocity, or produces noisy measurements. + +## Before contacting support + +1. Confirm that the DVL is powered and submerged. +2. Check the LED status: + * [LED signals](electrical.md#led-signals) +3. Check wiring and cable condition: + * [DVL electrical connection](electrical.md) + * [DVL A50/A125 serial interface](electrical.md#dvl-a50-and-dvl-a125-serial-interface) + * [DVL A100/A250 serial interface](electrical.md#dvl-a100-and-dvl-a250-serial-interface) +4. Open the web GUI: + * [DVL A50/A125 web GUI](dvl-a50_a125-gui.md) + * [DVL A100/A250 web GUI](dvl-a250_a100-gui.md) +5. Confirm that the software is up to date: + * [Software updates](sw-update.md) +6. Review [Installation](installation.md) for mounting, bubbles, vibration, and acoustic interference. +7. Use the [Support package checklist](support-package-checklist.md) before contacting Water Linked support. + +## Download diagnostic log { #download-diagnostics } + +Download a diagnostic log when bottom lock is unreliable, velocity is invalid, the web GUI reports warnings, or Water Linked support asks for one. + +Use the common [Diagnostic log](diagnostic-log.md) page for collection instructions and model-specific demo links. + +See the [Support package checklist](support-package-checklist.md) before contacting Water Linked support. + +## Invalid velocity + +Invalid velocity means the DVL does not currently have a valid velocity estimate. Check: + +* The DVL is submerged. +* Acoustics are enabled. +* The DVL has a clear line of sight to the seabed. +* The selected range mode includes the current altitude. +* The vehicle or boat speed is reasonable for the operating conditions. +* Bubbles, vibration, and acoustic interference are not affecting the measurement. + +If the DVL is in water tracking mode, remember that velocity is relative to the water column, not the bottom. See [Water tracking](water-tracking.md). + +## Loss of bottom lock + +Bottom lock depends on altitude, bottom conditions, beam paths, acoustic noise, and vehicle motion. + +If bottom lock is lost: + +1. Check that the bottom is within the operating range. +2. Check that range mode is not too restrictive. See [Range mode](range-mode.md). +3. Check that all beam paths are unobstructed. +4. Check for bubbles and turbulence. +5. Check for other active acoustic instruments. +6. Review [periodic cycling](configuration.md#periodic-cycling), especially in reflective tanks, pools, or open-water tests where every measurement matters. +7. Test in a simpler environment if possible. + +## Weak signal or noisy measurements + +Weak or noisy measurements can be caused by soft bottoms, acoustic reflections, bubbles, vibration, and other acoustic sources. + +Practical checks: + +* Compare signal quality with thrusters or motors off and on. +* Test away from tank walls, dock structures, or polished metal surfaces. +* Check whether transducer distances are stable and similar in a flat test area. +* Collect a diagnostic log while the issue is present. + +## Air bubbles + +Air bubbles can block or scatter the acoustic signal. + +Check for bubbles from: + +* Thrusters and propellers. +* Hull turbulence. +* Pumps and hoses. +* Waves or surface aeration. +* The DVL moving in and out of the water. + +If bubbles are present, try a calmer test condition or a mounting location with cleaner water flow. + +## Thrusters, propellers, and hull turbulence + +Thrusters, propellers, and hull edges can create turbulent or aerated water. This can reduce signal quality and cause invalid velocity. + +When testing: + +1. Check DVL output with thrusters or propellers stopped. +2. Check again at the expected operating speed. +3. If performance changes significantly, consider moving the DVL away from the turbulent flow. + +Do not assume a fixed safe distance; the required separation depends on the vehicle, speed, and water flow. + +## Mechanical vibration and flexible mounts + +The DVL should be mounted rigidly to the vehicle or boat. Flexible poles, loose brackets, or vibrating mounts can make measurements noisy. + +Check: + +* Fasteners are tight. +* The DVL cannot move relative to the vehicle. +* Poles or brackets do not visibly vibrate. +* Motors, pumps, or thrusters are not exciting the mount. + +## Operation close to the water surface + +Near the surface, waves and bubbles can affect acoustic measurements. The DVL should stay fully submerged during operation. + +Check: + +* Waves are not exposing the transducers to air. +* The DVL is not passing through surface bubbles. +* Boat pitch, roll, or heave is not making the beam paths unstable. + +## Boat-mounted installations + +For boat-mounted DVLs: + +* Use a rigid mount. +* Keep the DVL submerged at the expected operating speed. +* Avoid aerated flow from the hull or propeller. +* Check for vibration in the pole or bracket. +* Verify bottom lock and velocity at the intended speed before relying on the data. + +See [Installation](installation.md#boat-mounted-use). + +## Obstructed beam paths / line of sight + +The DVL needs a clear acoustic path from each transducer to the bottom. + +Check model-specific line-of-sight information: + +* [DVL A50 line of sight](dvl-a50.md#line-of-sight) +* [DVL A100 line of sight](dvl-a100.md#line-of-sight) +* [DVL A125 line of sight](dvl-a125.md#line-of-sight) +* [DVL A250 line of sight](dvl-a250.md#line-of-sight) + + + + +If one beam shows a different distance or flickers more than the others, check whether that beam is seeing a wall, frame, skid, cable, or other obstruction. + +## Active acoustic interference from other sensors + +Other acoustic instruments can interfere with DVL measurements, especially if they transmit at the same time. + +Check: + +1. Run the DVL with other acoustic instruments off. +2. Run the DVL with the other instruments on. +3. If performance changes, consider trigger or synchronization. See [Integration](integration.md#triggering-and-synchronization). + +## Thermal shutdown + +The DVL has a thermal shutdown mechanism to avoid damage. It issues a warning before shutting down at 55℃. Once it cools below 50℃, it automatically restarts. If the overheating issue is not addressed, it may repeat this shutdown/restart cycle. + +If thermal shutdown occurs, confirm that the DVL is submerged and that acoustics are disabled when the DVL must be powered out of water for a short time. + +## What to send to Water Linked support + +Submit a [support ticket](https://waterlinked.com/support) with the information listed in the [Support package checklist](support-package-checklist.md). diff --git a/docs/dvl/installation.md b/docs/dvl/installation.md new file mode 100644 index 00000000..6fe3024e --- /dev/null +++ b/docs/dvl/installation.md @@ -0,0 +1,122 @@ +# Installation + +This page gives common installation guidance for all our DVLs. Use it together with the mechanical and electrical page for your specific model. + +## Before installation + +1. Check that the DVL, cable, connector, and mounting hardware are undamaged. +2. Review the model-specific dimensions, mounting holes, and line-of-sight drawings. +3. Plan cable routing so the cable is protected from strain, sharp bends, and moving parts. +4. Confirm the electrical interface for your model: + * [DVL electrical connection](electrical.md) + * [DVL A50/A125 serial interface](electrical.md#dvl-a50-and-dvl-a125-serial-interface) + * [DVL A100/A250 serial interface](electrical.md#dvl-a100-and-dvl-a250-serial-interface) + +## Clear line of sight + +The DVL needs a clear acoustic path from each transducer to the seabed or other reflecting surface. + +When mounting the DVL: + +* Keep all beam paths free from brackets, vehicle frames, payloads, hulls, skids, and cables. +* Make sure the DVL is not looking into a wall, tank side, or nearby structure during testing. +* Check the web GUI or protocol output to see whether the transducers report similar and reasonable distances in a flat test area. + +See the model pages for line-of-sight drawings: + +* [DVL A50 line of sight](dvl-a50.md#line-of-sight) +* [DVL A100 line of sight](dvl-a100.md#line-of-sight) +* [DVL A125 line of sight](dvl-a125.md#line-of-sight) +* [DVL A250 line of sight](dvl-a250.md#line-of-sight) + + + + +## Mounting orientation + +Velocity and dead reckoning output use the configured vehicle frame. If the DVL is not mounted with its forward direction aligned with the vehicle forward direction, configure the mounting rotation offset. + +See [Axes](axes.md) for the common DVL axis convention and mounting rotation offset. + +!!! warning + Incorrect mounting rotation can make valid DVL data appear to point in the wrong direction. + +## Rigid mounting and vibration + +Use a rigid mount so the DVL moves with the vehicle or boat. Avoid flexible poles, long unsupported brackets, loose fasteners, or mounts that can vibrate. + +Mechanical vibration can make the velocity estimate noisy or unstable. If measurements look noisy: + +1. Check that the DVL cannot move relative to the vehicle. +2. Check for loose fasteners or flexing brackets. +3. Compare measurements with thrusters or motors off and on. + +## Thrusters, propellers, hulls, and bubbles + +Air bubbles and turbulent flow can reduce signal quality and cause invalid velocity or loss of bottom lock. + +When possible: + +* Mount the DVL away from strong turbulence from thrusters, propellers, pumps, and hull edges. +* Avoid positions where bubbles pass across the transducers. +* Avoid mounting directly behind a propeller or thruster wash. +* Consider the vehicle direction of travel and where bubbles will move during operation. + +No strict minimum distance is specified here because it depends on the vehicle, speed, water flow, and installation. + +## Boat-mounted use + +For boat-mounted installations, consider flow and bubbles around the hull: + +* Avoid mounting where the hull creates strong aerated flow. +* Avoid locations that come out of the water in waves or when the boat pitches and rolls. +* Use a rigid pole or bracket that does not vibrate. +* Keep the DVL submerged and stable during measurements. +* Check bottom lock at the expected boat speed before relying on the data. + +## Operation close to the surface + +Operation close to the water surface can be affected by bubbles, waves, and changing submersion. Keep the DVL fully submerged and avoid positions where waves or vehicle motion expose the transducers to air. + +If the DVL loses bottom lock near the surface, check for: + +* Bubbles passing across the transducers. +* Waves causing pitch and roll. +* The DVL or mounting bracket moving relative to the vehicle. +* Beam paths that intersect the hull, dock, tank wall, or other nearby structures. + +## Other acoustic instruments + +Other acoustic instruments can interfere with DVL measurements if they transmit at the same time or in a similar frequency range. + +If several acoustic instruments are used together: + +1. Test each instrument by itself first. +2. Check DVL performance with the other instruments active. +3. Use trigger or synchronization options when needed. See [Integration](integration.md#triggering-and-synchronization). + +## Grounding, power, and cable considerations + +Follow the electrical page for your model: + +* [DVL electrical connection](electrical.md) +* [DVL A50/A125 serial interface](electrical.md#dvl-a50-and-dvl-a125-serial-interface) +* [DVL A100/A250 serial interface](electrical.md#dvl-a100-and-dvl-a250-serial-interface) + +General checks: + +* Use an adequate power supply for the model. +* Protect the cable from strain and abrasion. +* Keep power and communication wiring away from high-noise wiring when practical. +* Follow the shield grounding guidance in the electrical documentation. + +## First water test + +1. Keep the DVL submerged before powering it for normal operation. +2. Open the web GUI and check that the DVL is connected. +3. Confirm that acoustics are enabled. +4. Check that the DVL gets bottom lock in a simple test environment. +5. Check velocity, altitude, and transducer distances. +6. If the output looks wrong, verify mounting rotation, range mode, line of sight, bubbles, vibration, and acoustic interference. + +See [How to diagnose](how-to-diagnose.md) if the DVL does not behave as expected. diff --git a/docs/dvl/integration.md b/docs/dvl/integration.md new file mode 100644 index 00000000..c5a8d0af --- /dev/null +++ b/docs/dvl/integration.md @@ -0,0 +1,85 @@ +# Integration + +This page helps you choose an interface for integrating our DVLs into a vehicle, boat, or control system. + +## Choose an interface + +| Use case | Recommended interface | +| --- | --- | +| First setup, diagnostics, configuration, and testing | Ethernet and the web GUI | +| Custom software integration over Ethernet | TCP JSON API | +| Direct vehicle integration over serial | Water Linked serial protocol | +| Existing systems with PD0, PD4, or PD6 support | PD formats | +| Multiple acoustic instruments | Triggering and synchronization | + +## TCP JSON API { #ethernet-jsontcp } + +Use the TCP JSON API when you want a network data stream, command interface, and easy access from custom software. In customer-facing documentation, Water Linked API refers to this TCP JSON API. + +The DVL TCP server is available on port `16171`. See [Network Setup](networking.md#tcp-data-stream). + +In our measurements, TCP JSON message latency was typically around 4 ms average, with 2 ms standard deviation and an observed maximum of 13 ms. This is not a hard real-time guarantee; actual latency can depend on network setup, host system, load, and integration method. + +Protocol references: + +* [DVL A50/A125 TCP JSON API](dvl-json-protocol.md) +* [DVL A100/A250 TCP JSON API](dvl-a250_a100-json-protocol.md) + +## Serial Water Linked protocol + +Use the Water Linked serial protocol when the vehicle controller expects a direct serial data stream. + +Electrical interfaces differ by model: + +* DVL A50 and DVL A125 use the same UART electrical interface. See [DVL A50/A125 serial interface](electrical.md#dvl-a50-and-dvl-a125-serial-interface). +* DVL A100 and DVL A250 use RS232. See [DVL A100/A250 serial interface](electrical.md#dvl-a100-and-dvl-a250-serial-interface). + +Protocol references: + +* [DVL A50/A125 serial protocol](dvl-serial-protocol.md) +* [DVL A100/A250 serial protocol](dvl-a250_a100-serial-protocol.md) + +## PD formats { #pd0-pd4-and-pd6 } + +Use PD formats only when the receiving system already supports PD0, PD4, or PD6. This can reduce integration work when replacing or adding a DVL to an existing system. + +PD4 and PD6 are supported over TCP and serial for all DVL models. PD0 is planned for DVL A100 and DVL A250, but is not available yet. + +Protocol references: + +* [PD formats](dvl-pd-formats.md) +* [PD6 format](dvl-pd-formats.md#pd6-protocol-tcpserial) +* [PD4 format](dvl-pd-formats.md#pd4-protocol-tcpserial) +* [PD0 status](dvl-pd-formats.md#pd0-protocol) + +## Triggering and synchronization + +Triggering can be useful when the DVL operates near other acoustic instruments and you want to avoid simultaneous acoustic transmissions. + +Triggering and synchronization are handled through protocol or electrical interfaces, not through the web GUI. + +### TCP JSON API or serial command trigger + +The DVL can queue externally requested pings when acoustic pinging is controlled by command. + +See: + +* [DVL A50/A125 TCP JSON API trigger ping](dvl-json-protocol.md#trigger-ping) +* [DVL A50/A125 serial trigger ping](dvl-serial-protocol.md#trigger-ping-wcx) +* [DVL A100/A250 TCP JSON API trigger ping](dvl-a250_a100-json-protocol.md#trigger-ping) +* [DVL A100/A250 serial trigger ping](dvl-a250_a100-serial-protocol.md#trigger-ping-wcx) + +### RX-line trigger + +For DVL A100 and DVL A250, sending a NULL character over the RS232 RX line triggers a pulse on the falling edge. + + + +## Diagnostics during integration + +If the integration does not behave as expected, collect a diagnostic log from the web GUI and include the integration interface in the support request. + +See: + +* [DVL diagnostic log](diagnostic-log.md) +* [How to diagnose](how-to-diagnose.md) diff --git a/docs/dvl/networking.md b/docs/dvl/networking.md index f24bd6fa..e700030a 100644 --- a/docs/dvl/networking.md +++ b/docs/dvl/networking.md @@ -1,42 +1,61 @@ -# Networking +# Network Setup -The DVL has several services available over ethernet: +The DVL has several services available over Ethernet: * [Multicast DNS](#multicast-dns-mdns) (mDNS) for easy discovery -* Web [GUI](../dvl/gui/dashboard.md), providing a visualisation of the data outputted by the DVL, as well as configuration, [updating of software](sw-update.md), diagnostics, and more. -* TCP [data stream](#tcp-data-stream) +* Web GUI for live data, configuration, diagnostics, and software updates +* [TCP data stream](#tcp-data-stream) * [Software updates](sw-update.md) +Use Ethernet for first setup whenever possible. It gives access to the web GUI, diagnostics, configuration, software updates, and the TCP data stream. + ## Network configuration ### Multicast DNS (mDNS) -The DVL runs a DHCP client which will attempt to obtain an IP address from a DHCP server (e.g. in a router) on the same network, and supports mDNS: the mDNS name of the DVL is `waterlinked-dvl`. On a computer which supports mDNS, one can then simply access the web [GUI](../dvl/gui/dashboard.md) at [http://waterlinked-dvl](http://waterlinked-dvl). +The DVL runs a DHCP client which attempts to obtain an IP address from a DHCP server on the same network, such as a router. + +The DVL also supports mDNS. On a computer that supports mDNS, open the web GUI at: + +```text +http://waterlinked-dvl +``` !!! note - If no DHCP server is available on the network, it is recommended to use the [fallback IP](#fallback-ip) or configure a [static IP address](#via-the-gui), as the DVL can spend up to 5 minutes searching for a DHCP server. + If no DHCP server is available on the network, use the [fallback IP](#fallback-ip) or configure a [static IP address](#via-the-gui). The DVL can spend up to 5 minutes searching for a DHCP server. ### Fallback IP -The DVL will always be available with the static IP address: **192.168.194.95**. To be able to connect to the DVL using it: +The DVL is always available with the static fallback IP address: + +```text +192.168.194.95 +``` -* Connect an ethernet cable directly from the DVL to your computer. -* For an/the ethernet interface of your computer, configure it to have a static IP address in the same subnet as 192.168.194.95, e.g. 192.168.194.90 or anything else of the form 192.168.194.xxx if using a subnet of the form 255.255.255.0 (aka 192.168.194.0/24). -* Activate the ethernet interface of your computer which you configured in the previous step. -* In a web browser, open http://192.168.194.95 to access the web [GUI](../dvl/gui/dashboard.md). +To connect using the fallback IP: -### Via the GUI +1. Connect an Ethernet cable directly from the DVL to your computer. +2. Configure the computer Ethernet interface with a static IP address in the same subnet, for example `192.168.194.90` with subnet mask `255.255.255.0`. +3. Activate the Ethernet interface. +4. Open `http://192.168.194.95` in a web browser. -The IP address of the DVL can be configured in two ways via the web [GUI](../dvl/gui/dashboard.md): +### Via the web GUI { #via-the-gui } -* DCHP client: an IP address is obtained from a DHCP server (e.g. in a router) on the same network, as in the discussion of [mDNS](#multicast-dns-mdns) above. -* Static: equip the DVL with a certain static IP address. +The DVL IP configuration can be changed in the web GUI: -After the IP configuration of the DVL is modified, the DVL needs to be rebooted for the settings take effect. +* DHCP client: the DVL obtains an IP address from a DHCP server on the network. +* Static IP: the DVL uses a configured static IP address. -!!! Note - The boot time, i.e. the time it takes from the DVL receives power until it starts operating normally, will depend upon the IP configuration. Using the [fallback IP](#fallback-ip), the boot time can be as much as 1 min 30 sec, whilst it can be as low as 20 sec with a static IP. +After changing the IP configuration, reboot the DVL for the settings to take effect. + +!!! note + Boot time depends on IP configuration. Using the fallback IP, boot time can be as much as 1 min 30 sec. With static IP, it can be as low as 20 sec. ## TCP data stream -The DVL can output data and receive commands over Transmission Control Protocol (TCP). A TCP server is available on port **16171** which outputs the latest data to all connected clients, and which listens to commands from any of these connected clients. See the DVL's TCP [protocol](../dvl/dvl-protocol.md#json-protocol-tcp). +The DVL can output data and receive commands over Transmission Control Protocol (TCP). A TCP server is available on port **16171**. It outputs the latest data to connected clients and listens for commands from connected clients. + +See the DVL TCP JSON API for: + +* [DVL A50/A125 TCP JSON API](dvl-json-protocol.md#json-protocol-tcp) +* [DVL A100/A250 TCP JSON API](dvl-a250_a100-json-protocol.md#json-protocol-tcp) diff --git a/docs/dvl/overview.md b/docs/dvl/overview.md new file mode 100644 index 00000000..b9302fbd --- /dev/null +++ b/docs/dvl/overview.md @@ -0,0 +1,93 @@ +# Overview +At Water Linked we pride ourselves on building the Worlds smallest DVLs in their respective categories. Our DVLs combine everything that is important in the smallest possible formfactor: Prize and Performance! + +## What is a DVL? +A DVL estimates velocity relative to the seafloor by sending acoustic waves from four angled transducers and measuring the frequency shift (Doppler effect) of the returned echoes. By combining measurements from all four transducers over time, the DVL can accurately estimate both the speed and direction of movement. + +![dvl_a50](../img/WL-21035-3_DVL-A50_Side4_1600_crop.jpg) + +## DVL comparison + +Here is a quick overview of the differences between the DVL models: + +| Feature | DVL A50 | DVL A100* | DVL A125 | DVL A250 | +| :--- | :--- | :--- | :--- | :--- | +| **Altitude range**** | 5 cm to 50 m |5 cm to 100 m | 5 cm to 125 m| 30 cm to 250 m | +| **Maximum velocity** | 5 m/s | 5 m/s | 15 m/s | 15 m/s | +| **Frequency** | 1 MHz | 625 kHz | 420 kHz | 250 kHz | +| **Water tracking** | Yes | Planned | Yes | Planned | +| **Diameter / height** | 66 mm / 25 mm | 90 mm / 34 mm | 125 mm / 30 mm | 149 mm / 40 mm | +| **Weight in air / water** | 170 g / 105 g | 200 g / 125 g | 750 g / 500 g | 1650 g / 750 g | +| **Power consumption** | 4 W (average) | 8 W (average) | 4 W (average) | 8 W (average) | +| **Serial protocol** | UART TTL (3.3 V, 5 V tolerant) | RS232 | UART TTL (3.3 V, 5 V tolerant) | RS232 | +| **IMU output** | No | Planned | No | Planned | +| **Ping triggering** | Software | Soft- and Hardware | Software | Soft- and Hardware | +| **Cable entry** | Side entry | Side entry or rear O-ring interface | Side entry | Side entry or rear O-ring interface | +| **Communication** | Ethernet and UART TTL | Ethernet and serial RS232 | Ethernet and UART TTL | Ethernet and serial RS232 | +| **Source level (dB re 1 μPa @ 1 m)** | 200 | | 209 | | +| **Depth rating** | 300 m or 600 m| 1000 m | 1000 m or 4000 m| 4000 m for side-entry cable configuration; rear O-ring interface version rated to 1000 m | +| **Main use case** | Compact platforms where size and payload capacity are limited and operations are conducted close to the bottom | Compact platforms where size and payload capacity are limited but require more range than the A50 | Long-range and deep-water subsea operations in high-pressure environments | Long-range and deep-water subsea operations where large operating altitudes are required | + +*Coming Q4 2026 + +**Under ideal conditions + + + + + + + + + +## A50 + +* [DVL A50 Documentation & Installation](dvl-a50.md) + +The [DVL A50](dvl-a50.md) is one of the world's smallest commercially available Doppler Velocity Logs. + +The A50 established a new market standard with its high performance, ultra-small 4-beam setup, open interface protocol, and low cost. + +## A100 + +* [DVL A100 Documentation & Installation](dvl-a100.md) + +The [DVL A100](dvl-a100.md) is a compact, high-accuracy Doppler Velocity Log for lightweight and integration-friendly platforms. + +The A100 supports close-range and mid-range operation up to 100 m altitude and shares web GUI, configuration, electrical, protocol, and integration documentation with the DVL A250 where behavior is identical. + +## A125 + +* [DVL A125 Documentation & Installation](dvl-a125.md) + +The [DVL A125](dvl-a125.md) is the next step up from the [DVL A50](dvl-a50.md), providing better performance at greater distances while still keeping a small form factor relative to competing DVLs. + +The DVL A125 builds on the DVL A50 with increased performance, a small 4-beam setup, an open interface protocol, and mid-to-low cost. + +## A250 + +* [DVL A250 Documentation & Installation](dvl-a250.md) + +The [DVL A250](dvl-a250.md) is the most capable DVL in the lineup, delivering long-range performance while maintaining a compact and efficient design. + +Operating at lower frequency for extended reach, the A250 enables reliable velocity measurements at distances up to 250 m, making it suitable for demanding subsea operations. + +The DVL A250 combines high performance, a compact 4-beam setup, open interface protocol, and a competitive cost, making it a powerful solution for larger vehicles and deep-water applications. diff --git a/docs/dvl/quickstart.md b/docs/dvl/quickstart.md new file mode 100644 index 00000000..476daa1b --- /dev/null +++ b/docs/dvl/quickstart.md @@ -0,0 +1,57 @@ +# Quickstart guide + +This guide helps you connect and access the GUI for all DVLs. + +## 1. Unbox and inspect + +Check that the DVL, cable, and any interface hardware are undamaged. + +## 2. Keep the DVL in water + +The DVL should be submerged before it is powered. This prevents overheating and is required for valid velocity measurements. + +!!! tip + Keep the DVL in a bucket of water when using it on a workbench. + +## 3. Mount the DVL + +Secure the DVL to your vehicle using the mounting holes and make sure the transducers have a clear line of sight to the bottom. + +See [Installation](installation.md) for common guidance on orientation, line of sight, vibration, bubbles, turbulence, and boat-mounted use cases. + +| Model | Mounting and dimensions | +| :--- | :--- | +| DVL A50 | [DVL A50](dvl-a50.md) | +| DVL A100 | [DVL A100](dvl-a100.md#dimensions) | +| DVL A125 | [DVL A125](dvl-a125.md) | +| DVL A250 | [DVL A250](dvl-a250.md#dimensions) | + +## 4. Connect power and Ethernet + +Wire the DVL according to the correct electrical interface for your model, then connect Ethernet to your computer or network. Ethernet is the recommended interface for first setup because it gives access to the web GUI, diagnostics, configuration, software updates, and the TCP data stream. + +Serial is available for vehicle integrations where a direct serial data stream is required. + +| Model | Electrical interface | Recommended interface | Optional serial interface | +| :--- | :--- | :--- | :--- | +| DVL A50 | [Electrical connection](electrical.md) | Ethernet | UART TTL | +| DVL A100 | [Electrical connection](electrical.md) | Ethernet | RS232 | +| DVL A125 | [Electrical connection](electrical.md) | Ethernet | UART TTL | +| DVL A250 | [Electrical connection](electrical.md) | Ethernet | RS232 | + +## 5. Configure network + +Configure your computer to reach the DVL over Ethernet. See [Network Setup](networking.md) for mDNS, fallback IP, static IP, and TCP information. + +## 6. Access the web GUI + +Open the DVL web GUI in a web browser. + +| Model | Web GUI documentation | +| :--- | :--- | +| DVL A50/A125 | [web GUI](dvl-a50_a125-gui.md) | +| DVL A100/A250 | [web GUI](dvl-a250_a100-gui.md) | + +## 7. Need help? + +Check out [How to diagnose](how-to-diagnose.md) and [FAQ](faq.md). diff --git a/docs/dvl/range-mode.md b/docs/dvl/range-mode.md new file mode 100644 index 00000000..cf922b5a --- /dev/null +++ b/docs/dvl/range-mode.md @@ -0,0 +1,53 @@ +# Range mode + +Range mode configuration can instruct the DVL to search for bottom lock in a limited altitude range. This can improve performance when the expected minimum and maximum altitude are known, for example in a river, pool, tank, or other constrained environment. + +## Model applicability + +The range-mode concept applies to all DVLs. The table below documents the currently published A50/A125 range modes. + + + +On supported models, the same configuration parameter can also enable [water tracking](water-tracking.md). + +## Configuration format + +| Range specifier | Behavior | +| -- | -- | +| `auto` | The DVL searches for bottom lock in its full operational area. This is the default. | +| `=a` | The DVL is locked to range mode `a`, where `a` is a number from `0` to `4`. | +| `a<=b`| The DVL searches for bottom lock from range mode `a` through range mode `b`. | +| `wt` | Enable water tracking on supported software and models. See [Water tracking](water-tracking.md). (Only A50/A125)| + +## DVL A50/A125/A100 range modes + +| Range mode | Lower altitude (m) | Upper altitude (m) | Update rate per second (Hz) | +| -- | -- | -- | -- | +| 0 | 0.05 | 0.6 | 15 | +| 1 | 0.3 | 3.0 | 10 | +| 2 | 1.5 | 14 | 5 - 6 | +| 3 | 7.7 | 36 | 7 - 8 | +| 4 | 15 | max | 2 - 4 | +| wt | 1.5 | 4.5 | 2 | + + + +## DVL A250 range modes + + +| Range mode | Lower altitude (m) | Upper altitude (m) | Update rate per second (Hz) | +| -- | -- | -- | -- | +| 0 | 0.3 | 3.0 | 10 | +| 1 | 1.5 | 14 | 5 - 6 | +| 2 | 7.7 | 72 | 7 - 8 | +| 3 | 15 | max | 2 - 4 | + +## Set with TCP JSON API or serial protocol + +### TCP JSON API +* [DVL A50/A125 TCP JSON API configuration](dvl-json-protocol.md#configuration-over-json) +* [DVL A100/A250 TCP JSON API configuration](dvl-a250_a100-json-protocol.md#configuration-over-json) + +### Serial +* [DVL A50/A125 serial configuration](dvl-serial-protocol.md#setting-configuration-parameters) +* [DVL A100/A250 serial configuration](dvl-a250_a100-serial-protocol.md#setting-configuration-parameters) diff --git a/docs/dvl/software-resources.md b/docs/dvl/software-resources.md new file mode 100644 index 00000000..61c33118 --- /dev/null +++ b/docs/dvl/software-resources.md @@ -0,0 +1,48 @@ +# Software resources + +This page lists Water Linked software resources that may be useful when integrating DVL products. + +## GitHub organization + +Water Linked publishes software examples, tools, and integration resources on GitHub: + +https://github.com/waterlinked + +The repositories below were identified from the Water Linked GitHub organization and checked against repository descriptions or README files on 2026-05-07. Repository availability, names, and APIs may change over time. Check each repository README before using it in an integration. + +## DVL software repositories + +| Repository | Description | Typical use | Maintained | +| --- | --- | --- | --- | +| [waterlinked_dvl](https://github.com/waterlinked/waterlinked_dvl) | C++ library and ROS 2 driver for Water Linked DVL devices, including DVL A50 and DVL A125. | ROS 2 integration, C++ integration, and starting from the included library examples. | Yes | +| [dvl-python](https://github.com/waterlinked/dvl-python) | Example code for working with the Water Linked DVL serial protocol and TCP JSON API. | Legacy Python examples for reading DVL protocol data over serial or TCP. Use together with the current protocol documentation. | No | +| [dvl-a50-ros-driver](https://github.com/waterlinked/dvl-a50-ros-driver) | Archived ROS 1 package for the Water Linked DVL A50. | Legacy ROS 1 integrations that still depend on the original DVL A50 driver. | No | + +## Examples and integration helpers + +Use these repositories as starting points when you need code-level integration examples: + +* [waterlinked_dvl](https://github.com/waterlinked/waterlinked_dvl) for ROS 2 and C++ projects using DVL A50 or DVL A125. +* [dvl-python](https://github.com/waterlinked/dvl-python) for legacy Python examples using the DVL serial protocol and TCP JSON API. +* [dvl-a50-ros-driver](https://github.com/waterlinked/dvl-a50-ros-driver) for legacy ROS 1 projects using DVL A50. + +Where a repository README states model support, use that scope as the source of truth. For other DVL models or custom integrations, use the protocol documentation and the integration guide linked below. + + +## Related resources + +* [DVL integration guide](integration.md) +* [DVL A50/A125 TCP JSON API](dvl-json-protocol.md) +* [DVL A100/A250 TCP JSON API](dvl-a250_a100-json-protocol.md) +* [DVL A50/A125 serial protocol](dvl-serial-protocol.md) +* [DVL A100/A250 serial protocol](dvl-a250_a100-serial-protocol.md) +* [PD formats](dvl-pd-formats.md) +* [PD integration overview](integration.md#pd0-pd4-and-pd6) +* [Electrical connection](electrical.md) +* [Network setup](networking.md) +* [DVL diagnostic log](diagnostic-log.md) +* [How to diagnose](how-to-diagnose.md) + +## Notes + +Software repositories are provided as integration aids. They may not cover every DVL model, software version, or customer platform. For production integrations, verify behavior against the current DVL protocol documentation and the README in the repository you plan to use. diff --git a/docs/dvl/support-package-checklist.md b/docs/dvl/support-package-checklist.md new file mode 100644 index 00000000..28763f85 --- /dev/null +++ b/docs/dvl/support-package-checklist.md @@ -0,0 +1,46 @@ +# Support package checklist + +Use this checklist before contacting Water Linked support about bottom lock, invalid velocity, noisy measurements, connection issues, or integration problems. + +The diagnostic log is most useful when it is recorded in the same setup and environment where the issue happens. + +## Before contacting support + +1. Check the relevant symptom in [How to diagnose](how-to-diagnose.md). +2. Open the web GUI and look for changes on the diagnostics or status page while the issue is happening. +3. If possible, compare with another DVL of the same type, another vehicle, or a simpler test setup. +4. If the issue only happens in one vehicle or environment, collect one diagnostic log when the DVL works as expected and one when the issue is visible. +5. Review [Installation](installation.md) for mounting, bubbles, vibration, line of sight, and acoustic interference. + +!!! note + Many DVL issues are caused by the installation, vehicle, or acoustic environment. A support package helps Water Linked separate DVL behavior from vehicle and environment effects. + +## Download diagnostic log + +Use the common [Diagnostic log](diagnostic-log.md) page for collection instructions and model-specific demo links. + +Keep the generated file and include it with the support request. + +## Include in the support request + +Include as much of this information as possible: + +* DVL model. +* Serial number, if available. +* Software/firmware version. +* Diagnostic log from the web GUI. +* Description of the problem and when it happens. +* Description of how the DVL is mounted. +* Photos of the DVL and the installation. +* Operating altitude or range to seabed. +* Vehicle or boat speed. +* Range mode and tracking mode. +* Environment description, such as pool, tank, harbor, river, lake, or open sea. +* Whether thrusters, propellers, pumps, motors, echo sounders, sonars, modems, or other acoustic instruments were active. +* Screenshots from the web GUI if they show status, warnings, invalid velocity, or bottom-lock behavior. + +## If the issue may need service + +Start by collecting diagnostics and sending the support package to Water Linked through the [support page](https://waterlinked.com/support). Water Linked support may ask for additional checks before deciding the next step. + +Do not send the DVL for service until Water Linked support has reviewed the issue and asked for the next action. diff --git a/docs/dvl/sw-update.md b/docs/dvl/sw-update.md index c6bfdd8d..bbb27731 100644 --- a/docs/dvl/sw-update.md +++ b/docs/dvl/sw-update.md @@ -1,41 +1,45 @@ # Software updates -It is recommended to always run the latest DVL software where possible. The latest software can be obtained [automatically](#automatic-software-update) or [manually](#offline-software-update). +We recommend running the latest DVL software where possible. Software updates are done from the web GUI **About** page. The latest software can be obtained [automatically](#automatic-software-update) or [manually](#offline-software-update). -The release notes for each release is available in the [GUI](../dvl/gui/dashboard.md) and also in the [GUI demo](https://dvl.demo.waterlinked.com/#/about). +The release notes for each release are available in the web GUI **About** page. You can also view the public demo About pages: -!!! Warning - During the software upgrade, the thermal protection feature is turned off. To prevent the DVL from overheating, it is important to submerge the DVL in water throughout the update process. - - If the DVL is switched off during an upgrade it might be permanently damaged.” +* [DVL A50/A125 About page](https://dvl.demo.waterlinked.com/#/about) +* [DVL A100/A250 About page](https://dvl2.demo.waterlinked.com/#about) +!!! warning + During the software update, the thermal protection feature is turned off. To prevent the DVL from overheating, keep the DVL submerged in water throughout the update process. + + If the DVL is switched off during an update, it might be permanently damaged. ## Automatic software update -The DVL's [GUI](../dvl/gui/dashboard.md) automatically checks and indicates if a new software version is available. +The DVL web GUI automatically checks and indicates if a new software version is available from the **About** page. -* Connect the DVL over ethernet to a network connected to the internet. If on a personal computer, it may be necessary to make a network bridge between a network interface (such as wifi) which has access to the internet and the ethernet interface through which the DVL is connected. -* Go to http://[IP_ADDRESS_OF_THE_DVL]:9000 in a web browser. -* The GUI will automatically check if there is a new version available, and if so, initiate installation of it with a single click. +* Connect the DVL over Ethernet to a network connected to the internet. If you use a personal computer, it may be necessary to make a network bridge between a network interface with internet access, such as Wi-Fi, and the Ethernet interface connected to the DVL. +* Open the DVL web GUI in a web browser. +* Go to the **About** page. +* If a new version is available, start the software update from the **About** page. ## Offline software update -If it is not possible to connect the DVL to the internet, one can proceed as follows. +If it is not possible to connect the DVL to the internet, use an offline software update. -* Find the current version and chip ID of the DVL at *Menu -> About* in the [GUI](../dvl/gui/dashboard.md). +* Find the current version and chip ID of the DVL on the **About** page in the web GUI. * Manually download an update package (`.wlup`) from the [update server](https://update.waterlinked.com/) using the chip ID. -* Verify if the downloaded version is newer than the currently running version. -* Set system time as shown below. -* Navigate to http://[IP_ADDRESS_OF_THE_DVL]:9000 in a web browser. -* Select 'Manual upload' and then upload the downloaded `.wlup` file. - -### Failure during upgrade (set system time) - -When performing an offline software upgrade it the following error might occur: `Failed: Error upgrading: resize: non-zero exit code: exit status 1`. This error is resolved by setting the system time before performing an upgrade. Proceed as follows. - -* Go to DVL GUI and click on "Configuration" in left menu -* Open "Advanced configuration" menu -* Scroll to "System time configuration" -* Select "Manual time" in "System time source" and click "Set manual time" -* Click on "About" in left menu and click "Software upgrade" -* Perform upgrade again +* Verify whether the downloaded version is newer than the currently running version. +* Set the system time as described below. +* Open the DVL web GUI in a web browser. +* Go to the **About** page. +* Select **Manual upload** and then upload the downloaded `.wlup` file. + +### Failure during update (set system time) + +When performing an offline software update, the following error might occur: `Failed: Error upgrading: resize: non-zero exit code: exit status 1`. This error is resolved by setting the system time before performing an update. + +* Go to the DVL web GUI and click **Configuration** or **Settings** in the left menu. +* Open the **Advanced configuration** menu. +* Scroll to **System time configuration**. +* Select **Manual time** in **System time source** and click **Set manual time**. +* Click **About** in the left menu and click **Software upgrade**. +* Perform the update again. diff --git a/docs/dvl/water-tracking.md b/docs/dvl/water-tracking.md new file mode 100644 index 00000000..a5d19ec8 --- /dev/null +++ b/docs/dvl/water-tracking.md @@ -0,0 +1,89 @@ +# Water Tracking + +Water tracking is a mode where the DVL estimates velocity relative to the water column instead of the sea bottom. It can be useful when the DVL cannot get bottom lock, or when the movement of the water itself is relevant. + +## Supported models + +| Model | Water tracking | +| :--- | :--- | +| DVL A50 | Supported | +| DVL A100 | Planned, not available yet | +| DVL A125 | Supported | +| DVL A250 | Planned, not available yet | + +Water tracking requires a software version with water tracking support. See [Software updates](sw-update.md) for update instructions. For DVL A100 and DVL A250, water tracking is planned but not available yet. + +## Mode of operation + +Water tracking uses acoustic reflections from the water column, approximately `1.5 m to 4.5 m` below the DVL. It is intended for use when the distance to the bottom is more than 4.5 m. + +When the bottom is within the normal bottom-tracking range of the DVL, water-tracking velocity estimates can be affected by bottom reflections. With fast currents the velocity estimate can become invalid, and with slow currents the estimate can be biased toward the bottom-relative velocity. + +The maximum measurable velocity in water tracking mode is 7.5 m/s. + +Update rate is `2 Hz`. + +!!! warning + Dead reckoning performance with water tracking is untested and can give large errors. + +## Web GUI + +The dashboard shows the active tracking mode. On supported software, the tracking mode can be selected from the configuration page. + +The diagnostic page still shows spatial velocity, per-transducer velocity, and validity. In water tracking mode, the acoustic signal view shows signal strength and noise as separate time-based graphs. + +## TCP JSON API + +Water tracking is available in TCP JSON API `json_v3.2` for supported models. Use the TCP JSON API configuration method for your model: + +* [DVL A50/A125 TCP JSON API configuration](dvl-json-protocol.md#configuration-over-json) +* DVL A100/A250 TCP JSON API configuration is planned for water tracking and is not available yet. + +Enable water tracking by setting `range_mode` to `wt`: + +```json +{"command":"set_config","parameters":{"range_mode":"wt"}} +``` + +Set `range_mode` back to `auto` to return to automatic bottom tracking: + +```json +{"command":"set_config","parameters":{"range_mode":"auto"}} +``` + +Water tracking does not introduce a separate report type. The DVL continues to use the normal velocity-and-transducer report, with the field `"type"` showing the active tracking mode. When water tracking is active, the report describes velocity relative to the water column rather than velocity relative to the bottom and the `"type"` will be `"velocity_water"`. + +See the TCP JSON API for your model for the report fields: + +* [DVL A50/A125 TCP JSON API velocity-and-transducer report](dvl-json-protocol.md#velocity-and-transducer-report) +* DVL A100/A250 TCP JSON API water-tracking report fields are planned and are not available yet. + +## Serial API + +Water tracking is available in serial protocol >= `2.7.0` for supported models. Use the serial configuration method for your model: + +* [DVL A50/A125 serial configuration](dvl-serial-protocol.md#configuration-over-serial) +* DVL A100/A250 serial configuration for water tracking is planned and is not available yet. + +Enable water tracking by setting `range_mode` to `wt` using the `wcs` command: + +```text +wcs,,,,,wt, +``` + +Set `range_mode` back to `auto` to return to automatic bottom tracking: + +```text +wcs,,,,,auto, +``` + +Water tracking introduces a serial report called `wrs`, which is similar to the `wrz` report but does not include altitude data. Use this data when water tracking is activated. + +```text +wrs,[vx],[vy],[vz],[valid],[fom],[covariance],[time_of_validity],[time_of_transmission],[time],[status] +``` + +See the serial protocol for your model for the report format: + +* [DVL A50/A125 serial velocity report](dvl-serial-protocol.md#velocity-report-wrs) +* DVL A100/A250 serial water-tracking reports are planned and are not available yet. diff --git a/docs/img/dvl_a250_back_entry_drawing.png b/docs/img/dvl_a250_back_entry_drawing.png new file mode 100644 index 0000000000000000000000000000000000000000..edb56bf467b12e0d5da524ee964b9e7cdd9856cb GIT binary patch literal 108042 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 z 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%0D_u~{$U zXzS#f6HF*v&RcP(oGaS9Jopcw2S=_F-ZJ)F);i7p>RA1+VA||3-&G!0;|;Mw^}rW2AFu_IIGu6q!iDQ zHne)7;2?l-w3*KZVkLn=80*{BnlRb^3q?%b-ErlO#vNM;)1M?oNF521_Abw zXYM_inutZGtj?qb)Bvs#k$mRpv@0_}62HzGmdU0C0Ib4spyugmjl!P}Pp0?cFU#(V zape7)y8JZ!?G`;75+^zc_)m=qt6f4kH_*eFR$ihgP*<9BJ{0DkK%r8|1eaTF$IiPvC+YBdxMinoASlA;47uh-|(u z#$=1*szCj_Wkz0Sns^PO!A5oGnrV%^ACkMZQ|`c_vpOs--%UIZ=!aD&yP`E|w&q+` z9^?o&7|SBguNcLsFR+~a)LULbFv#fY_?YuqqA;dyRA1#E9elg2Yv51=KGP5@g!4)f zd-mRb0s?d$CjBh?UU_%CnGHYO5X~L zindbF{3X(xNC))L{mfh{2veR5_#pQ+;7aA&2 zj@&e0u{je-9tOgqMlr&y3B45vR zCAu}IbE{!}CMsONfYZwp>V{Kn&`(1WY6?b9{}&{ukN?Duc(lv2ZC&xR2xryn`kTMU zI7tGm(W2#~!gXApk5I09?7_a1SRJ$b&6w&a#a1frvO;yFww>brB>P}2`9LIcfxg*} zpz%!VUtFVLO~JmYQ{mK2KgSfm#-7*Ej^%U>!XSjkJtDv!Lf%8Q&wk^-B{LU~Y}?ZI z6&%aa{hHE{s7_(Lesj$!ebla1NstBmir7sI+B_SqZBzX@dDTqJMXZOMwwtLf>1Xgo z9BbM%1r%33Z)B}McqS+$*7z*B49^(tyNP*xMD#{=E#9n+Z+()

E5mjE=exSDR$U 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 pAPNY*_j-h$-u>R||9=9jR*9;O* literal 0 HcmV?d00001 diff --git a/docs/img/dvl_a250_front_side_drawing.png b/docs/img/dvl_a250_front_side_drawing.png new file mode 100644 index 0000000000000000000000000000000000000000..4c1e05777b69e20738bd2f4ec21a992c44d9239b GIT binary patch literal 54488 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 XMdQl+^%4*Z3c%q*#}8)irw05V?d2gt literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md index 6cb2e082..6263d860 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,7 +14,7 @@ /* Each item in a row takes up 1/3 of the width on large screens */ .col-3 { - flex: 0 0 33%; + flex: 0 0 48%; box-sizing: border-box; } @@ -33,7 +33,7 @@

- - - - diff --git a/docs/io-interface-cards/io-interface-rev2.md b/docs/io-interface-cards/io-interface-rev2.md new file mode 100644 index 00000000..4852e0c4 --- /dev/null +++ b/docs/io-interface-cards/io-interface-rev2.md @@ -0,0 +1,15 @@ +### Revision 2 + +![I/O_Interface_rev2](../img/WL-31014-2_IO_Interface_connections.png) + +Dimensions: 30.6 mm x 50 x 18.6 mm (Width x Height x Thickness) + +| Connector | Function | Comment | +| ------------------- | :--------- | :------ | +| RJ45 (8P8C) | Ethernet | 10/100 BASE-T | +| 3x1 header | Serial | TX, RX, GND | +| Molex Micro-Fit 3.0 | Power | 10 - 30 VDC | +| 2x Ø1.5mm pads | Alt. power | | + +!!! Note + The Molex Micro-Fit 3.0 on revision 2 is prone to damage by excessive sideways force. Take care not the yank the power cable when connected. \ No newline at end of file diff --git a/docs/io-interface-cards/io-interface-rev3.md b/docs/io-interface-cards/io-interface-rev3.md new file mode 100644 index 00000000..d32c0a71 --- /dev/null +++ b/docs/io-interface-cards/io-interface-rev3.md @@ -0,0 +1,12 @@ +### Revision 3 + +![I/O_Interface_rev3](../img/WL-31014-3_IO_Interface_connections.png) + +Dimensions: 40 x 42 x 18.6 mm (Width x Height x Thickness) + +| Connector | Function | Comment | +| ------------------- | :--------- | :------ | +| RJ45 (8P8C) | Ethernet | 10/100 BASE-T | +| 3x1 header | Serial | TX, RX, GND | +| Molex Micro-Fit 3.0 | Power | 10 - 30 VDC | +| 2x Ø1.5mm pads | Alt. power | Fits [Würth 691137710002](https://octopart.com/691137710002-w%C3%BCrth+elektronik-78871135) | \ No newline at end of file diff --git a/docs/modem-m64/modem-m64-protocol.md b/docs/modem-m64/modem-m64-protocol.md index ecbe8eb1..36b0a141 100644 --- a/docs/modem-m64/modem-m64-protocol.md +++ b/docs/modem-m64/modem-m64-protocol.md @@ -50,7 +50,7 @@ The modem with role B will go back to listen mode if several consecutive packets Payload where every byte is \0 is reserved. It is used to keep modems in sync if no data packet is queued by the user. This sync packet is filtered out by the receiver. Avoid this payload by compressing the data or otherwise ensuring atleast 1 bit is non-zero. Checksum is optional when sending commands to the modem. The modem always returns a checksum. The checksum algorithm -is CRC-8 and it is formatted as a hexadecimal number using 2 lower-case charaters (ex: `*c3`). See the [checksum section](../dvl/dvl-protocol.md#checksum) of the manual for our DVL product (which uses the same CRC-8 algorithm) for further details and example code. +is CRC-8 and it is formatted as a hexadecimal number using 2 lower-case charaters (ex: `*c3`). See the [checksum section](../dvl/dvl-serial-protocol.md#checksum) of the manual for our DVL product (which uses the same CRC-8 algorithm) for further details and example code. ## Commands diff --git a/mkdocs.yml b/mkdocs.yml index 51193e9e..6513b06c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -134,24 +134,50 @@ nav: - Software updates: explorer-kit/upgrader.md - DVL: - - DVL-A50 — Introduction: dvl/dvl-a50.md - - DVL-A125 — Introduction: dvl/dvl-a125.md - - Interfaces: dvl/interfaces.md - - Networking: dvl/networking.md - - Axes: dvl/axes.md - - Protocol: dvl/dvl-protocol.md - - GUI: - - Dashboard: dvl/gui/dashboard.md - - Configuration: dvl/gui/configuration.md - - Diagnostic report: dvl/gui/diagnostic-report.md - - Demo GUI: dvl/gui/demo-gui.md - - Dead reckoning: dvl/dead-reckoning.md + - Overview: dvl/overview.md + - Get started Quickstart guide: dvl/quickstart.md + + - Models: + - A50: dvl/dvl-a50.md + - A100: dvl/dvl-a100.md + - A125: dvl/dvl-a125.md + - A250: dvl/dvl-a250.md + + - Install and connect: + - Installation: dvl/installation.md + - Electrical: dvl/electrical.md + - Network setup: dvl/networking.md + + - Operate the device: + - Axes: dvl/axes.md + - Range mode: dvl/range-mode.md + - Water tracking: dvl/water-tracking.md + - Settings and configuration: dvl/configuration.md + - Diagnostic log: dvl/diagnostic-log.md + - Dead reckoning: dvl/dead-reckoning.md + - Software updates: dvl/sw-update.md + - Web GUI: + - DVL A50/A125 web GUI: dvl/dvl-a50_a125-gui.md + - DVL A100/A250 web GUI: dvl/dvl-a250_a100-gui.md + - Integration: + - Integration overview: dvl/integration.md + - TCP JSON API: + - A50/A125: dvl/dvl-json-protocol.md + - A100/A250: dvl/dvl-a250_a100-json-protocol.md + - Serial protocol: + - A50/A125: dvl/dvl-serial-protocol.md + - A100/A250: dvl/dvl-a250_a100-serial-protocol.md + - PD formats: dvl/dvl-pd-formats.md + - Triggering and synchronization: dvl/dvl-triggering.md + - Software resources: dvl/software-resources.md - DVL for BlueROV2: dvl/bluerov-integration.md - DVL with UGPS for BlueROV2: dvl/bluerov-integration-dvl-ugps.md - - Software updates: dvl/sw-update.md - - Troubleshooting: dvl/dvl-troubleshooting.md - - DVL FAQ: dvl/faq.md + + - Troubleshooting: + - How to diagnose: dvl/how-to-diagnose.md + - Support package checklist: dvl/support-package-checklist.md + - FAQ: dvl/faq.md - Modem: - Modem-M64 (retired): @@ -170,6 +196,8 @@ nav: - M16 FAQ: modem-m16/modem-m16-faq.md - I/O interface cards: + - Revision 2: io-interface-cards/io-interface-rev2.md + - Revision 3: io-interface-cards/io-interface-rev3.md - Revision 4: io-interface-cards/io-interface-rev4.md - Revision 6: io-interface-cards/io-interface-rev6.md From 4b61582479037401c8327365d7dd8d7655a8caf3 Mon Sep 17 00:00:00 2001 From: Esten Date: Fri, 15 May 2026 13:23:43 +0200 Subject: [PATCH 2/2] Clean --- docs/dvl/dvl-protocol.md | 842 ------------------------------ docs/dvl/dvl-troubleshooting.md | 51 -- docs/dvl/gui/configuration.md | 34 -- docs/dvl/gui/dashboard.md | 51 -- docs/dvl/gui/demo-gui.md | 3 - docs/dvl/gui/diagnostic-report.md | 9 - docs/dvl/interfaces.md | 148 ------ 7 files changed, 1138 deletions(-) delete mode 100644 docs/dvl/dvl-protocol.md delete mode 100644 docs/dvl/dvl-troubleshooting.md delete mode 100644 docs/dvl/gui/configuration.md delete mode 100644 docs/dvl/gui/dashboard.md delete mode 100644 docs/dvl/gui/demo-gui.md delete mode 100644 docs/dvl/gui/diagnostic-report.md delete mode 100644 docs/dvl/interfaces.md diff --git a/docs/dvl/dvl-protocol.md b/docs/dvl/dvl-protocol.md deleted file mode 100644 index 3e2e146a..00000000 --- a/docs/dvl/dvl-protocol.md +++ /dev/null @@ -1,842 +0,0 @@ -## Water Linked DVL protocol - -Describes the Water Linked DVL protocols (serial and ethernet). - -## Terminology - -* DVL - Doppler Velocity Log - Uses hydro-acoustic beams to measure the velocity at which the DVL is moving across a surface (typically an unmoving one such as the sea bottom), and the distance to this surface. -* ACK - Acknowledgement. The command issued was successful. -* NAK - Negative acknowledgement. The command issued failed. -* Ping - A pulse of sound sent by the DVL -* Time of validity - Timestamp of the surface reflection ('center of ping') -* Time of transmission - Timestamp taken directly before sending data over the serial or TCP protocols. The difference between time of transmission and time of validity includes both the time for the acoustic wave to travel from the surface from which it was reflected back to the DVL, and the decoding and processing of this signal internally in the DVL. - -## Version - -This document describes serial protocol version `2.6.x` (major.minor.patch) and JSON protocol `json_v3.1` (major.minor): - -- MAJOR version increments represent incompatible API changes -- MINOR version increments represent additional backwards-compatible functionality -- PATCH version increments represent backwards-compatible bug fixes - -### Version history overview - -| Software release | Serial protocol version | Ethernet protocol version | Main protocol improvements | -| -- | -- | -- | -- | -| 2.6.1 | 2.6.0 | json_v3.1 | Serial baud rate configurable. Add PD4 protocol support in serial 'wcp' command. Some serial protocol names [changed](#change-serial-output-protocol-wcp). | -| 2.5.2 | 2.5.0 | json_v3.1 | Add PD4 protocol support (experimental) -| 2.4.4 | 2.5.0 | json_v3.1 | Change gyro calibration to store persistently. Note: gyro calibration commands now takes up to 15 seconds. -| 2.4.0 | 2.5.0 | json_v3.1 | Add ability to trigger pings (JSON/Serial), add configuration for periodic cycling (JSON/Serial) -| 2.2.1 | 2.4.0 | json_v3 | Add serial output protocol configuration, range mode configuration and calibrate gyro command, Fix missing line ending in configuration (JSON), fix dark mode enabled naming inconsistency (JSON), change speed of sound and mounting rotation offset from integer to float -| 2.1.0 | 2.3.0 | json_v3 | Add configuration, add time_of_validity/time_of_transmission, add covariance (JSON) -| 2.0.8 | 2.2.0 | json_v2 | Add position estimation, Add output of orientation angles -| 1.6.0 | 2.1.0 | - | Initial (velocity only) - -## JSON protocol (TCP) - -### Overview - -The DVL supports sending velocity, transducer, and position updates using the Transmission Control Protocol (TCP). The DVL runs a TCP server on port 16171. - -The format of each packet is JSON. - -### Velocity-and-transducer report - -A velocity-and-transducer report is sent for each velocity calculation of the DVL. The rate depends on the altitude of the DVL (distance to the sea bottom or other reflecting surface), but will be in the range 2-15 Hz. - -The X, Y, and Z axes are with respect to [body frame](axes.md#body-frame) of the DVL, or the [vehicle frame](axes.md#vehicle-frame) if the DVL is mounted on a vehicle at an angle, specified as a 'mounting rotation offset', from the forward axis of the vehicle. - -The messages are delimited by newline. - -| Variable | Description | -|----------|-------------| -| time | Milliseconds since last velocity report (ms) | -| vx | Velocity in x direction (m/s) | -| vy | Velocity in y direction (m/s) | -| vz | Velocity in z direction (m/s) | -| fom | Figure of merit, a measure of the accuracy of the velocities (m/s) | -| covariance | Covariance matrix for the velocities. The figure of merit is calculated from this (entries in (m/s)^2) | -| altitude | Distance to the reflecting surface along the Z axis (m) | -| transducers | Is a list containing information from each transducer: [id, velocity (m/s), distance (m), rssi (dBm), nsd (dBm), beam_valid (True/False)] | -| velocity_valid | If true, the DVL has a lock on the reflecting surface, and the altitude and velocities are valid (True/False) | -| status | 8 bit status mask. Bit 0 is set to 1 for high temperature and DVL will soon enter thermal shutdown. Remaining bits are reserved for future use. | -| time_of_validity | Timestamp of the surface reflection, aka 'center of ping' (Unix timestamp in microseconds) | -| time_of_transmission | Timestamp from immediately before sending of the report over TCP (Unix timestamp in microseconds) | -| format | Format type and version for this report: `json_v3.1` | -| type | Report type: `velocity` | - -Example of TCP report (indented for legibility) - -``` -{ - "time": 106.3935775756836, - "vx": -3.713480691658333e-05, - "vy": 5.703703573090024e-05, - "vz": 2.4990416932269e-05, - "fom": 0.00016016385052353144, - "covariance": [ - [ - 2.4471841442164077e-08, - -3.3937477272871774e-09, - -1.6659699175747278e-09 - ], - [ - -3.3937477272871774e-09, - 1.4654466085062268e-08, - 4.0409570134514183e-10 - ], - [ - -1.6659699175747278e-09, - 4.0409570134514183e-10, - 1.5971971523143225e-09 - ] - ], - "altitude": 0.4949815273284912, - "transducers": [ - { - "id": 0, - "velocity": 0.00010825289791682735, - "distance": 0.5568000078201294, - "rssi": -30.494251251220703, - "nsd": -88.73271179199219, - "beam_valid": true - }, - { - "id": 1, - "velocity": -1.4719001228513662e-05, - "distance": 0.5663999915122986, - "rssi": -31.095735549926758, - "nsd": -89.5116958618164, - "beam_valid": true - }, - { - "id": 2, - "velocity": 2.7863150535267778e-05, - "distance": 0.537600040435791, - "rssi": -27.180519104003906, - "nsd": -96.98075103759766, - "beam_valid": true - }, - { - "id": 3, - "velocity": 1.9419496311456896e-05, - "distance": 0.5472000241279602, - "rssi": -28.006759643554688, - "nsd": -88.32147216796875, - "beam_valid": true - } - ], - "velocity_valid": true, - "status": 0, - "format": "json_v3.1", - "type": "velocity", - "time_of_validity": 1638191471563017, - "time_of_transmission": 1638191471752336 -} -``` - -### Dead reckoning report - -A dead reckoning report outputs the current speed, position, and orientation of the DVL as calculated by [dead reckoning](dead-reckoning.md), with respect to a [frame](dead-reckoning.md#frame) defined by the axes of the DVL's [body frame](axes.md#body-frame), or [vehicle frame](axes.md#vehicle-frame) if a mounting rotation offset is set, at the start of the dead reckoning run. The expected update rate is 5 Hz. - - - -Variable | Description -------------|------------- -ts | Time stamp of report (Unix timestamp in seconds) -x | Distance in X direction (m) -y | Distance in Y direction (m) -z | Distance in downward direction (m) -std | Standard deviation (figure of merit) for position (m) -roll | Rotation around X axis (degrees) -pitch | Rotation around Y axis (degrees) -yaw | Rotation around Z axis, i.e. heading (degrees) -type | Report type: `position_local` -status | Reports if there are any issues with the DVL (0 if no errors, 1 otherwise) -format | Format type and version for this report: `json_v3` - - -Example of a dead reckoning report. - -``` -{ - "ts": 49056.809, - "x": 12.43563613697886467, - "y": 64.617631152402609587, - "z": 1.767641898933798075, - "std": 0.001959984190762043, - "roll": 0.6173566579818726, - "pitch": 0.6173566579818726, - "yaw": 0.6173566579818726, - "type": "position_local", - "status": 0, - "format": "json_v3.1" -} - -``` - -### Reset dead reckoning - -Dead reckoning can be reset by issuing the `reset_dead_reckoning` command: - -``` -{"command": "reset_dead_reckoning"} -``` - -If the request is successfully received the response will have 'success' set to 'true'. The dead reckoning will have a delay of approximately 50ms until the positioning values being zeroed out. If the response is unsuccessful, the 'success' will be 'false' and a non-empty describing text will be returned in 'error_message'. - -``` -{ - "response_to":"reset_dead_reckoning", - "success": true, - "error_message": "", - "result": null, - "format": "json_v3.1", - "type": "response" -} -``` - -### Calibrate gyro - -The gyro can be calibrated by issuing the `calibrate_gyro` command: - -``` -{"command":"calibrate_gyro"} -``` - -The response will be as follows if the calibration is successful. If unsuccessful, `success` will be `false`, and a non-empty `error_message` will be provided. - -``` -{ - "response_to": "calibrate_gyro", - "success": true, - "error_message": "", - "result": null, - "format": "json_v3.1", - "type": "response" -} -``` - -### Trigger ping - -In setups where multiple acoustic sensors are used it can be useful to control the pinging of each acoustic sensor individually. By setting the configuration `acoustic_enabled = false` the pinging of the DVL can be externally controlled. Up to 15 external trigger commands can be queued by issuing the `trigger_ping` command. The DVL will execute each ping in quick succession until no more commands are in the queue. - -``` -{"command":"trigger_ping"} -``` - -The response will be as follows if the calibration is successful. If queue is full, `success` will be `false`, and a non-empty `error_message` will be provided. - -``` -{ - "response_to": "trigger_ping", - "success": true, - "error_message": "", - "result": null, - "format": "json_v3.1", - "type": "response" -} -``` - -### Configuration over JSON - -#### Configuration parameters - -| Variable | Description | -|----------|-------------| -| speed_of_sound | Speed of sound (1000-2000 m/s). Integer | -| mounting_rotation_offset | See the definition of the [vehicle frame](axes.md#vehicle-frame) of the DVL. Typically 0, but can be set to be non-zero if the forward axis of the DVL is not aligned with the forward axis of a vehicle on which it is mounted (0-360 degrees). Integer | -| acoustic_enabled | `true` for normal operation of the DVL,`false` when the sending of acoustic waves from the DVL is disabled (e.g. to save power or slow down its heating up in air) | -| dark_mode_enabled | `false` when the LED operates as [normal](interfaces.md#led-signals), `true` for no blinking of the LED (e.g. if the LED is interfering with a camera) | -| range_mode | `auto` when operating as normal, otherwise see [range mode configuration](dvl-protocol.md#range-mode-configuration) | -| periodic_cycling_enabled | `true` for normal operation where the DVL periodically searches for bottom lock shorter than the existing bottom lock, `false` if periodic cycling is disabled | - - -#### Fetching current configuration - -The current configuration of the DVL can be obtained by issuing the `get_config` command: - -``` -{"command": "get_config"} -``` - -If the configuration is successfully fetched, the response will be in the following format. If not, `success` will be false, a non-empty `error_message` string will be provided, and `result` will be `null`. - - -``` -{ - "response_to":"get_config", - "success":true, - "error_message":"", - "result":{ - "speed_of_sound":1475.00, - "acoustic_enabled":true, - "dark_mode_enabled":false, - "mounting_rotation_offset":20.00, - "range_mode":"auto", - "periodic_cycling_enabled":true - }, - "format":"json_v3.1", - "type":"response" -} -``` - -#### Setting configuration parameters - -Setting of configuration parameters can be carried out by issuing a `set_config` in the following format, including those parameters which are to be set: - -``` -{"command":"set_config","parameters":{"speed_of_sound":1480}} -``` - -If the parameters are successfully set, the response will be in the following format. If not, `success` will be false, and a non-empty `error_message` string will be provided. - - -``` -{ - "response_to": "set_config", - "success": true, - "error_message": "", - "result" :null, - "format": "json_v3.1", - "type": "response" -} -``` - - -## Serial Protocol - -### Overview - -The default serial communication format is 115200 8-N-1 (no hardware flow control). Release 2.6.1 and later allow different baud rates through GUI configuration. - -Packets sent to and received from the DVL start with a `w` and end with LF, CR+LF, or CR. The packet format is: - -| Start byte | Direction | Command | Options (0 to many) | Checksum | End byte | -|------------|------------------|----------|----------------------|----------|----------------| -| `w` | `c` or `r` | `x` | `,[option]` | `*xx` | `\n`, `\r\n`, or `\r` | - -`Direction` is `c` (short for 'command') for packets sent to the DVL, and `r` (short for 'response') for packets sent from the DVL. -The commands can be sent from a terminal program that supports sending a full line at a time. The timeout between characters is approximately 10 ms. - -!!!note - Please verify the baud rate configuration in the GUI if you are unable to communicate with the default baud rate. - - -!!!note - The checksum is optional when sending commands to the DVL. The DVL always returns a checksum. The checksum algorithm - is CRC-8 and it is formatted as a hexadecimal number using 2 lower-case characters (ex: `*c3`). See [below](#checksum) for details. - -### Command overview - -The commands in the table are shown without the checksum and without the mandatory line ending (any of `\n`, `\r\n`, or `\r`) for readability. In all cases, the response to a submitted command may be `wrn`, `wr?`, or `wr!` (see below for details), but only the format of a successful response is listed. - -| Command | Description | Response | Description | -|---------|-------------|----------|-------------| -| `wcv` | Get protocol version | `wrv,`*[major],[minor],[patch]* | Protocol version. eg: `wrv,2.5.0` | -| `wcw` | Get product detail | `wrw,`*[name]*,*[version]*,*[chipID]*,*[IP address]* | Where type is dvl, name is product name, version is software version, chip ID is the chip ID and _optionally_ the IP address if connected to DHCP server: eg: `wrw,dvl-a50,2.2.1,0xfedcba98765432` or `wrw,dvl-a50,2.2.1,0xfedcba98765432,10.11.12.140` | -| `wcs,`*[configuration parameters]* | Set configuration parameters | `wra` | Successfully set the specified configuration parameters. See [Configuration](#configuration-over-serial) for details | -| `wcc` | Get current configuration | `wrc,`*[configuration parameters]* | Entire current configuration. See [Configuration](#configuration-over-serial) for details | -| `wcr` | Reset dead reckoning | `wra` | Successfully started a new [dead reckoning](dead-reckoning.md#starting-dead-reckoning) run | -| `wcx` | Trigger ping | `wra` | Successfully queued a ping | -| `wcg` | Calibrate gyro | `wra` | Successfully calibrated gyro | -| `wcp` | Change serial output protocol | `wra` | Successfully changed output protocol | -| | | `wrz,`*[details below]* | Velocities calculated | -| | | `wru,`*[details below]* | Transducer information | -| | | `wrp,`*[details below]* | [Dead reckoning](dead-reckoning.md) report | -| | | `wrx,`*[details below]* | DEPRECATED: Velocities calculated (old format) | -| | | `wrt,`*[details below]* | DEPRECATED: Transducer information (old format) | -| | | `wr?` | Malformed request: packet cannot be understood or no newline received before timeout | -| | | `wr!` | Malformed request: packet does not match the given checksum | -| | | `wrn` | Not acknowledged (nack): an error occurred when handling the packet | - - - -### Velocity report (wrz) - -A velocity report is outputted for each velocity calculation of the DVL. The rate depends on the altitude of the DVL (distance to the sea bottom or other reflecting surface), but will be in the range 2-15 Hz. - -The X, Y, and Z axes are with respect to [body frame](axes.md#body-frame) of the DVL, or the [vehicle frame](axes.md#vehicle-frame) if the DVL is mounted on a vehicle at an angle, specified as a 'mounting rotation offset', from the forward axis of the vehicle. - -The report has the following format: -`wrz,`*[vx],[vy],[vz],[valid],[altitude],[fom],[covariance],[time_of_validity],[time_of_transmission],[time],[status]* - - -| Variable | Description | -|----------|-------------| -| vx | Velocity in x direction (m/s) | -| vy | Velocity in y direction (m/s) | -| vz | Velocity in z direction (m/s) | -| valid | If `y`, the DVL has a lock on the reflecting surface, and the altitude and velocities are valid (y/n) | -| altitude | Measured altitude to the bottom (m) | -| fom | Figure of merit, a measure of the accuracy of the velocities (m/s) | -| covariance | Covariance matrix for the velocities. The figure of merit is calculated from this. 9 entries ((m/s)^2) separated by ; | -| time_of_validity | Timestamp of the surface reflection, aka 'center of ping' (Unix timestamp in microseconds) | -| time_of_transmission | Timestamp from immediately before sending of the report over TCP (Unix timestamp in microseconds) | -| time | Milliseconds since last velocity report (ms) | -| status | 8 bit status mask. Bit 0 is set to 1 for high temperature and DVL will soon enter thermal shutdown. Remaining bits are reserved for future use. | - -Example where all velocities are valid: - -``` -wrz,0.120,-0.400,2.000,y,1.30,1.855,1e-07;0;1.4;0;1.2;0;0.2;0;1e+09,7,14,123.00,1*50 -``` - -### Transducer report (wru) - -A transducer report is outputted for each of the four transducers of the DVL for each velocity calculation of the DVL. The rate will be the same as that of the velocity report. If the transducer did not receive a signal which could be successfully decoded, `distance` will be set to -1, and `velocity` will be set to 0. RSSI and NSD will be outputted in all cases. - -The report has the following format: -`wru,`*[id],[velocity],[distance],[rssi],[nsd]* - - -| Variable | Description | -|----------|-------------| -| id | Transducer number | -| velocity | Velocity in the direction of the transducer (m/s) | -| distance | Distance (parallel to the transducer beam, i.e. not the vertical distance) to the reflecting surface from this transducer (m) | -| rssi | Received signal strength indicator: strength of the signal received by this transducer (dBm) | -| nsd | Noise spectral density: strength of the background noise received by this transducer (dBm) | - -Example where all data is valid: - -``` -wru,0,0.070,1.10,-40,-95*9c -wru,1,-0.500,1.25,-62,-104*f0 -wru,2,2.200,1.40,-56,-98*18 -wru,3,1.800,1.35,-58,-96*a3 -``` - - -### Dead reckoning report (wrp) - -A dead reckoning report outputs the current speed, position, and orientation of the DVL as calculated by [dead reckoning](dead-reckoning.md), with respect to a [frame](dead-reckoning.md#frame) defined by the axes of the DVL's [body frame](axes.md#body-frame), or [vehicle frame](axes.md#vehicle-frame) if a mounting rotation offset is set, at the start of the dead reckoning run. The expected update rate is 5 Hz. - -The format is: -`wrp,`*[time_stamp],[x],[y],[z],[pos_std],[roll],[pitch],[yaw],[status]* - -Variable | Description -------------|------------- -time_stamp | Time stamp of report (Unix timestamp in seconds) -x | Distance in X direction (m) -y | Distance in Y direction (m) -z | Distance in downward direction (m) -pos_std | Standard deviation (Figure of merit) for position (m) -roll | Rotation around X axis (degrees) -pitch | Rotation around Y axis (degrees) -yaw | Rotation around Z axis, i.e. heading (degrees) -status | Reports if there are any issues with the DVL (0 if no errors, 1 otherwise) | - -Example: - -``` -wrp,49056.809,0.41,0.15,1.23,0.4,53.9,13.0,19.3,0*de -wrp,49057.269,0.39,0.18,1.23,0.4,53.9,13.0,19.3,0*e2 -``` - - -### Reset dead reckoning (wcr) - -Dead reckoning can be reset by issuing the `wcr` command. The reply will be an ack (`wra`) if the reset is successful, and a nak (`wrn`) if not. - -### Calibrate gyro (wcg) - -The gyro can be calibrated by issuing the `wcg` command. The reply will be an ack (`wra`) if the reset is successful, and a nak (`wrn`) if not. - -### Trigger ping (wcx) - -In setups where multiple acoustic sensors are used it can be useful to control the pinging of each acoustic sensor individually. By setting the configuration `acoustic_enabled = n` the pinging of the DVL can be externally controlled. Up to 15 external trigger commands can be queued by issuing the `wcx` command. The DVL will execute each ping in quick succession until no more commands are in the queue. - -The reply will be an ack (`wra`) if the command is successful, and a nak (`wrn`) if queue is full. - -### Change serial output protocol (wcp) - -The serial output protocol in use can configured by issuing the `wcp` command. The selected protocol is persistent over reboots. - -``` -wcp,[protocol number] -``` - -The supported protocols are: - -| Protocol number | Name | Description | -| --------------- | ---- | ----------- | -| 0 | Output disabled | No output on serial. Recommended if serial port is not used to lower latency on ethernet protocols. | -| 1 | WL - Serial V1 and V2 | All output including the deprecated `wrx` and `wrt` sentences. | -| 2 | PD6 | PD6 protocol output. See [PD6 protocol description](#pd6-protocol-tcpserial) | -| 3 | WL - Serial V2 | All output excluding the deprecated `wrx` and `wrt` sentences. | -| 4 | Not used | Not used | -| 5 | Not used | Not used | -| 6 | PD4 | PD4 protocol output See [PD4 protocol description](#pd4-protocol-tcpserial) | - -The reply will be an ack (`wra`) if the protocol change is successful, and a nak (`wrn`) if not. - -Example setting configuring output to use protocol number 3: - -``` -wcp,3 -``` - -!!!note - Prior to release 2.6.1 protocol number 1 was named `Backward compatible` and protocol number 3 was named `Latest`. There is no change in functionality. - -### Configuration over serial - -#### Configuration parameters - -| Variable | Description | -|----------|-------------| -| speed_of_sound | Speed of sound (1000-2000 m/s). Float | -| mounting_rotation_offset | See the definition of the [vehicle frame](axes.md#vehicle-frame) of the DVL. Typically 0, but can be set to be non-zero if the forward axis of the DVL is not aligned with the forward axis of a vehicle on which it is mounted (0-360 degrees). Float | -| acoustic_enabled | `y` for normal operation of the DVL,`n` when the sending of acoustic waves from the DVL is disabled (e.g. to save power or slow down its heating up in air) | -| dark_mode_enabled | `n` when the LED operates as [normal](interfaces.md#led-signals). `y` for no blinking of LED (e.g. if the LED is interfering with a camera) | -| range_mode |`auto` when operating as normal, otherwise see [range mode configuration](dvl-protocol.md#range-mode-configuration) | -| periodic_cycling_enabled | `y` when operating as normal, otherwise `n`. See [Configuration over JSON](dvl-protocol.md#configuration-over-json) for details - -!!!note - For backward compatibility the `range_mode` and `periodic_cycling_enabled` parameters are optional when setting the configuration. They will always be returned when reading the configuration (`wcc`). - Speed of sound and mounting rotation was changed from integer to float in serial protocol 2.4.0 - -#### Fetching current configuration - -The current configuration of the DVL can be obtained by issuing the `wcc` command. - - -If the configuration is successfully fetched, the response will be in the following format. If not, a nak `wrn` will be returned. - -``` -wrc,[speed_of_sound],[mounting_rotation_offset],[acoustic_enabled],[dark_mode_enabled],[range_mode],[periodic_cycling_enabled] -``` - -#### Setting configuration parameters - -Setting of configuration parameters can be carried out by issuing the `wcs` command in the following format. - - -``` -wcs,[speed_of_sound],[mounting_rotation_offset],[acoustic_enabled],[dark_mode_enabled],[range_mode],[periodic_cycling_enabled] -``` - -Those parameters which are not to be set can be left blank. - -Example for setting dark mode without changing the other parameters: - -``` -wcs,,,,y,, -``` - -Example for setting speed of sound to 1450 m/s and disabling acoustics, without changing the other parameters: - -``` -wcs,1450,,n,,, -``` - -The response will be an ack `wra` if the parameters are successfully set, a nak `wrn` if the command was successfully parsed but the parameters were not successfully set, and a malformed request `wr?` if the command was not successfully parsed, e.g. if the wrong number of parameters was used, or either `speed_of_sound` or `mounting_rotation_offset` was not an integer. - -The new configuration will not be returned in the response, but can be obtained by issuing a `wcc` command as above. - - -### Velocity report, old format (wrx) [Deprecated] - -Same purpose as the [velocity report](#velocity-report-wrz), but in an older format: - -`wrx,`*[time],[vx],[vy],[vz],[fom],[altitude],[valid],[status]* - -| Variable | Description | -|----------|-------------| -| time | Milliseconds since last velocity report (ms) | -| vx | Velocity in x direction (m/s) | -| vy | Velocity in y direction (m/s) | -| vz | Velocity in z direction (m/s) | -| fom | Figure of merit, a measure of the accuracy of the velocities (m/s) | -| altitude | Distance to the reflecting surface along Z axis (m) | -| valid | If `y`, the DVL has lock on the reflecting surface, and the altitude and velocities are valid (y/n) | -| status | 8 bit status mask. Bit 0 is set to 1 for high temperature and DVL will soon enter thermal shutdown. Remaining bits are reserved for future use. | - -Example where velocities are valid: - -``` -wrx,112.83,0.007,0.017,0.006,0.000,0.93,y,0*d2 -wrx,140.43,0.008,0.021,0.012,0.000,0.92,y,0*b7 -wrx,118.47,0.009,0.020,0.013,0.000,0.92,y,0*54 -``` - -Example where velocities and altitude are not valid and a high temperature warning occurs: - -``` -wrx,1075.51,0.000,0.000,0.000,2.707,-1.00,n,1*04 -wrx,1249.29,0.000,0.000,0.000,2.707,-1.00,n,1*6a -wrx,1164.94,0.000,0.000,0.000,2.707,-1.00,n,1*39 -``` - -### Transducer report, old format (wrt) [Deprecated] - -Same purpose as the [transducer report](#transducer-report-wru), but in an older format, and combining the data of all four transducers: - -`wrt,`*[dist_1],[dist_2],[dist_3],[dist_4]* - -| Variable | Description | -|----------|-------------| -| dist_1 | Distance (parallel to the transducer beam, i.e. not the vertical distance) to reflecting surface from transducer 1 (m) | -| dist_2 | Distance to reflecting surface from transducer 2 (m) | -| dist_3 | Distance to reflecting surface from transducer 3 (m) | -| dist_4 | Distance to reflecting surface from transducer 4 (m) | - -Example where all distances are valid: - -``` -wrt,15.00,15.20,14.90,14.20*b1 -wrt,14.90,15.10,14.80,14.10*ac -``` - -Example where distance is not valid for transducer 4: - -``` -wrt,14.90,15.10,14.80,-1.00*53 -wrt,15.00,15.20,14.90,-1.00*71 -``` - - -### Checksum - -The checksum algorithm is CRC-8 (Polynomal: 0x07, Init: 0x00, RefIn/RefOut: false, XorOut: 0x00, Check: 0xf4). -Checksum is formatted as a hexadecimal number using 2 lower-case characters (ex: `*c3`). - -Compatible implementations: - -* Python 3: [crcmod](https://pypi.org/project/crcmod/) `crcmod.predefined.mkPredefinedCrcFun("crc-8")` -* Golang: [github.com/sigurn/crc8](https://github.com/sigurn/crc8) `crc8.MakeTable(crc8.CRC8)` - -Example for how to verify checksum using Python 3 and [crcmod](https://pypi.org/project/crcmod/): - -``` -crc = crcmod.predefined.mkPredefinedCrcFun("crc-8") -sentence = b"wrx,1164.94,0.000,0.000,0.000,2.707,-1.00,n,1*39" -data, checksum = sentence.split(b"*") - -if crc(data) == int(checksum, 16): - print("CRC valid") -else: - print("CRC invalid") -``` - -The [crcmod](https://pypi.org/project/crcmod/) python package can generate code in other languages. Here is an example (subject to the [MIT License](https://opensource.org/licenses/MIT)) for C which should be straightforward to adapt to other languages. - -``` -static const uint8_t lookup_table[256] = { - 0x00U,0x07U,0x0EU,0x09U,0x1CU,0x1BU,0x12U,0x15U, - 0x38U,0x3FU,0x36U,0x31U,0x24U,0x23U,0x2AU,0x2DU, - 0x70U,0x77U,0x7EU,0x79U,0x6CU,0x6BU,0x62U,0x65U, - 0x48U,0x4FU,0x46U,0x41U,0x54U,0x53U,0x5AU,0x5DU, - 0xE0U,0xE7U,0xEEU,0xE9U,0xFCU,0xFBU,0xF2U,0xF5U, - 0xD8U,0xDFU,0xD6U,0xD1U,0xC4U,0xC3U,0xCAU,0xCDU, - 0x90U,0x97U,0x9EU,0x99U,0x8CU,0x8BU,0x82U,0x85U, - 0xA8U,0xAFU,0xA6U,0xA1U,0xB4U,0xB3U,0xBAU,0xBDU, - 0xC7U,0xC0U,0xC9U,0xCEU,0xDBU,0xDCU,0xD5U,0xD2U, - 0xFFU,0xF8U,0xF1U,0xF6U,0xE3U,0xE4U,0xEDU,0xEAU, - 0xB7U,0xB0U,0xB9U,0xBEU,0xABU,0xACU,0xA5U,0xA2U, - 0x8FU,0x88U,0x81U,0x86U,0x93U,0x94U,0x9DU,0x9AU, - 0x27U,0x20U,0x29U,0x2EU,0x3BU,0x3CU,0x35U,0x32U, - 0x1FU,0x18U,0x11U,0x16U,0x03U,0x04U,0x0DU,0x0AU, - 0x57U,0x50U,0x59U,0x5EU,0x4BU,0x4CU,0x45U,0x42U, - 0x6FU,0x68U,0x61U,0x66U,0x73U,0x74U,0x7DU,0x7AU, - 0x89U,0x8EU,0x87U,0x80U,0x95U,0x92U,0x9BU,0x9CU, - 0xB1U,0xB6U,0xBFU,0xB8U,0xADU,0xAAU,0xA3U,0xA4U, - 0xF9U,0xFEU,0xF7U,0xF0U,0xE5U,0xE2U,0xEBU,0xECU, - 0xC1U,0xC6U,0xCFU,0xC8U,0xDDU,0xDAU,0xD3U,0xD4U, - 0x69U,0x6EU,0x67U,0x60U,0x75U,0x72U,0x7BU,0x7CU, - 0x51U,0x56U,0x5FU,0x58U,0x4DU,0x4AU,0x43U,0x44U, - 0x19U,0x1EU,0x17U,0x10U,0x05U,0x02U,0x0BU,0x0CU, - 0x21U,0x26U,0x2FU,0x28U,0x3DU,0x3AU,0x33U,0x34U, - 0x4EU,0x49U,0x40U,0x47U,0x52U,0x55U,0x5CU,0x5BU, - 0x76U,0x71U,0x78U,0x7FU,0x6AU,0x6DU,0x64U,0x63U, - 0x3EU,0x39U,0x30U,0x37U,0x22U,0x25U,0x2CU,0x2BU, - 0x06U,0x01U,0x08U,0x0FU,0x1AU,0x1DU,0x14U,0x13U, - 0xAEU,0xA9U,0xA0U,0xA7U,0xB2U,0xB5U,0xBCU,0xBBU, - 0x96U,0x91U,0x98U,0x9FU,0x8AU,0x8DU,0x84U,0x83U, - 0xDEU,0xD9U,0xD0U,0xD7U,0xC2U,0xC5U,0xCCU,0xCBU, - 0xE6U,0xE1U,0xE8U,0xEFU,0xFAU,0xFDU,0xF4U,0xF3U, -}; - -uint8_t crc8(uint8_t *message, int message_length) { - uint8_t checksum = 0; - while (message_length > 0) { - checksum = lookup_table[*message ^ checksum]; - message++; - message_length--; - } - return checksum; -} -``` - -## PD6 protocol (TCP/Serial) - -### Overview - -The PD6 support allows for integration with equipment that may already have a PD6 protocol interface, removing the necessity to create a driver based on the standard Water Linked protocol. -PD6 protocol is supported for output via serial and ethernet. -PD6 protocol over TCP is always enabled. The port in use is configurable in the GUI. The default port is TCP 1037. -The serial output can be configured to output PD6 using the [Change serial output protocol](#change-serial-output-protocol-wcp) command. - -### Command overview - -Sentences TS, BI and BD are filled with relevant numbers. All other sentences are set to zero values. - -#### Timing and scaling data (TS) - -`:TS,YYMMDDHHmmsshh,SS.S,+TT.T,DDDD.D,CCCC.C,BBB ` - -| Field| Explanation | Value | -| -- | -- | -- | -|YYMMDDHHmmsshh | Year, month, day, hour, minute, second, hundredths of seconds | Report timestamp | -| SS.S | Salinity in parts per thousand (ppt). | Always 0 | -| DDDD.D | Depth of transducer face in meters. | Always 0 | -| CCCC.C | Speed of sound in meters per second. | Configured speed of sound| -| BBB | Built-in Test (BIT) result code. | Always 0 | - -#### Bottom track, instrument referenced velocity data (BI) - -`:BI,±XXXXX,±YYYYY,±ZZZZZ,±EEEEE,S ` - -| Field| Explanation | Value | -| -- | -- | -- | -| ±XXXXX | X-axis velocity data in mm/s | Current speed | -| ±YYYYY | Y-axis velocity data in mm/s | Current speed | -| ±ZZZZZ | Z-axis velocity data in mm/s | Current speed | -| ±EEEEE | Error in velocity data in mm/s | Current error | -| S | Status of velocity | A = good. V = bad | - -!!! note - Axis used in the BI sentence is the [vehicle frame](./axes.md). - -#### Bottom track, earth referenced distance data (BD) - -`:BD,±EEEEEEEE.EE,±NNNNNNNN.NN,±UUUUUUUU.UU,DDDD.DD,TTT.TT ` - - -| Field| Explanation | Value | -| -- | -- | -- | -| ±EEEEEEEE.EE | East distance in meters. | Always 0 | -| ±NNNNNNNN.NN | North distance in meters. | Always 0 | -| ±UUUUUUUU.UU | Upward distance in meters. | Always 0 | -| DDDD.DD | Range to bottom in meters | Current altitude | -| TTT.TT | Time since last good velocity estimate in seconds. | Always 0 | - -#### Bottom track, ship referenced distance data (BS) - -- In the 2.4.0 software release the BS values are always zero. -- As of the 2.4.4 software release the BS values are given by the actual velocity. - -`:BS,±TTTTTTTT.TT,±LLLLLLLL.LL,±NNNNNNN.NN,S ` - - -| Field| Explanation | Value | -| -- | -- | -- | -| ±TTTTTTTT.TT | Transverse movement, (+ = Port to Starboard velocity relative to bottom) In mm/s | Y axis velocity | -| ±LLLLLLLL.LL | Longitudinal movement. (+ = Aft to Forward velocity relative to bottom) In mm/s | X axis velocity | -| ±NNNNNNN.NN | Ship velocity away from bottom in mm/s | Z axis velocity | -| S | Status of velocity | A = good. V = bad | - - -#### Example output - - - -``` -:SA, +0.00, +0.00, 0.00 -:TS,22020812061800, 0.0, +0.0, 0.0,1475.0, 0 -:WI, +0, +0, +0, +0,V -:WS, +0, +0, +0,V -:WE, +0, +0, +0,V -:WD, +0.00, +0.00, +0.00, 0.00, 0.00 -:BI, +123, -420, +2000, +0,A -:BS, -420, +123, +2000,A -:BE, +0, +0, +0,V -:BD, +0.00, +0.00, +0.00, 5.32, 0.00 -``` - -## Range mode configuration - -Range mode configuration can be used to instruct the DVL to only search for bottom lock in a limited altitude range. This can improve performance when operating in environments where you know the DVL minimum and/or maximum altitude. (Eg when operating in a river or pool) - -The format for configuring range mode can be as follows: - -| Range specifier | Behavior | -| -- | -- | -| `auto` | The DVL will search for bottom lock in it's full operational area (Default) | -| `=a` | The DVL is locked to range mode `a` where `b` is a number from `0-4` | -| `a<=b`| The DVL will search for bottom lock within range mode `a` and `b` | - -The available range modes are: - -| Range mode | Lower altitude (m) | Upper altitude (m) | Update rate per second (Hz) | -| -- | -- | -- | -- | -| 0 | 0.05 | 0.6 | 15 | -| 1 | 0.3 | 3.0 | 10 | -| 2 | 1.5 | 14 | 5 - 6 | -| 3 | 7.7 | 36 | 7 - 8 | -| 4 | 15 | max | 2 - 4 | - -Examples: - -* `=3` The DVL will search for bottom lock between 7.7 and 36m -* `2<=3` The DVL will search for bottom lock between 1.5 and 36m - - -## PD4 protocol (TCP/Serial) - -### Overview - -The PD4 string is intended for use with equipment that may already have a PD4 protocol interface, removing the necessity to create a driver based on the standard Water Linked protocol. PD4 protocol is supported for output via serial and ethernet. The PD4 protocol over TCP is always enabled. The port in use is configurable in the GUl. The default port is TCP 1038. - -!!!note - PD4 support was added in software release 2.5.2 and is experimental. Please give feedback on this feature. - - -### Data Format -PD4 is a binary protocol where fields are defined by their position in one message. -Data fields which use more than one byte are LittleEndian encoded. - -| Byte(s) | Data type | used | Unit | -| --- |--- |--- |--- | -| 0 | DVL Data ID 7Dh | y | | -| 1 | Data structure ( Always equal to 0) | y | | -| 2,3 | Number of bytes | y | | -| 4 | System Config (0x10100011[^system_config]) | y | | -| 5,6 | X velocity bottom | y | mm/s | -| 7,8 | Y velocity bottom | y | mm/s | -| 9,10 | Z velocity bottom | y | mm/s | -| 11,12 | E velocity bottom | y | mm/s | -| 13,14 | BM1 range to bottom | y | cm | -| 15,16 | BM2 range to bottom | y | cm | -| 17,18 | BM3 range to bottom | y | cm | -| 19,20 | BM4 range to bottom | y | cm | -| 21 | Bottom status | y | bool | -| 22,23 | X-Velocity reference layer | n | | -| 24,25 | Y-Velocity reference layer | n | | -| 26,27 | Z-Velocity reference layer | n | | -| 28,29 | E-Velocity reference layer | n | | -| 30,31 | Reference layer start | n | | -| 32,33 | Reference layer end | n | | -| 34 | Reference layer status | n | | -| 35 | Time of first ping - hour | y | hours | -| 36 | Time of first ping - minute | y | minutes | -| 37 | Time of first ping - second | y | seconds | -| 38 | Time of first ping - hundreths | y | centi-seconds | -| 39,40 | Bit result | n | | -| 41,42 | Speed of Sound | y | m/s | -| 43,44 | Temperature | n | | -| 45,46 | Checksum | y | N/A | - -#### Notes -To use the BM1-BM4 correctly you should use this translation. The numbering comes from the Transducer numbering (see image below) -**BM1** is transducer 3 -**BM2** is transducer 1 -**BM3** is transducer 4 -**BM4** is transducer 2 -![dvl_a50_transducer_numbering](../img/WL-21035-3_DVL-A50_Front_1600_transducers_crop.jpg) - - - - -[^system_config]: Tells that the velocities are in ship coordinates, Tilt is used, Three beam not computed, and 600 Khz diff --git a/docs/dvl/dvl-troubleshooting.md b/docs/dvl/dvl-troubleshooting.md deleted file mode 100644 index ae46fb0c..00000000 --- a/docs/dvl/dvl-troubleshooting.md +++ /dev/null @@ -1,51 +0,0 @@ -# DVL Troubleshooting - -## Is my DVL faulty? - -Below is a small list to check if your DVL is not performing as expected or you are experiencing any issues. It starts with the basic before moving on to more advanced troubleshooting. When you come to the point of failure or if the troubleshooting do not help, please submit a support ticket to our support team through our [Support portal](https://waterlinked.com/support). Please write what you are experiencing and how you tested/used the DVL when you experienced the issue. - -In the Support Portal please describe the test environment or test setup you have used and how the DVL is mounted. If possible, open the DVL GUI and go to Diagnostic Log in the left menu. Press the Create Diagnostic Report button. This will automatically record a log file that you can download to your computer. Please add the [Diagnostic reports](gui/diagnostic-report.md) and pictures of the test setup in the support portal. This will help our support team greatly! - -If the troubleshooting guide do not help, please check out [FAQ DVL](../dvl/faq.md)! - -### Check if DVL is powered -1. Put the DVL under water and power it on with an adequate power supply. - * Does the DVL pull any current? Expected current consumption: Approximate average 260mA at 18V - * Does the LED turn on? - -### LED -1. For LED status, see [LED Signals](interfaces.md#led-signals). - -### Wiring -1. Check that you have wired your DVL correctly, see [Wiring interface](interfaces.md#wiring-interface). - - 1.1 If you have a custom connector you need to ask the supplier for the correct drawings. -2. Check for damages along the cable and that there are good connection where you have terminated your DVL. -3. Check for short between Negative/Ground and Positive (10-30V). - -### Environmental Check -1. The Line of sight should be clear of any obstacles including walls, see [Line of sight](dvl-a50.md#line-of-sight). - - 1.1 One easy way to make sure the Line of sight is clear from any walls is to observe that all beam shows approximately the same distance to the bottom. If some of the beams are flickering or showing another distance it might pick up a reflection from a wall or some other obstacle in the line of sight. Obstacle free radius from the DVL to the wall depending on the distance to the bottom can be calculated with this formula: **Obstacle free radius** = tan(32.5°) × **distance from DVL to bottom**. -2. If testing in a pool, tank or bucket it should **not** be made out of a **polished metal** or very clean surfaces. This can introduce more noise and make it harder for the DVL to get a bottom lock. -3. Check that there are no motors, echo sunders, pumps, running hose. This can create noise in the same frequency as the DVL and have an impact on the acoustic signals. -4. Make sure the environment is not acting on the DVL in a way that makes it pitch and yaw (waves). That will send the acoustic signals in many directions making it hard to achieve a bottom lock. - -## Thermal Shutdown -The DVL has a thermal shutdown mechanism to avoid damage. It will issue a warning before shutting down at 55℃. Once it cools below 50℃, it automatically restarts. If the overheating issue is not addressed, it may repeat this shutdown/restart cycle. - -1. Is the DVL in water? If not it will overheat and enter a shutdown/restart cycle. - -## GUI -1. Connect your DVL yo Ethernet by following the Network documentation, see [Setup Network](networking.md#networking). Use the [Fallback IP](networking.md#fallback-ip) if you are struggling. - -2. You are able to access and see the Dashboard like displayed in our [Web Demo](https://dvl.demo.waterlinked.com/#/diagnostic). - -3. Check that you have the latest software, see [Software Updates](sw-update.md#software-updates) - - -## Collecting data -Assuming you have checked the above and that your testing environment will not affect the performance of the DVL, you can now start collecting data! - -1. Go into the [Diagnostic report](gui/diagnostic-report.md) and collect data. Fill the description with relevant information of the test environment and observed issue. -2. Take picture of the test environment and how DVL is mounted to bracket or ROV. -3. If there are known issues under certain conditions/setup please perform these tests as well and collect diagnostic reports. -4. Open a ticker through our support portal [Support portal](https://waterlinked.com/support) where you upload the diagnostic reports, pictures with a description of your issue. diff --git a/docs/dvl/gui/configuration.md b/docs/dvl/gui/configuration.md deleted file mode 100644 index dcda68b2..00000000 --- a/docs/dvl/gui/configuration.md +++ /dev/null @@ -1,34 +0,0 @@ -# Configuration - -Configuration of the DVL is available in the the GUI by pressing *Menu -> Configuration*. Output configuration is available by pressing *Menu -> Outputs* . Configuration can also be performed via the [DVL protocol](../dvl-protocol.md). - -## Screenshot - - -![](../../img/dvl_gui_configuration.png) - - -## Parameters - -Name | Description ------|------------ -Speed of sound | Speed of sound in the environment (sea water, fresh water etc) -Acoustic enabled | Enable/disable sending acoustic waves from the DVL -Mounting rotation offset | Configure DVL mounting direction in relation to vehicle. 0 if LED on DVL is pointing forward on the vehicle. See [axes](../axes.md) -Dark mode | Disable the LED to avoid interference with camera -Save drift compensation | Calibrate the gyro bias in the IMU. Place the DVL on a stationary surface (preferably at the environment operating temperature) and press the button. Recommended to improve [dead reckoning positioning estimation](../dead-reckoning.md) - -Advanced configuration - -Name | Description ------|------------ -Network configuration | Static IP address or get IP address from DHCP server -System time configuration | Configure Network time protocol (NTP) server to use or set time manually -Factory reset | Reset all configuration of the DVL. Reboot is required. -Reboot | Reboot the DVL - -!!!note "Recommended configuration when only serial port is used" - Configure network to "Static IP" to shorten boot time - -!!!note "Recommended configuration when only ethernet is used" - Configure serial output protocol to "Disabled" to lower latency for TCP protocol diff --git a/docs/dvl/gui/dashboard.md b/docs/dvl/gui/dashboard.md deleted file mode 100644 index 7c4b359d..00000000 --- a/docs/dvl/gui/dashboard.md +++ /dev/null @@ -1,51 +0,0 @@ -# Dashboard - -Both the DVL-A50 and the DVL-A125 have a web-based GUI. In your favorite web browser, simply navigate to the DVL's [IP address](../networking.md). - -The default page is a dashboard which provides a summary and visualisation of both the velocity and [dead reckoning](../dead-reckoning.md) data outputted by the DVL, as well as an indication of current status. - -## Screenshot - - -![](../../img/dvl_gui_dashboard.png) - -## Dashboard Parameters - -### Doppler Velocity -Parameter |Description -----------------------------------------|--------------------------------------------------------------------- -Speed | Combined speed from x, y, z velocities. -Altitude | Distance from seabed to DVL (unless beams blocked by something else). -Figure of merit (See note below) | Maximum uncertainty of measurement given in m/s. -Ping rate | Rate at which data velocity is being outputted (depends on velocity). -Velocity valid | Indicates if the velocity is valid to be used. - -!!! Note - Figure of merit (FOM) represent the maximum possible uncertainty and indicates the largest potential error in the measured speed from our DVL. This value is derived from the covariance matrix, which identifies the direction with the highest uncertainty in the sensor data. It provides a worst-case error margin. The maximum amount by which the actual speed may differ from the measured speed due to various factors from environment such as acoustic noise from other sources. - - - -### Dead reckoning -Parameter |Description -----------------------------------------|------------------------------------------------------------------------------------------------------------------------ -Speed | Speeds in x,y,z(Downward) directions with FOM that is the Euclidean norm of the standard deviations for each direction. -Position | Calculated position with FOM that is the Euclidean norm of the standard deviations for each direction. -Roll, pitch, Yaw | Orientation from the gyro. When dead reckoning is reset on the DVL, the gyro reinitializes its orientation. This means that the current orientation of the DVL at the time of reset will be set as the new zero orientation. - -### Horizontal velocity -Graphical indication of the horizontal direction of speed. - -## Vertical velocity -Graphical indication of the vertical velocity. - -## Map controls - -Button |Description -----------------------------------------|----------------------------------------------------------------- -+/-/[ ] |Zoom and fullscreen controls -![](../../img/dvl_gui_icon_arrow.png) | Center map to dvl position -![](../../img/dvl_gui_icon_reset.png) | Reset calculated position and start position tracking from zero. -... |More - |Set trail length - |Set grid size - |Calibrate gyro diff --git a/docs/dvl/gui/demo-gui.md b/docs/dvl/gui/demo-gui.md deleted file mode 100644 index db5e3c02..00000000 --- a/docs/dvl/gui/demo-gui.md +++ /dev/null @@ -1,3 +0,0 @@ -# Demo site - -We maintain a [demo](https://dvl.demo.waterlinked.com) of the DVL's GUI, running on simulated data. diff --git a/docs/dvl/gui/diagnostic-report.md b/docs/dvl/gui/diagnostic-report.md deleted file mode 100644 index 02931176..00000000 --- a/docs/dvl/gui/diagnostic-report.md +++ /dev/null @@ -1,9 +0,0 @@ -# Diagnostic report - -Allows for generation of a log file for sending to Water Linked customer support. - -Enter a small description of the problem you are experiencing, and then click on the button. Attach the generated `.wdat` file when contacting Water Linked support. - -## Screenshot - -![diagnostics_report](../../img/diagnostic_report_dvl.png) diff --git a/docs/dvl/interfaces.md b/docs/dvl/interfaces.md deleted file mode 100644 index 32098e3f..00000000 --- a/docs/dvl/interfaces.md +++ /dev/null @@ -1,148 +0,0 @@ -# Interfaces - -For both the DVL-A50 and the DVL-A125. - -## LED Signals - -* No green light: Power is off. - -* Fixed green light: The DVL is powering on. Depending on configuration it can take ~30-60 seconds to power on. - -* Flashing green light, mostly off (slow, every few seconds): DVL looking for bottom lock. - -* Flashing green light, mostly on (slow, every few seconds): DVL has bottom lock. - -* Flashing green light (fast, many times a second): DVL is in [thermal shutdown](dvl-troubleshooting.md#thermal-shutdown) - -## Wiring interface - -The tables below shows the pinning of the DVL interface. - -| Interface | Color | -| :------------------ | :-- | -| Negative/Ground | Black | -| Positive (10-30V) | Red | -| ETH RX+ | Green/White | -| ETH RX- | Green | -| ETH TX- | Orange | -| ETH TX+ | Orange/White | -| UART TX | Brown/White | -| UART RX | Brown | -| Shielded wire | Naked (silver) | - -#### Seacon MCOM8M Connector (DVL A50 only) -The table below shows the specific pinout for the Seacon MCOM8M connector. - -| Interface | Pin | -| :------------------ | :-- | -| Negative/Ground | 1 | -| Positive (10-30V) | 2 | -| ETH RX+ | 3 | -| ETH RX- | 4 | -| ETH TX- | 5 | -| ETH TX+ | 6 | -| UART TX | 7 | -| UART RX | 8 | - - -!!! Note - Power must be applied to the power terminals before applying voltage to UART pins - -## Shielded Cable Information - -The DVL is equipped with a shielded cable that helps protect the communication and power lines from external electromagnetic interference (EMI) and radio frequency interference (RFI). Please note that the DVL electronics themselves are not internally connected to the shield; it is up to the user to decide whether and how to connect the shield. - -!!! Note - For DVLA50, shielded cables were introduced autumn 2024 from serial number 30273 and upwards, and 05838 and upwards. - - DVLA50's with Seacon MCOMSM connector and DVLA50's made before autumn 2024 are delivered with unshielded cable. - - All DVLA125 are delivered with shielded cable. - -### Connecting the Shield - -For optimal performance, especially when mounted on an ROV (Remotely Operated Vehicle) or AUV (Autonomous Underwater Vehicle), it is recommended to connect the shield to reduce the impact of interference on the communication and power signals. The most common connection methods are: - -1. **Chassis Ground**: - Connecting the shield to the chassis of the ROV/AUV is the most typical practice. This method allows the shield to provide a path to ground for any noise or interference, helping to improve signal integrity. The ROV or AUV chassis often acts as a common reference point for grounding, which makes this a natural choice. - -2. **Common Ground**: - Alternatively, you can connect the shield to the common electrical ground of the ROV/AUV. This method may be used when the electrical and signal systems are designed to share a common ground. It helps ensure that interference is grounded without creating ground loops. - -### Recommendation - -We recommend connecting the shield to the **chassis ground** of the ROV or AUV (if possible). This approach generally provides the best noise suppression by using the vehicle’s structure as a solid grounding point. However, if your system design prefers the use of a common electrical ground, that option can also be considered. Always ensure that the shield is grounded at one end only to avoid ground loops, unless your system design calls for grounding at both ends for specific applications. - - -## Terminal Interface - -The DVL-A50 has a 3.3 volt UART interface (5V tolerant). - -| Settings | Value | -| :------------------ | :-- | -| Baud rate | 115200 | -| Data parity stop | 8N1 | -| Flow control | None | - -!!! Warning - There can be a momentary (<10 us) power spike (~5 V) on the UART lines when power is applied to the DVL, which may damage equipment which is not 5V tolerant. - -See the DVL's [serial protocol](dvl-protocol.md#serial-protocol). - -## Ethernet Interface - -See [networking](networking.md) and the DVL's [TCP protocol](dvl-protocol.md#json-protocol-tcp). - - -## Code examples - -[Code](https://github.com/waterlinked/dvl-python/tree/master/tcp) for parsing of the data outputted by the DVL over TCP. - - -## I/O interface - -The I/O Interface provides a simple means of connection to the Water Linked DVLs. It provides magnetics for the ethernet connection and utilizes the Molex Micro-Fit 3.0 power connector (Part number: 436500204) which is standard for Water Linked products. Female connectors is listed under [Mates with Part(s)](https://www.molex.com/en-us/products/part-detail/436500204#mates-with-use-with) - -There currently exists three revisions of the I/O Interface. Revision 2 and 3 are electrically identical. Revision 4 has an integrated USB-to-UART interface and a micro USB port. - -### Revision 4 - -![I/O_Interface_rev4](../img/WL-31014-4_IO_Interface_connections.png) - -Dimensions: 50.6 x 47 x 18.6 mm (Width x Height x Thickness) - -| Connector | Function | Comment | -| ------------------- | :--------- | :------ | -| RJ45 (8P8C) | Ethernet | 10/100 BASE-T | -| Micro USB | Serial | FTDI based | -| Molex Micro-Fit 3.0 | Power | 10 - 30 VDC | -| 2x Ø1.5mm pads | Alt. power | Fits [Würth 691137710002](https://octopart.com/691137710002-w%C3%BCrth+elektronik-78871135) | - -### Revision 3 - -![I/O_Interface_rev3](../img/WL-31014-3_IO_Interface_connections.png) - -Dimensions: 40 x 42 x 18.6 mm (Width x Height x Thickness) - -| Connector | Function | Comment | -| ------------------- | :--------- | :------ | -| RJ45 (8P8C) | Ethernet | 10/100 BASE-T | -| 3x1 header | Serial | TX, RX, GND | -| Molex Micro-Fit 3.0 | Power | 10 - 30 VDC | -| 2x Ø1.5mm pads | Alt. power | Fits [Würth 691137710002](https://octopart.com/691137710002-w%C3%BCrth+elektronik-78871135) | - -### Revision 2 - -![I/O_Interface_rev2](../img/WL-31014-2_IO_Interface_connections.png) - -Dimensions: 30.6 mm x 50 x 18.6 mm (Width x Height x Thickness) - -| Connector | Function | Comment | -| ------------------- | :--------- | :------ | -| RJ45 (8P8C) | Ethernet | 10/100 BASE-T | -| 3x1 header | Serial | TX, RX, GND | -| Molex Micro-Fit 3.0 | Power | 10 - 30 VDC | -| 2x Ø1.5mm pads | Alt. power | | - -!!! Note - The Molex Micro-Fit 3.0 on revision 2 is prone to damage by excessive sideways force. Take care not the yank the power cable when connected.