You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[](https://sonarcloud.io/summary/new_code?id=PonomarevDA_dronecan_application)[](https://sonarcloud.io/summary/new_code?id=PonomarevDA_dronecan_application)[](https://github.com/PonomarevDA/dronecan_application/actions/workflows/build.yml)[](https://github.com/PonomarevDA/dronecan_application/actions/workflows/check_crlf.yml)
2
-
3
-
# DroneCAN application
4
-
5
-
This is a C library with C++ helpers that brings up the [libcanard](https://github.com/dronecan/libcanard), platform-specific drivers and serialization together to build a minimal DroneCAN application.
6
-
7
-
A minimal application includes the following protocol-features:
# libdcnode [](https://sonarcloud.io/summary/new_code?id=PonomarevDA_libdcnode)[](https://sonarcloud.io/summary/new_code?id=PonomarevDA_libdcnode)[](https://github.com/PonomarevDA/libdcnode/actions/workflows/build.yml)
78
2
79
-
**1. Initialize**
3
+
Lightweight [DroneCAN / UAVCAN v0](https://dronecan.github.io/) node toolkit built on top of [libcanard](https://github.com/dronecan/libcanard), [platform_specific](platform_specific) and [libparams](https://github.com/PonomarevDA/libparams). It wraps the transport, exposes a small C API for node setup/spin, and offers C++ helpers for typed publishers/subscribers and logging.
80
4
81
-
Include `dronecan.hpp` header and call `uavcanInitApplication` in the beginning of the application. Call `uavcanSpinOnce` periodically.
82
-
83
-
```c++
84
-
// Include dronecan.hpp header file
85
-
#include"libdcnode/dronecan.h"
86
-
87
-
// Initialize the library somewhere
88
-
constuint8_t node_id = 42;
89
-
auto init_res = uavcanInitApplication(node_id);
90
-
if (init_res < 0) {
91
-
// handle error here
92
-
}
93
-
94
-
// Spin it periodically:
95
-
while (true) {
96
-
...
97
-
uavcanSpinOnce();
98
-
...
99
-
}
100
-
```
5
+
## Features
101
6
102
-
**2. Add publisher**
7
+
- Implements core DroneCAN services out of the box: [NodeStatus](https://legacy.uavcan.org/Specification/7._List_of_standard_data_types/#nodestatus), [GetNodeInfo](https://legacy.uavcan.org/Specification/7._List_of_standard_data_types/#getnodeinfo), [Param.GetSet and Param.ExecuteOpcode](https://legacy.uavcan.org/Specification/7._List_of_standard_data_types/#uavcanprotocolparam), [RestartNode](https://legacy.uavcan.org/Specification/7._List_of_standard_data_types/#restartnode), and [GetTransportStats](https://legacy.uavcan.org/Specification/7._List_of_standard_data_types/#gettransportstats).
8
+
- Platform abstraction (`include/libdcnode/platform.hpp`) so you can plug in your own timing, reset, unique-ID, and CAN driver callbacks.
9
+
- Templated C++ wrappers for publishing/subscribing (`include/libdcnode/pub.hpp`, `include/libdcnode/sub.hpp`) with optional filters and periodic senders; legacy interfaces remain in `include/libdcnode/publisher.hpp` and `include/libdcnode/subscriber.hpp`.
10
+
- Debug logger (`include/libdcnode/logger.hpp`) that publishes `uavcan.protocol.debug.LogMessage` with severity helpers.
11
+
- DSDL compiler baked into the build (`Libs/dronecan_dsdlc`) so message code is generated during CMake configure.
103
12
104
-
Adding a publisher is very easy. Include `publisher.hpp` header, create an instance of the required publisher and just call `publish` when you need. Here is a BatteryInfo publisher example:
13
+
## Repository layout
105
14
106
-
```c++
107
-
#include"libdcnode/dronecan.h"
108
-
#include"libdcnode/publisher.hpp"
15
+
-`src/`: core node implementation (`dronecan.cpp`) and logger.
16
+
-`include/libdcnode/`: public headers (C API, C++ helpers, platform/params interfaces).
Adding a subscriber is easy as well. Let's consider a RawCommand subscriber example. Include `subscriber.hpp` header, create a callback for your application and instance of the required subscriber, then initilize it.
Sometimes for subscriber you want to specify a filter. For example, you may want to subscribe on a specific command channel or sensor ID. Let's consider an ArrayCommand example with filter that will only pass the messages with actuator ID = 0.
During configure, DSDL code is generated into `build/generated/libdcnode/serialization` using `Libs/dronecan_dsdlc/dronecan_dsdlc.py`. If you add custom DSDL namespaces, point `DSDL_IN_DIR` (see `CMakeLists.txt`) to your set or rerun `scripts/code_generation.sh` with your paths.
174
31
175
-
**Run example**
32
+
## Usage example
176
33
177
-
You can run a provided example in SITL mode. Just run:
34
+
The `examples/ubuntu` target demonstrates the C API plus the modern C++ pub/sub wrappers.
The example wires a simple parameter set, binds platform callbacks, subscribes to actuator/ESC/light commands, and periodically publishes battery and circuit status messages while spinning the node.
> You can find the provided SITL application in [examples/ubuntu](examples/ubuntu) folder.
54
+
## Testing
193
55
194
-
## Platform specific notes
195
-
196
-
There are a few functions that require an implementation. They are declared in [include/application/internal.h](include/application/internal.h).
56
+
```bash
57
+
python3 -m venv .venv &&source .venv/bin/activate
58
+
pip install -r requirements-dev.txt
59
+
scripts/vcan.sh slcan0 # once, requires sudo
60
+
pytest tests/smoke_socketcan.py
61
+
```
197
62
198
-
A user must provide the following function implementation:
63
+
The smoke tests expect the Ubuntu example (node ID 50 on `slcan0`) to be running; they verify `NodeStatus` and `GetNodeInfo` responses via the `dronecan` Python client.
199
64
200
-
```c++
201
-
/**
202
-
* @return the time in milliseconds since the application started.
203
-
* @note This function must be provided by a user!
204
-
*/
205
-
uint32_tplatformSpecificGetTimeMs();
206
-
```
65
+
## Changelog
207
66
208
-
A user may also provide the implementation of the optional functions. These function have a weak implementation in [src/weak.c](src/weak.c).
209
-
210
-
```c++
211
-
/**
212
-
* @return whether the request will be processed
213
-
* True - the application will be restarted soon.
214
-
* False - the restarted is not supported or can't be handled at the moment.
215
-
* @note Implementation is recommended, but optional.
216
-
*/
217
-
boolplatformSpecificRequestRestart();
218
-
219
-
/**
220
-
* @param[out] out_id - hardware Unique ID
221
-
* @note Implementation is recommended, but optional.
|[v0.6.0](https://github.com/PonomarevDA/libdcnode/tree/v0.6.0)| 2025-10-17 | Build model changed: standalone library; platform hooks provided by user (no more source-include mode). |
71
+
|[v0.5.0](https://github.com/PonomarevDA/libdcnode/tree/v0.5.0)| 2024-09-26 | Decoupled the platform specific functions from the library |
72
+
|[v0.4.0](https://github.com/PonomarevDA/libdcnode/tree/v0.4.0)| 2024-07-29 | Added macro helpers for pub and sub traits |
|[v0.2.0](https://github.com/PonomarevDA/libdcnode/tree/v0.2.0)| 2024-01-06 | Add bxcan and fdcan drivers |
75
+
|[v0.1.0](https://github.com/PonomarevDA/libdcnode/tree/v0.1.0)| 2023-12-22 | First public drop; pure C, manual serialization, and source-include usage (include the C sources into your app). |
0 commit comments