diff --git a/dispersion_protocol/autopilot_connected_hardware_config.png b/dispersion_protocol/autopilot_connected_hardware_config.png new file mode 100644 index 0000000..0c6daa6 Binary files /dev/null and b/dispersion_protocol/autopilot_connected_hardware_config.png differ diff --git a/dispersion_protocol/control_sequence.png b/dispersion_protocol/control_sequence.png new file mode 100644 index 0000000..f5f20ec Binary files /dev/null and b/dispersion_protocol/control_sequence.png differ diff --git a/dispersion_protocol/discovery_sequence.png b/dispersion_protocol/discovery_sequence.png new file mode 100644 index 0000000..9ccfb4e Binary files /dev/null and b/dispersion_protocol/discovery_sequence.png differ diff --git a/dispersion_protocol/hardware_config.png b/dispersion_protocol/hardware_config.png new file mode 100644 index 0000000..34f84c4 Binary files /dev/null and b/dispersion_protocol/hardware_config.png differ diff --git a/dispersion_protocol/microservice.md b/dispersion_protocol/microservice.md new file mode 100644 index 0000000..368faf3 --- /dev/null +++ b/dispersion_protocol/microservice.md @@ -0,0 +1,250 @@ +# Dispersion Microservice + +## Introduction + +The dispersion protocol allows MAVLink control over the dispersion devices mounted on a vehicle from a variety of sources. The dispersion state can be managed manually by an operator in real time or set as part of an auto mission. + +The protocol defines what information is published, in what order for key workflow sequences for developers, configurators, and users of the vehicle. It also defines a logging framework for storage of that information. + +The protocol supports a variety of hardware configurations, and enables dispersion systems with a variety of capabilities. + +## Concepts + +Key Terms: + +| Term | Description | +| :-------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Dispersion Device | A system containing one chemical mixture and the infrastructure to deliver that to a field | +| Dispersion Component (aka Subcomponent) | A discrete unit of the dispersion device that has independent dispersion rate control. Depending on the hardware configuration, there could be no subcomponents, all the way to a subcomponent per nozzle for independent nozzle control. | + +There are a few ways to interact with the dispersion device that can be categorized as follows: + +- hardware configuration - low frequency device hardware changes that impact the behavior of dispersion device for long periods of time. These parameters are managed via [Parameter Protocol](https://mavlink.io/en/services/parameter.html). +- job configuration - optional use of prescription maps to define expected dispersion device behavior. These are managed via the [File Transfer Protocol](https://mavlink.io/en/services/ftp.html). +- navigation - high frequency messages providing real time vehicle navigation information to the device for making real time corrections +- control - optional use of MAVLink commands to make adjusts to dispersion behavior or control behavior through automated mission plans +- locking - provides a locking and unlocking mechanism, that ensures the dispersion device stops dispersing and does not respond to control messages when locked +- status - custom MAVLink messages are used to report the device state at a scheduled interval or on key events +- logging - all dispersion related mavlink messages are logged and that data can be managed via the [File Transfer Protocol](https://mavlink.io/en/services/ftp.html). + +### Hardware Set-ups + +The protocol can be used with either standalone MAVLink dispersion devices, or devices that are directly connected to autopilot I/O. The two approaches are described below. + +> **NOTE** +> This protocol is designed to work best with a standalone MAVLink dispersion device that shares a high throughput, low latency communication bus with its controller. While any MAVLink source can be used to control the device, a common configuration is to have an autopilot providing critical real time vehicle position and trajectory data and a user interface to manage locking or low frequency control and configuration. + +#### MAVLink Dispersion Device + +The protocol can be used to support independent MAVLink dispersion devices. + +The device will need to have the same system ID as the autopilot and should use one of the dispersion device component IDs (these need to be configurable for support of multiple dispersion devices on one system). + +Commonly the device is connected to the autopilot via a (relatively high speed) local serial link. The autopilot must forward commands from a ground station and telemetry from the device. When executing missions, the autopilot will need to re-emit mission items as command protocol commands when connected to a MAVLink dispersion device. These should be addressed to the targeted device. + +It is also common to connect the dispersion device, autopilot, and ground station to a common communication bus in such a way the autopilot does not have to relay messages to and from the dispersion device. For example all devices could communicate MAVLink via a shared LAN or have a bridge into that LAN. In this situation, all messages going to and from the dispersion device can be put on this shared communication bus and assume the relevant subscriber will be able to access it. The autopilot will still need to provide the necessary vehicle telemetry and, when relevant to a mission, the necessary mission items as command protocol commands. + +> **NOTE** +> This is why commands used in missions need a target dispersion component id - otherwise you can't send to a particular dispersion device from a mission + +![standalone dispersion device connected to an autopilot and gcs mavlink node](hardware_config.png) + +#### Autopilot-connected Dispersion Device + +Dispersion devices that don't support a MAVLink interface may still be controllable via autopilot I/0 (via some other protocol/custom driver). For these devices the autopilot can act as a dispersion device with respect to ground stations and other external MAVLink systems. In this case the autopilot should emit COMPONENT_BASIC_INFORMATION, DISPERSION_DEVICE_INFORMATION, DISPERSION_DEVICE_STATUS and respond to commands MAV_CMD_DO_SET_DISPERSION_TARGETS and MAV_CMD_SET_DISPERSION_LOCK from a ground station. Instead of forwarding commands from a GCS or mission items during a mission, it will execute them on the connected dispersion hardware (ie PWM controlled dispersion motor) via the autopilot driver. It is expected that an autopilot driver will likely have to provide invalid values for things like droplet size limits, pressure limits, and tank capacity in their messages. As long as the associated dispersion type fields and capability flags are consistent with what functionality is not supported, this is valid. To help with discovery, it is expected that COMPONENT_BASIC_INFORMATION is supported with reasonable defaults (ie vendor_name="Dispersion Driver", model_name"Default") to indicate this dispersion device is really just a collection of relevant hardware controlled by the autopilot rather than a stand alone manufactured device. + +![autopilot connected dispersion device](autopilot_connected_hardware_config.png) + +### Hardware Configuration + +A dispersion device can take many form factors with spray devices being the most variable. It is very common to have different spray boom widths and variable nozzle spacing. Each nozzle can also have a unique limit range for flow rate, pressure, and droplet size. Since you might have anywhere from one nozzle to a couple hundred nozzles. While this hardware configuration can change, it is not typically during the middle of a job and is something you would expect to persist through power cycles. That makes the [Parameter Protocol](https://mavlink.io/en/services/parameter.html) a really good candidate for this scenario. It also provides a good infrastructure to save common configurations as param files. + +### Job Configuration + +There is job specific information that sometimes must be provided to the dispersion device before each mission but does not belong in the real time control messages during the mission. This information should make use of the [Parameter Protocol](https://mavlink.io/en/services/parameter.html) when possible. At the time of writing, the only known case that would not work for the [Parameter Protocol](https://mavlink.io/en/services/parameter.html) is delivering prescription maps to the dispersion device. These files should be provided through the [File Transfer Protocol](https://mavlink.io/en/services/ftp.html) infrastructure to the workspace url provided in [DISPERSION_DEVICE_INFORMATION](#dispersion_device_information). + +### Operation + +A dispersion device has 3 primary methods for accomplishing its task. The first method relies on direct manual control via a MAVLink command to assign dispersion targets for every subcomponent of the dispersion device. This concept applies to devices ranging from no subcomponent to hundreds. You would typically only see this used when making minor corrections to a specific component or you apply the same requirements to all subcomponents. The second method relies on automated control from an autopilot. In this case, the autopilot provides a MAVLink command to assign dispersion targets for every subcomponent of the dispersion device as specific location. Since the autopilot only has vehicle position estimations and no sense of each individual subcomponent position, you would typically only see this used when it applies to all subcomponents. Internally the dispersion device can make additional corrections to heading changes. The third method requires a prescription map be provided to the dispersion device and the vehicle to provide kinematic information. The dispersion device can account from prescription expectation, vehicle kinematics, and hardware configuration to deliver individualized component control. + +### Logging + +To accommodate the creation of effectiveness and compliance reports for a specific application, a mini logging infrastructure is proposed. Effectively all MAVLink messages as handled by the Dispersion Device should be logged into a binary file that can then be retrieved using the [File Transfer Protocol](https://mavlink.io/en/services/ftp.html) pointed at the workspace directory url found in [DISPERSION_DEVICE_INFORMATION](#dispersion_device_information). This logging logic should take place within the Dispersion Device. See [logging implementation details](#logging-implementation). + +## Implementation and Messages + +### Discovery of Dispersion Device + +The MAVlink nodes that need to communicate with Dispersion Devices start the process by sending a broadcast [MAV_CMD_REQUEST_MESSAGE](https://mavlink.io/en/messages/common.html#MAV_CMD_REQUEST_MESSAGE) for [COMPONENT_BASIC_INFORMATION](https://mavlink.io/en/messages/common.html#COMPONENT_INFORMATION_BASIC). Every dispersion device should respond with a [COMPONENT_BASIC_INFORMATION](https://mavlink.io/en/messages/common.html#COMPONENT_INFORMATION_BASIC). For more information specific to the dispersion device and its capability, a [MAV_CMD_REQUEST_MESSAGE](https://mavlink.io/en/messages/common.html#MAV_CMD_REQUEST_MESSAGE) for [DISPERSION_DEVICE_INFORMATION](#dispersion_device_information) should be sent. The target dispersion device should respond with [DISPERSION_DEVICE_INFORMATION](#dispersion_device_information) for each component. A component id of zero indicates the message represents the device as a whole. + +The MAVLink node should then create as many interface instances as Dispersion Devices found. + +![sequence diagram for discovering a dispersion device](discovery_sequence.png) + +### Control of a Dispersion Device + +Device control refers to messages that can change the state of the dispersion device and its subcomponents. There are only two types of control messages: the [MAV_CMD_DO_SET_DISPERSION_TARGETS](#mav_cmd_do_set_dispersion_targets) message for assigning a target dispersion rate and the [MAV_CMD_SET_DISPERSION_LOCK](#mav_cmd_set_dispersion_lock) for locking the dispersion device in case of unexpected behavior. The lock message always takes precedence so if the device or its components is locked, all dispersion will cease and all incoming control messages that are not "unlock" will be ignored. The lock is intended to serve as an emergency off. When the system is unlocked, the dispersion device will respond to control messages in the order that they are received no matter the source. When it comes to precision dispersion, low latency is critical. If you are applying a payload at 15m/s and want to have an uncertainty at the CM level, the overall latency from position measurement to action must be approximately 1/100th of a second. There are obviously many levers an end user can pull to account for higher latency, but it is worth noting effort should be made to reduce this latency. It is recommended position gates are anticipated on the autopilot and blocking receives are utilized on the dispersion device. There should be a low latency communication bus between the two. + +All control messages are handled via the pre-existing [MAVLink command microservice](https://mavlink.io/en/services/command.html). Autopilots can also use the mavlink command [MAV_CMD_DO_SET_DISPERSION_TARGETS](#mav_cmd_do_set_dispersion_targets) for real time dispersion device control in automated missions. + +![sequence diagram for control messages](control_sequence.png) + +> **NOTE** +> Be disciplined about conflicting control sources that are not the lock, as they will be processed in the order in which they are received. So if multiple controller instances of a given type exist, take care to keep them stateless or synchronize their state. For example, if there are multiple user interfaces with dispersion on/off buttons, it is critical that the button either always send the same command or if it changes between "dispersion on" and "dispersion off" depending on the current dispersion device state, that all interfaces reflect the same value. + +> **NOTE** +> The [MAV_CMD_SET_DISPERSION_LOCK](#mav_cmd_set_dispersion_lock) messages should only be used as an emergency shutoff. All normal control should happen through the [MAV_CMD_DO_SET_DISPERSION_TARGETS](#mav_cmd_do_set_dispersion_targets) message. As an example, the lock message should be used to shut off the spray system when taking fallback actions like landing in place or returning home. The lock should not be used to turn the dispersion on or off at waypoints in an automated mission. In fact, a normal mission in general should never need to use the lock. + +### Autopilot State for Dispersion Device + +The autopilot should send the [GLOBAL_POSITION_INT_COV](#https://mavlink.io/en/messages/common.html#GLOBAL_POSITION_INT_COV) or [LOCAL_POSITION_NED_COV](#https://mavlink.io/en/messages/common.html#LOCAL_POSITION_NED_COV) message to the dispersion device. This data is required by the Dispersion Device control system to make effective dynamic dispersion rate corrections based on system current velocity. This message is not as critical as the timing for dispersion on and off but it does have an impact on coverage quality. A relatively low rate publish frequency of 10Hz or faster is likely ample since extrapolation can be utilized. + +### Dispersion Device Broadcast/Status Messages + +The dispersion device should send out its status in [DISPERSION_DEVICE_STATUS](#dispersion_device_status) at a low regular rate (e.g. 5 Hz) but also during key events such as a mavlink command, flag change, or rapid pressure change. + +This message is meant as broadcast, so it's sent to all parties on the network. + +## Messages/Command/Enum Summary + +This is the set of messages/enums for communication between a mavlink node and a dispersion device. + +| Message | Description | +| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [DISPERSION_DEVICE_INFORMATION](#dispersion_device_information) | Information about the dispersion device. This message should be requested by some source such as a ground control station using [MAV_CMD_REQUEST_MESSAGE](https://mavlink.io/en/messages/common.html#MAV_CMD_REQUEST_MESSAGE). The min/max limits for dispersion rate and pressure are driven by the underlying hardware. Software defined limits will be a subset of the limits specified here. | +| [DISPERSION_DEVICE_STATUS](#dispersion_device_status) | Message reporting the status of a dispersion device. This message should be published at a low regular rate (e.g. 5 Hz) but also during key events. | +| [GLOBAL_POSITION_INT_COV](#https://mavlink.io/en/messages/common.html#GLOBAL_POSITION_INT_COV) or [LOCAL_POSITION_NED_COV](#https://mavlink.io/en/messages/common.html#LOCAL_POSITION_NED_COV) | Message containing autopilot state relevant for a dispersion device. This message is to be sent from the autopilot to the dispersion device component. The data of this message are for the dispersion device estimator corrections, in particular speed compensation. | +| [COMPONENT_BASIC_INFORMATION](https://mavlink.io/en/messages/common.html#COMPONENT_INFORMATION_BASIC) | Message providing basic information about a MAVLink component. This message is meant to be sent by the dispersion device on request via [MAV_CMD_REQUEST_MESSAGE](https://mavlink.io/en/messages/common.html#MAV_CMD_REQUEST_MESSAGE). | + +| Command | Description | +| :-------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [MAV_CMD_REQUEST_MESSAGE](https://mavlink.io/en/messages/common.html#MAV_CMD_REQUEST_MESSAGE) | Request the target system(s) emit a single instance of a specified message. This is used to request [DISPERSION_DEVICE_INFORMATION](#dispersion-device-information). | +| [MAV_CMD_DO_SET_DISPERSION_TARGETS](#mav_cmd_do_set_dispersion_targets) | Command to provide real time adjustment to dispersion device and subcomponent output. | +| [MAV_CMD_SET_DISPERSION_LOCK](#mav_cmd_set_dispersion_lock) | Command for locking/unlocking the device from responding to [MAV_CMD_DO_SET_DISPERSION_TARGETS](#mav_cmd_do_set_dispersion_targets) messages. When locked, the device should stop dispersing. | + +| Enum | Description | +| :---------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------- | +| [DISPERSION_DEVICE_CAP_FLAGS](#dispersion_device_cap_flags) | Dispersion device capability flags (bitmap). Used in [DISPERSION_DEVICE_INFORMATION](#dispersion_device_information). | +| [DISPERSION_DEVICE_STATUS_FLAGS](#dispersion_device_status_flags) | Flags for dispersion device operation (bitmap). Used in [DISPERSION_DEVICE_STATUS](#dispersion_device_status). | +| [DISPERSION_DEVICE_ERRORS](#dispersion_device_errors) | Dispersion device error flags (bitmap, 0 means no error). Used in [DISPERSION_DEVICE_STATUS](#dispersion_device_status). | +| [DISPERSION_DEVICE_WARNINGS](#dispersion_device_warnings) | Dispersion device warning flags (bitmap, 0 means no warning). Used in [DISPERSION_DEVICE_STATUS](#dispersion_device_status). | +| [MAV_DISPERSION_TYPE](#mav_dispersion_type) | The dispersion type a device is setup for. Dispersion types specify the units for capacity and dispersion rate. | + +## How to Implement the Dispersion Device Interface + +### Microservice Dependencies + +The dispersion device is targeted to be a stand alone MAVLink device meaning it needs to support some existing MAVLink microservices beyond the dispersion microservice outlined above. The following microservices are required: + +- [Heartbeat/Connection](https://mavlink.io/en/services/heartbeat.html) +- [Command](https://mavlink.io/en/services/command.html) +- [File Transfer Protocol](https://mavlink.io/en/services/ftp.html) +- [Ping](https://mavlink.io/en/services/ping.html) +- [Time Synchronization](https://mavlink.io/en/services/timesync.html) +- [Parameter Protocol](https://mavlink.io/en/services/parameter.html) + +> **NOTE** +> There is not a microservice definition for this but there is a requirement to support [COMPONENT_INFORMATION_BASIC](https://mavlink.io/en/messages/common.html#COMPONENT_INFORMATION_BASIC) + +### Device Parameters (Hardware Configuration) + +A dispersion device can take many form factors with spray devices being the most variable. It is very common to have different spray boom widths and variable nozzle spacing. Each nozzle can also have a unique limit range for flow rate, pressure, and droplet size. Since you might have anywhere from one nozzle to a couple hundred nozzles. While this hardware configuration can change, it is not typically during the middle of a job and is something you would expect to persist through power cycles. That makes the [Parameter Protocol](https://mavlink.io/en/services/parameter.html) a really good candidate for this scenario. It also provides a good infrastructure to save common configurations as param files. + +The definition of these parameters is an implementation detail so only a potential example parameter set for hardware configuration is proposed. It might look something like as follows: + +| Name | Type | Units | Values | Description | +| :------------------------------- | :------ | :------------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| FILL_CAPACITY_MAX | `float` | liters or kg | positive | Maximum fill capacity of this device in Liters for sprayers and Kg for spreaders. Units are determined based on the DISPERSION_DEVICE_CAP_FLAGS. (liters or kg) | +| SUBCOMPONENT_COUNT | `float` | | | Number of subcomponents this device has. | +| COMPONENT_1_OFFSET_X | `float` | m | positive | component 1 x position offset relative to device in meters | +| COMPONENT_1_OFFSET_Y | `float` | m | positive | component 1 y position offset relative to device in meters | +| COMPONENT_1_OFFSET_Z | `float` | m | positive | component 1 z position offset relative to device in meters | +| COMPONENT_1_RATE_MAX | `float` | liters/min or kg/min | positive | Maximum dispersion rate component 1 supports | +| COMPONENT_1_RATE_MIN | `float` | liters/min or kg/min | positive | Minimum dispersion rate component 1 supports | +| COMPONENT_1_PRESSURE_MAX | `float` | Pa | positive | Maximum pressure component 1 supports | +| COMPONENT_1_PRESSURE_MIN | `float` | Pa | positive | Minimum pressure component 1 supports | +| COMPONENT_1_DROPLET_DIAMETER_MAX | `float` | um | positive | Maximum droplet diameter component 1 supports | +| COMPONENT_1_DROPLET_DIAMETER_MIN | `float` | um | positive | Minimum droplet diameter component 1 supports | +| ... | ... | ... | ... | ... | + +### Logging Implementation + +#### File Management + +The dispersion device must be hosting a MAVFTP server to facilitate the offloading of generated log data. + +The device should be continuously logging every message in full fidelity to a binary file with the extension as documented in the file format section below using a rotating file handler that caps the file size to limit based on underlying compute specifications. There should be an additional limit to the number of files allowed before the oldest file is replaced. Each filename should end with its count like follows: log.bin, log.bin.1, log.bin.2, etc. It is recommended each file have a unique name by giving the base name a suffix of the created timestamp per the [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339) spec format. So an example file name might look like "dispersion_1996-12-19T16:39:57.112.bin.12". + +The implementation should support a more efficient logging method option for applications where memory efficiency is incredibly important. Such a logging implementation could store key events at a minimum to provide enough information to construct effective coverage reports while dropping regularly published data that has no meaningful events. + +#### Log File Format + +[Target File Format Spec](https://github.com/flocked-agriculture/mavlink_utils/wiki/Mavlink-Logger#file-format) + +### Messages to Send + +The messages listed below should be broadcast on the network/on all connections (sent to everyone). This set is not comprehensive in that it does not necessarily reiterate what is already defined in the pre-existing microservices documented as a dependency above. It is expected those messages get implemented as well. + +[HEARTBEAT](https://mavlink.io/en/messages/common.html#HEARTBEAT) + +Heartbeats should always be sent (usually at 1 Hz). + +> **WARNING** +> Dispersion devices that set their `sysid` from the autopilot will need to wait for the autopilot's heartbeat before emitting their own (note that if the dispersion device can receive heartbeats from multiple autopilots then the `sysid` must be explicitly/statically configured). + +- `sysid`: the same sysid as the autopilot (this can either be done by configuration, or by listening to the autopilot's heartbeat first and then copying the sysid, default: 1) +- `compid`: [MAV_COMP_ID_DISPERSIONER](#mav_comp_id_dispersioner) +- `type`: [MAV_TYPE_DISPERSION](#mav_type_dispersion) +- `autopilot`: [MAV_AUTOPILOT_INVALID](https://mavlink.io/en/messages/common.html#MAV_AUTOPILOT_INVALID) +- `base_mode`: 0 +- `custom_mode`: 0 +- `system_status`: `MAV_STATE_UNINIT` + +[DISPERSION_DEVICE_STATUS](#dispersion_device_status) + +The dispersion device status should be published a low regular rate (e.g. 5 Hz) but also during key events such as a mavlink command, flag change, or rapid pressure change for each subcomponent and the device itself. + +> **IMPORTANT** +> When publishing the status message in response to key events, it is essential that the status message timestamp aligns with when that event was enacted otherwise leading and falling edge detection during post processing of the data will incorrectly represent the world. + +[COMPONENT_BASIC_INFORMATION](https://mavlink.io/en/messages/common.html#COMPONENT_INFORMATION_BASIC) + +This information should be published in response to a [MAV_CMD_REQUEST_MESSAGE](https://mavlink.io/en/messages/common.html#MAV_CMD_REQUEST_MESSAGE) on startup. + +[DISPERSION_DEVICE_INFORMATION](#dispersion_device_information) + +The static information about the dispersion device needs to be sent out when requested using [MAV_CMD_REQUEST_MESSAGE](https://mavlink.io/en/messages/common.html#MAV_CMD_REQUEST_MESSAGE). + +### Messages to Listen To/Handle + +This set is not comprehensive in that it does not necessarily reiterate what is already defined in the pre-existing microservices documented as a dependency above. It is expected those messages get implemented as well. + +[GLOBAL_POSITION_INT_COV](#https://mavlink.io/en/messages/common.html#GLOBAL_POSITION_INT_COV) or [LOCAL_POSITION_NED_COV](#https://mavlink.io/en/messages/common.html#LOCAL_POSITION_NED_COV) + +One of the above two messages must be provided by the autopilot so the dispersion device can correct the dispersion behavior to account for changes in vehicle performance. The GLOBAL_POSITION_INT_COV should be provided if the reference frame for the system is MAV_FRAME_GLOBAL and the LOCAL_POSITION_NED_COV should be used if the reference frame for the system is MAV_FRAME_LOCAL_NED. + +The device should utilize which message is provided to determine its coordinate frame and then confirm there is no inconsistency in expected coordinate frame across all the data it will use to accomplish the task. + +If this message the rate is not ok, the command [MAV_CMD_SET_MESSAGE_INTERVAL](https://mavlink.io/en/messages/common.html#MAV_CMD_SET_MESSAGE_INTERVAL) can be used to request it at a certain rate. + +[COMMAND_LONG](https://mavlink.io/en/messages/common.html#COMMAND_LONG) + +The dispersion device needs to check for commands. See below which commands should get answered. + +### Commands to Answer + +[MAV_CMD_REQUEST_MESSAGE](https://mavlink.io/en/messages/common.html#MAV_CMD_REQUEST_MESSAGE) + +The dispersion device should send out messages when they get requested, e.g. DISPERSION_DEVICE_INFORMATION, [COMPONENT_BASIC_INFORMATION](https://mavlink.io/en/messages/common.html#COMPONENT_INFORMATION_BASIC). + +[MAV_CMD_SET_MESSAGE_INTERVAL](https://mavlink.io/en/messages/common.html#MAV_CMD_SET_MESSAGE_INTERVAL) + +The dispersion device should stream messages at the rate requested. + +[MAV_CMD_DO_SET_DISPERSION_TARGETS](#mav_cmd_do_set_dispersion_targets) + +Command to provide real time adjustment to dispersion device or subcomponent output. + +[MAV_CMD_SET_DISPERSION_LOCK](#mav_cmd_set_dispersion_lock) + +Command for locking/unlocking the device from responding to [MAV_CMD_DO_SET_DISPERSION_TARGETS](#mav_cmd_do_set_dispersion_targets) messages. When locked, the device should stop dispersing. diff --git a/text/0020-dispersion-payload.md b/text/0020-dispersion-payload.md new file mode 100644 index 0000000..a8fb5b8 --- /dev/null +++ b/text/0020-dispersion-payload.md @@ -0,0 +1,117 @@ +# Dispersion Payload Protocol + +- Start date: 2025-02-18 +- Contributors: Wesley Murray , ... +- Related issues: N/A + +## Summary + +The scope of this document is to define a message definition set and protocol for interacting with a dispersion payload to ensure effective control as well as compliance and efficacy reporting. The goal is to create an agreed-on standard for what data is necessary and how it should be used so that there can be more transparency in the UAV crop protection space. + +Here is the tentative [roadmap](https://docs.google.com/document/d/1s2IZq7PTo6RKCK9s6nvesvSOUHC8mK7Xy0dpXFQYWSA/edit?usp=sharing) for taking this concept from RFC to productions. + +## Motivation + +There is an increasing demand for using UAVs to deliver chemicals in agriculture for crop protection. This most commonly happens in the form of sprayers or spreaders. Sprayers are typically for liquid payloads and spreaders for granular solids. This has resulted in many indepent solutions to the problem, all using their own version of a black box. This often leaves aerial applicators unable to provide transparency into their service from a regulatory compliance side of things or for customer satisfaction in a situation where very hazardous chemical are frequently applied. This should not be the case. + +From the technical side of things, the concept of operations around agricultural applications provide the opportunity to push the techical envelope without a safety risk to people. Thus, expanding MAVLink support into the space will inherently increase adoption of MAVLink which will help validate other aspects of the standard in an unstructured enviornment. So putting a little investment in agriculture specific solutions IMO has out sized benefits. + +## Detailed Design + +### Background + +For those not familiar with aerial application in Agriculture, I strongly recommend using the [Aerial Applicator's Manual](https://www.epa.gov/system/files/documents/2023-11/national-aerial-applicator-manual-2014.pdf). Specifically Chapter 4. + +I used the [MAVLink Gimbal Protocol](https://mavlink.io/en/services/gimbal_v2.html) as my template. I must admit, I do not like the concept of splitting the manager and device. I think it over complicates the protocol but I still followed the pattern since there is context I am likely missing. In this PR you will see a proposal that is the device only, but adding on the manager layer is pretty trivial. That being said, I would like to see strong justification for the addition of a manager before I will agree to add it in during the implementation. + +### Test Cases + +A procotol can be very difficult to analyze in isolation so I started by creating the following set of test cases. These test cases are effectively situations and workflows the protocol must support to provide any value. I then used the proposed protocol to accomplish said test cases. This is an excellent review point for industry specific individuals who might not have a technical background. For those with a technical background this is still a useful starting point because it provides context. + +[x] user needs to manually rinse out the system and must be able to control via some sort of interface (physical or digital) +[x] user might need to stop spray mid flight for an emergency without the autopilot being able to override +[x] payload gets overfilled during servicing +[x] payload is not full enough when trying to take off +[x] clogged nozzle during flight +[x] motor (spray pump, or spreader motor) failure during flight +[x] spray system leaks +[x] autopilot control of spray system +[x] aircraft exceeds speed at which the device can keep up +[x] device is turned on before aircraft is at minimum speed +[x] dynamically adjust deposition rate based on aircraft speed +[x] get payload information for planning (ie lead in/out distances, spray leg length, etc) + +- Swath width will be configured during planning so OOS + +[x] data for compliance and efficancy reporting can be extracted + +- Factors that cannot be known by the dispersion device is OOS and can be collected in other parts of the system (ie wind, chemical being applied, etc) + +[x] payload is at target fill and ready to go +[x] spot spraying. This happens at the planning level. This protocol supports setting flow rate at specific locations which is enough for spot spraying. +[x] communication buses might be lossy so protocol must handle failure detection. +[x] ability to construct a synchronized timestamp across mavlink nodes to account for latency in commands when generating reports +[x] multiple dispersion devices are connected to the autopilot and need independent control +[x] a single dispersion device has multiple nozzles that require independent nozzle control +[x] the user can adjust droplet size on the ground station during a mission to account for changing wind conditions +[x] a dispersion device could correct flow rate for individual nozzles during turning +[x] a dispersion device can reduce overspray when intersecting an existing not perpendicular spray line by individually turning off one nozzle at a time +[x] protocol supports nozzle count of largest existing sprayer with some additional room for expansion + +### Implementation + +The target XML content can be found in [this public pull request](https://github.com/flocked-agriculture/mavlink/pull/1). + +After reviewing other submissions, I think I might have gone too far down this path but I wanted something complete to get reviewed by industry relevant people in my network before submitting here to the MAVLink community. I created a messages.md file with the full set of message definitions and a microservice.md file detailing how the protocol should work that is submitted with this PR. I have a couple of versions: one with a manager and one without. I used the one without because it is less complex and conveys the same concept. + +Every enum that is not a bitmask uses the zero value as a default UNKNOWN value. This, in my experience, results in more robust systems since it is very common to initialize values to zero in the background. Developers can miss this and if zero is a common valid value, the issue often wont surface until late run time. By having a default value that is useless, systems will almost immediately surface an error. + +This protocol should at a minimum support the capability of existing systems and then project into the future a little bit to be a timely, durable, and valuable solution. So, this protocol is designed to support a system with multiple dispersion devices and multiple subcomponents on that device. For the sake of this design, we consider a dispersion device to be a system containing one chemical mix and the infrastructure to deliver that to a field. The dipsersion device must have one gateway compute node that is responsible for communicating over a MAVLink interface. In the most simple form, a disperison device could be a microprocessor, tank, esc, motor, and spreader wheel that needs rate assigned at specific GPS locations but it can take on a more complex form factor for large ground based spray systems. These might have multiple feeder tanks with n number of subcomponents allowing independent control of subcomponent droplet size and flow rate to support many powerful features such as spot spraying and turn compenstation. + +### Questions + +1. ~~This is a combined protocol for spraying and spreading since there are many common elements. Should this be split up?~~ +1. ~~For any kind of effective reporting, not only do the messages needs to be defined but there should also be a degree of standardization on how that information gets logged so utilities can interact with it. Making logging suggestions seemed out of scope here but is there anything I should add to nudge people in the right direction?~~ +1. ~~Is a dispersion manager needed? I genuinely believe the source should not matter. Anything should be able to send a request and it get processed in the order it is received. The only time any prioritization should occur is manual triggers vs automated. No this could be handled through a manager but it is pretty easy implement with just the deivce using the MANUAL vs AUTO request type. I also expect there to be multiple possible viable sources for manual on/off live at any given moment. All should be immediately respected. I feel like the overhead with a manager only allowign two control sources could make this over complicated.~~ +1. Am I missing any critical workflows or test cases? Ie Debug level motor controller and motor information (deemed out of scope, should be a separate protocol for general motor controller and motor information) +1. ~~should we encourage using something like the parameter protocol rather than a command message for configuration?~~ +1. ~~with the device and device component architecture should I switch to manager/device concept~~ +1. with the device and device component sharing a message definition should I use FUEL_STATUS to handle fill level since it is only relevant to the device and not subcomponents? + +### Tentative Decisions + +1. this protocol supports the current state of aerial and ground spray systems +1. the protocol will combine spreader and sprayer into one with the addition of an enum indicating dispersion type in the relevant messages +1. dispersion payloads will be implemented as standalone MAVLink devices +1. a logging infrastructure is proposed +1. a dispersion manager will not be used +1. eliminated request message in favor of mav command infrastructure +1. the parameter protocol will be used for configuration since supporting devices with multiple independent sub components significant increased configuration overhead +1. unix timestamps will be used where possible to ensure accurate reporting on dispersion quality +1. switched status flags and error flags bitmask to continuous enums since almost all of the time the flags would be mutually exclusive. It is worth the size reduction. If multiple codes do happen at the same time, it is common to combine them into a unqiue enum or oscillate between the codes on publish. Warning flags were left as a bit mask since they dont block operation and can be ignored. This makes multiple overlapping warnings likely. +1. I will not be using the fuel status message since this dispersion device is not fuel and I believe the fuel status messages has an unnecessary amount of information. + +## Alternatives + +1. Do nothing. Solutions are already evolving organically. While the problem will be solved, it is subject to the issues documented in the motivation section. +1. Create documentation on how to use the generic payload messaging infrastructure to accomplish this goal. [ArduPilot Crop Sprayer](https://ardupilot.org/copter/docs/sprayer.html) + +## References + +- ISOBUS (HSI) Agriculture Comm Standards: https://www.aef-online.org/about-us/activities/high-speed-isobus.html +- Pix4D Spot Spraying Article: https://www.pix4d.com/blog/variable-rate-application-wheat-field/ +- Aerial Applicator's Manual: https://www.epa.gov/system/files/documents/2023-11/national-aerial-applicator-manual-2014.pdf +- MAVLink Gimbal Protocol: https://mavlink.io/en/services/gimbal_v2.html +- XAG P150: https://www.xa.com/en/p150 +- DJI Agras T40: https://www.dji.com/t40 +- Hylio: https://www.hyl.io/ +- Rotor: https://rotor.ai/ +- Guardian Agriculture: https://guardian.ag/ +- PYKA: https://www.flypyka.com/ +- TeeJet Dynajet: https://www.teejet.com/precision-farming/application-control-and-monitoring/dynajet +- TeeJet Precision Ag Products: https://www.farmco.com/price%20lists/teejet/2024%2009-01%20teejet%20precision%20picture%20price.pdf +- CPNozzles Accuflow: https://www.cpnozzles.com/products/accu-flo-nozzles/ + +## TODO + +1. um (micron) should be added as an allowed xml unit