forked from Archive/PX4-Autopilot
"MAVCAN" PNP & Register example implementation
This commit is contained in:
parent
e5d29d4079
commit
8b2d20df34
|
@ -32,10 +32,10 @@
|
|||
branch = master
|
||||
[submodule "src/drivers/uavcan_v1/libcanard"]
|
||||
path = src/drivers/uavcan_v1/libcanard
|
||||
url = https://github.com/PX4/libcanard.git
|
||||
url = https://github.com/UAVCAN/libcanard.git
|
||||
[submodule "src/drivers/uavcan_v1/public_regulated_data_types"]
|
||||
path = src/drivers/uavcan_v1/public_regulated_data_types
|
||||
url = https://github.com/PX4/public_regulated_data_types.git
|
||||
url = https://github.com/UAVCAN/public_regulated_data_types.git
|
||||
[submodule "src/modules/micrortps_bridge/micro-CDR"]
|
||||
path = src/modules/micrortps_bridge/micro-CDR
|
||||
url = https://github.com/PX4/Micro-CDR.git
|
||||
|
|
Binary file not shown.
|
@ -39,8 +39,8 @@ px4_add_git_submodule(TARGET git_public_regulated_data_types PATH ${DSDL_DIR})
|
|||
|
||||
find_program(NNVG_PATH nnvg)
|
||||
if(NNVG_PATH)
|
||||
execute_process(COMMAND ${NNVG_PATH} --templates ${CMAKE_CURRENT_SOURCE_DIR}/templates --outdir ${CMAKE_CURRENT_BINARY_DIR}/dsdlc_generated --target-language cpp -I ${DSDL_DIR}/uavcan ${DSDL_DIR}/regulated)
|
||||
execute_process(COMMAND ${NNVG_PATH} --templates ${CMAKE_CURRENT_SOURCE_DIR}/templates --outdir ${CMAKE_CURRENT_BINARY_DIR}/dsdlc_generated --target-language cpp ${DSDL_DIR}/uavcan)
|
||||
execute_process(COMMAND ${NNVG_PATH} --outdir ${CMAKE_CURRENT_BINARY_DIR}/dsdlc_generated --target-language c -I ${DSDL_DIR}/uavcan ${DSDL_DIR}/reg)
|
||||
execute_process(COMMAND ${NNVG_PATH} --outdir ${CMAKE_CURRENT_BINARY_DIR}/dsdlc_generated --target-language c ${DSDL_DIR}/uavcan)
|
||||
else()
|
||||
message(FATAL_ERROR "UAVCAN Nunavut nnvg not found")
|
||||
endif()
|
||||
|
|
|
@ -162,12 +162,12 @@ int16_t CanardSocketCAN::transmit(const CanardFrame &txf, int timeout_ms)
|
|||
_send_tv->tv_usec = txf.timestamp_usec % 1000000ULL;
|
||||
_send_tv->tv_sec = (txf.timestamp_usec - _send_tv->tv_usec) / 1000000ULL;
|
||||
|
||||
return sendmsg(_fd, &_send_msg, 0);
|
||||
return sendmsg(_fd, &_send_msg, 1000);
|
||||
}
|
||||
|
||||
int16_t CanardSocketCAN::receive(CanardFrame *rxf)
|
||||
{
|
||||
int32_t result = recvmsg(_fd, &_recv_msg, 0);
|
||||
int32_t result = recvmsg(_fd, &_recv_msg, 1000);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
|
|
|
@ -36,8 +36,6 @@
|
|||
#include <lib/ecl/geo/geo.h>
|
||||
#include <lib/version/version.h>
|
||||
|
||||
#define REGULATED_DRONE_SENSOR_BMSSTATUS_ID 32080
|
||||
|
||||
using namespace time_literals;
|
||||
|
||||
UavcanNode *UavcanNode::_instance;
|
||||
|
@ -153,19 +151,41 @@ void UavcanNode::Run()
|
|||
// Subscribe to messages uavcan.node.Heartbeat.
|
||||
canardRxSubscribe(&_canard_instance,
|
||||
CanardTransferKindMessage,
|
||||
uavcan::node::Heartbeat_1_0::PORT_ID,
|
||||
uavcan::node::Heartbeat_1_0::SIZE,
|
||||
uavcan_node_Heartbeat_1_0_FIXED_PORT_ID_,
|
||||
uavcan_node_Heartbeat_1_0_EXTENT_BYTES_,
|
||||
CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC,
|
||||
&_heartbeat_subscription);
|
||||
|
||||
// Subscribe to messages uavcan.node.NodeIDAllocationData_1_0 for PNP V1
|
||||
canardRxSubscribe(&_canard_instance,
|
||||
CanardTransferKindMessage,
|
||||
uavcan_pnp_NodeIDAllocationData_1_0_FIXED_PORT_ID_,
|
||||
uavcan_pnp_NodeIDAllocationData_1_0_EXTENT_BYTES_,
|
||||
CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC,
|
||||
&_pnp_v1_subscription);
|
||||
|
||||
canardRxSubscribe(&_canard_instance,
|
||||
CanardTransferKindResponse,
|
||||
uavcan_register_Access_1_0_FIXED_PORT_ID_,
|
||||
uavcan_register_Access_Response_1_0_EXTENT_BYTES_,
|
||||
CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC,
|
||||
&_register_access_subscription);
|
||||
|
||||
if (_param_uavcan_v1_bat_md.get() == 1) {
|
||||
canardRxSubscribe(&_canard_instance,
|
||||
canardRxSubscribe(&_canard_instance,
|
||||
CanardTransferKindResponse,
|
||||
uavcan_register_List_1_0_FIXED_PORT_ID_,
|
||||
uavcan_register_List_Response_1_0_EXTENT_BYTES_,
|
||||
CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC,
|
||||
&_register_list_subscription);
|
||||
|
||||
|
||||
|
||||
canardRxSubscribe(&_canard_instance,
|
||||
CanardTransferKindMessage,
|
||||
static_cast<CanardPortID>(_param_uavcan_v1_bat_id.get()),
|
||||
regulated::drone::sensor::BMSStatus_1_0::SIZE,
|
||||
test_port_id,
|
||||
reg_drone_srv_battery_Status_0_1_EXTENT_BYTES_,
|
||||
CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC,
|
||||
&_drone_sensor_BMSStatus_subscription);
|
||||
}
|
||||
&_drone_srv_battery_subscription);
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
@ -193,27 +213,61 @@ void UavcanNode::Run()
|
|||
|
||||
|
||||
|
||||
if (hrt_elapsed_time(&_uavcan_pnp_nodeidallocation_last) >= 1_s &&
|
||||
_node_register_setup != CANARD_NODE_ID_UNSET &&
|
||||
_node_register_request_index == _node_register_last_received_index+1){
|
||||
|
||||
PX4_INFO("NodeID %i request register %i", _node_register_setup, _node_register_request_index);
|
||||
|
||||
uavcan_register_List_Request_1_0 msg;
|
||||
msg.index = _node_register_request_index;
|
||||
|
||||
uint8_t request_payload_buffer[uavcan_register_List_Request_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_];
|
||||
|
||||
CanardTransfer request = {
|
||||
.timestamp_usec = hrt_absolute_time(), // Zero if transmission deadline is not limited.
|
||||
.priority = CanardPriorityNominal,
|
||||
.transfer_kind = CanardTransferKindRequest,
|
||||
.port_id = uavcan_register_List_1_0_FIXED_PORT_ID_, // This is the subject-ID.
|
||||
.remote_node_id = _node_register_setup,
|
||||
.transfer_id = _uavcan_register_list_request_transfer_id,
|
||||
.payload_size = uavcan_register_List_Request_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_,
|
||||
.payload = &request_payload_buffer,
|
||||
};
|
||||
|
||||
int32_t result = uavcan_register_List_Request_1_0_serialize_(&msg, request_payload_buffer, &request.payload_size);
|
||||
|
||||
if(result == 0){
|
||||
// set the data ready in the buffer and chop if needed
|
||||
++_uavcan_register_list_request_transfer_id; // The transfer-ID shall be incremented after every transmission on this subject.
|
||||
result = canardTxPush(&_canard_instance, &request);
|
||||
|
||||
++_node_register_request_index;
|
||||
}
|
||||
}
|
||||
|
||||
// send uavcan::node::Heartbeat_1_0 @ 1 Hz
|
||||
if (hrt_elapsed_time(&_uavcan_node_heartbeat_last) >= 1_s) {
|
||||
|
||||
uavcan::node::Heartbeat_1_0 heartbeat{};
|
||||
uavcan_node_Heartbeat_1_0 heartbeat{};
|
||||
heartbeat.uptime = _uavcan_node_heartbeat_transfer_id; // TODO: use real uptime
|
||||
heartbeat.health = uavcan::node::Heartbeat_1_0::HEALTH_NOMINAL;
|
||||
heartbeat.mode = uavcan::node::Heartbeat_1_0::MODE_OPERATIONAL;
|
||||
heartbeat.health.value = uavcan_node_Health_1_0_NOMINAL;
|
||||
heartbeat.mode.value = uavcan_node_Mode_1_0_OPERATIONAL;
|
||||
|
||||
heartbeat.serializeToBuffer(_uavcan_node_heartbeat_buffer);
|
||||
|
||||
const CanardTransfer transfer = {
|
||||
CanardTransfer transfer = {
|
||||
.timestamp_usec = hrt_absolute_time(),
|
||||
.priority = CanardPriorityNominal,
|
||||
.transfer_kind = CanardTransferKindMessage,
|
||||
.port_id = uavcan::node::Heartbeat_1_0::PORT_ID,
|
||||
.port_id = uavcan_node_Heartbeat_1_0_FIXED_PORT_ID_,
|
||||
.remote_node_id = CANARD_NODE_ID_UNSET,
|
||||
.transfer_id = _uavcan_node_heartbeat_transfer_id++,
|
||||
.payload_size = uavcan::node::Heartbeat_1_0::SIZE,
|
||||
.payload_size = uavcan_node_Heartbeat_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_,
|
||||
.payload = &_uavcan_node_heartbeat_buffer,
|
||||
};
|
||||
|
||||
uavcan_node_Heartbeat_1_0_serialize_(&heartbeat, _uavcan_node_heartbeat_buffer, &transfer.payload_size);
|
||||
|
||||
int32_t result = canardTxPush(&_canard_instance, &transfer);
|
||||
|
||||
if (result < 0) {
|
||||
|
@ -226,49 +280,11 @@ void UavcanNode::Run()
|
|||
_uavcan_node_heartbeat_last = transfer.timestamp_usec;
|
||||
}
|
||||
|
||||
// send regulated::drone::sensor::BMSStatus_1_0 @ 1 Hz
|
||||
if (_param_uavcan_v1_bat_md.get() == 2) {
|
||||
if (hrt_elapsed_time(&_regulated_drone_sensor_bmsstatus_last) >= 1_s) {
|
||||
|
||||
battery_status_s battery_status;
|
||||
|
||||
if (_battery_status_sub.update(&battery_status)) {
|
||||
regulated::drone::sensor::BMSStatus_1_0 bmsstatus{};
|
||||
//bmsstatus.timestamp = battery_status.timestamp;
|
||||
//bmsstatus.remaining_capacity = battery_status.remaining;
|
||||
|
||||
bmsstatus.serializeToBuffer(_regulated_drone_sensor_bmsstatus_buffer);
|
||||
|
||||
const CanardTransfer transfer = {
|
||||
.timestamp_usec = hrt_absolute_time(),
|
||||
.priority = CanardPriorityNominal,
|
||||
.transfer_kind = CanardTransferKindMessage,
|
||||
.port_id = static_cast<CanardPortID>(_param_uavcan_v1_bat_id.get()),
|
||||
.remote_node_id = CANARD_NODE_ID_UNSET,
|
||||
.transfer_id = _regulated_drone_sensor_bmsstatus_transfer_id++,
|
||||
.payload_size = regulated::drone::sensor::BMSStatus_1_0::SIZE,
|
||||
.payload = &_regulated_drone_sensor_bmsstatus_buffer,
|
||||
};
|
||||
|
||||
int32_t result = canardTxPush(&_canard_instance, &transfer);
|
||||
|
||||
if (result < 0) {
|
||||
// An error has occurred: either an argument is invalid or we've ran out of memory.
|
||||
// It is possible to statically prove that an out-of-memory will never occur for a given application if the
|
||||
// heap is sized correctly; for background, refer to the Robson's Proof and the documentation for O1Heap.
|
||||
PX4_ERR("Battery transmit error %d", result);
|
||||
}
|
||||
|
||||
_regulated_drone_sensor_bmsstatus_last = transfer.timestamp_usec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transmitting
|
||||
// Look at the top of the TX queue.
|
||||
for (const CanardFrame *txf = nullptr; (txf = canardTxPeek(&_canard_instance)) != nullptr;) {
|
||||
// Check if the frame has timed out.
|
||||
if (hrt_absolute_time() > txf->timestamp_usec) {
|
||||
if (hrt_absolute_time() > txf->timestamp_usec) { //FIXME wrong I think
|
||||
// Send the frame. Redundant interfaces may be used here.
|
||||
const int tx_res = _can_interface->transmit(*txf);
|
||||
|
||||
|
@ -312,23 +328,111 @@ void UavcanNode::Run()
|
|||
|
||||
} else if (result == 1) {
|
||||
// A transfer has been received, process it.
|
||||
PX4_DEBUG("received Port ID: %d", receive.port_id);
|
||||
PX4_INFO("received Port ID: %d", receive.port_id);
|
||||
|
||||
if (receive.port_id == static_cast<CanardPortID>(_param_uavcan_v1_bat_id.get())) {
|
||||
auto bms_status = regulated::drone::sensor::BMSStatus_1_0::deserializeFromBuffer((const uint8_t *)receive.payload,
|
||||
receive.payload_size);
|
||||
if (receive.port_id == uavcan_pnp_NodeIDAllocationData_1_0_FIXED_PORT_ID_) {
|
||||
uavcan_pnp_NodeIDAllocationData_1_0 msg;
|
||||
|
||||
size_t pnp_in_size_bits = receive.payload_size;
|
||||
uavcan_pnp_NodeIDAllocationData_1_0_deserialize_(&msg, (const uint8_t*)receive.payload, &pnp_in_size_bits);
|
||||
|
||||
//TODO internal database with unique id to node ip mappings now we give an hardcoded ID back
|
||||
|
||||
msg.allocated_node_id.count = 1;
|
||||
msg.allocated_node_id.elements[0].value = 15; // HACK hardcoded ID
|
||||
|
||||
_uavcan_pnp_nodeidallocation_last = hrt_absolute_time();
|
||||
_node_register_request_index = 0;
|
||||
_node_register_last_received_index = -1;
|
||||
_node_register_setup = msg.allocated_node_id.elements[0].value; // This nodeID has to be configured
|
||||
|
||||
PX4_INFO("Received NodeID allocation request assigning %i", msg.allocated_node_id.elements[0].value);
|
||||
|
||||
uint8_t node_id_alloc_payload_buffer[uavcan_pnp_NodeIDAllocationData_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_];
|
||||
|
||||
CanardTransfer transfer = {
|
||||
.timestamp_usec = hrt_absolute_time(), // Zero if transmission deadline is not limited.
|
||||
.priority = CanardPriorityNominal,
|
||||
.transfer_kind = CanardTransferKindMessage,
|
||||
.port_id = uavcan_pnp_NodeIDAllocationData_1_0_FIXED_PORT_ID_, // This is the subject-ID.
|
||||
.remote_node_id = CANARD_NODE_ID_UNSET, // Messages cannot be unicast, so use UNSET.
|
||||
.transfer_id = _uavcan_pnp_nodeidallocation_v1_transfer_id,
|
||||
.payload_size = uavcan_pnp_NodeIDAllocationData_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_,
|
||||
.payload = &node_id_alloc_payload_buffer,
|
||||
};
|
||||
|
||||
result = uavcan_pnp_NodeIDAllocationData_1_0_serialize_(&msg, node_id_alloc_payload_buffer, &transfer.payload_size);
|
||||
|
||||
if(result == 0) {
|
||||
// set the data ready in the buffer and chop if needed
|
||||
++_uavcan_pnp_nodeidallocation_v1_transfer_id; // The transfer-ID shall be incremented after every transmission on this subject.
|
||||
result = canardTxPush(&_canard_instance, &transfer);
|
||||
}
|
||||
} if (receive.port_id == uavcan_register_List_1_0_FIXED_PORT_ID_) {
|
||||
uavcan_register_List_Response_1_0 msg;
|
||||
|
||||
size_t register_in_size_bits = receive.payload_size;
|
||||
uavcan_register_List_Response_1_0_deserialize_(&msg, (const uint8_t*)receive.payload, ®ister_in_size_bits);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if(strncmp((char*)msg.name.name.elements, "uavcan.pub.battery_status.id", msg.name.name.count) == 0) { //Battery status publisher
|
||||
_node_register_setup = CANARD_NODE_ID_UNSET;
|
||||
PX4_INFO("NodeID %i battery_status publisher set PortID to %i", receive.remote_node_id, test_port_id);
|
||||
_node_register_last_received_index++;
|
||||
|
||||
uavcan_register_Access_Request_1_0 request_msg;
|
||||
memcpy(&request_msg.name, &msg.name, sizeof(uavcan_register_Name_1_0));
|
||||
|
||||
uavcan_register_Value_1_0_select_natural16_(&request_msg.value);
|
||||
request_msg.value.natural16.value.count = 1;
|
||||
request_msg.value.natural16.value.elements[0] = test_port_id;
|
||||
|
||||
|
||||
uint8_t request_payload_buffer[uavcan_register_Access_Request_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_];
|
||||
|
||||
CanardTransfer transfer = {
|
||||
.timestamp_usec = hrt_absolute_time(), // Zero if transmission deadline is not limited.
|
||||
.priority = CanardPriorityNominal,
|
||||
.transfer_kind = CanardTransferKindRequest,
|
||||
.port_id = uavcan_register_Access_1_0_FIXED_PORT_ID_, // This is the subject-ID.
|
||||
.remote_node_id = receive.remote_node_id, // Messages cannot be unicast, so use UNSET.
|
||||
.transfer_id = _uavcan_register_access_request_transfer_id,
|
||||
.payload_size = uavcan_register_Access_Request_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_,
|
||||
.payload = &request_payload_buffer,
|
||||
};
|
||||
|
||||
result = uavcan_register_Access_Request_1_0_serialize_(&request_msg, request_payload_buffer, &transfer.payload_size);
|
||||
|
||||
if(result == 0) {
|
||||
// set the data ready in the buffer and chop if needed
|
||||
++_uavcan_register_access_request_transfer_id; // The transfer-ID shall be incremented after every transmission on this subject.
|
||||
result = canardTxPush(&_canard_instance, &transfer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else if (receive.port_id == test_port_id) {
|
||||
PX4_INFO("NodeID %i Battery Status msg", receive.remote_node_id);
|
||||
//TODO deserialize
|
||||
|
||||
/*
|
||||
|
||||
battery_status_s battery_status{};
|
||||
battery_status.id = bms_status.battery_id;
|
||||
battery_status.voltage_v = bms_status.voltage;
|
||||
//battery_status.remaining = bms_status.remaining_capacity;
|
||||
battery_status.timestamp = hrt_absolute_time();
|
||||
_battery_status_pub.publish(battery_status);
|
||||
_battery_status_pub.publish(battery_status);*/
|
||||
}
|
||||
|
||||
// Deallocate the dynamic memory afterwards.
|
||||
_canard_instance.memory_free(&_canard_instance, (void *)receive.payload);
|
||||
}
|
||||
} else {
|
||||
PX4_INFO("RX canard %d\r\n", result);
|
||||
}
|
||||
}
|
||||
|
||||
perf_end(_cycle_perf);
|
||||
|
|
|
@ -53,8 +53,23 @@
|
|||
#include <canard.h>
|
||||
#include <canard_dsdl.h>
|
||||
|
||||
#include <regulated/drone/sensor/BMSStatus_1_0.hpp>
|
||||
#include <uavcan/node/Heartbeat_1_0.hpp>
|
||||
#include <reg/drone/srv/battery/Status_0_1.h>
|
||||
#include <reg/drone/srv/battery/Parameters_0_1.h>
|
||||
#include <uavcan/node/Heartbeat_1_0.h>
|
||||
|
||||
//Quick and Dirty PNP imlementation only V1 for now as well
|
||||
#include <uavcan/node/ID_1_0.h>
|
||||
#include <uavcan/pnp/NodeIDAllocationData_1_0.h>
|
||||
#include <uavcan/pnp/NodeIDAllocationData_2_0.h>
|
||||
|
||||
//Quick and Dirty UAVCAN register implementation
|
||||
#include <uavcan/_register/List_1_0.h>
|
||||
#include <uavcan/_register/Access_1_0.h>
|
||||
|
||||
#define PNP1_PORT_ID uavcan_pnp_NodeIDAllocationData_1_0_FIXED_PORT_ID_
|
||||
#define PNP1_PAYLOAD_SIZE uavcan_pnp_NodeIDAllocationData_1_0_SERIALIZATION_BUFFER_SIZE_BYTES_
|
||||
#define PNP2_PORT_ID uavcan_pnp_NodeIDAllocationData_2_0_FIXED_PORT_ID_
|
||||
#define PNP2_PAYLOAD_SIZE uavcan_pnp_NodeIDAllocationData_2_0_SERIALIZATION_BUFFER_SIZE_BYTES_
|
||||
|
||||
#include "CanardInterface.hpp"
|
||||
|
||||
|
@ -106,7 +121,10 @@ private:
|
|||
pthread_mutex_t _node_mutex;
|
||||
|
||||
CanardRxSubscription _heartbeat_subscription;
|
||||
CanardRxSubscription _drone_sensor_BMSStatus_subscription;
|
||||
CanardRxSubscription _pnp_v1_subscription;
|
||||
CanardRxSubscription _drone_srv_battery_subscription;
|
||||
CanardRxSubscription _register_access_subscription;
|
||||
CanardRxSubscription _register_list_subscription;
|
||||
|
||||
uORB::Subscription _battery_status_sub{ORB_ID(battery_status)};
|
||||
uORB::Subscription _parameter_update_sub{ORB_ID(parameter_update)};
|
||||
|
@ -117,12 +135,24 @@ private:
|
|||
perf_counter_t _interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": cycle interval")};
|
||||
|
||||
// uavcan::node::Heartbeat_1_0
|
||||
uint8_t _uavcan_node_heartbeat_buffer[uavcan::node::Heartbeat_1_0::SIZE];
|
||||
uint8_t _uavcan_node_heartbeat_buffer[uavcan_node_Heartbeat_1_0_EXTENT_BYTES_];
|
||||
hrt_abstime _uavcan_node_heartbeat_last{0};
|
||||
CanardTransferID _uavcan_node_heartbeat_transfer_id{0};
|
||||
|
||||
// regulated::drone::sensor::BMSStatus_1_0
|
||||
uint8_t _regulated_drone_sensor_bmsstatus_buffer[regulated::drone::sensor::BMSStatus_1_0::SIZE];
|
||||
|
||||
const uint16_t test_port_id = 1234;
|
||||
|
||||
CanardTransferID _uavcan_pnp_nodeidallocation_v1_transfer_id{0};
|
||||
hrt_abstime _uavcan_pnp_nodeidallocation_last{0};
|
||||
|
||||
CanardTransferID _uavcan_register_list_request_transfer_id{0};
|
||||
CanardTransferID _uavcan_register_access_request_transfer_id{0};
|
||||
//Register interface NodeID TODO MVP right have to make a queue
|
||||
uint8_t _node_register_setup = CANARD_NODE_ID_UNSET;
|
||||
int32_t _node_register_request_index = 0;
|
||||
int32_t _node_register_last_received_index = -1;
|
||||
|
||||
// regulated::drone::sensor::BMSStatus_1_0
|
||||
uint8_t _regulated_drone_sensor_bmsstatus_buffer[reg_drone_srv_battery_Status_0_1_EXTENT_BYTES_];
|
||||
hrt_abstime _regulated_drone_sensor_bmsstatus_last{0};
|
||||
CanardTransferID _regulated_drone_sensor_bmsstatus_transfer_id{0};
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit bec890304a2888bc516416e4ebf252f761558b92
|
||||
Subproject commit cde670347425023480a1417fcd603b27c8eb06c1
|
|
@ -1 +1 @@
|
|||
Subproject commit 4ef80c77c7ea9a5ac74ec1fa58055e7609b7758e
|
||||
Subproject commit d874225ea4b5a79a4639bcfcb9096ccd943138a9
|
Loading…
Reference in New Issue