|
|
|
#include "uavcan.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "main.h"
|
|
|
|
#include "math.h"
|
|
|
|
#include "node_flow_water.h"
|
|
|
|
|
|
|
|
#define MEMPOOL_OBJECTS 16
|
|
|
|
|
|
|
|
static CanardInstance g_canard; //The library instance
|
|
|
|
static uint8_t g_canard_memory_pool[2048];
|
|
|
|
static uint32_t spin_time = 0;
|
|
|
|
uint8_t feedback_status =0;
|
|
|
|
//static const uint8_t gimbal_id = 0xC5; //Arena for memory allocation, used by the library
|
|
|
|
//static uint32_t g_uptime = 0;
|
|
|
|
|
|
|
|
uint8_t sver_p1 = 1;
|
|
|
|
uint8_t sver_p2 = 0;
|
|
|
|
uint8_t sver_p3 = 0;
|
|
|
|
//static uint8_t node_health = UAVCAN_NODE_HEALTH_OK;
|
|
|
|
//static uint8_t node_mode = UAVCAN_NODE_MODE_INITIALIZATION;
|
|
|
|
static uint64_t send_next_node_id_allocation_request_at; ///< When the next node ID allocation request should be sent
|
|
|
|
static uint8_t node_id_allocation_unique_id_offset;
|
|
|
|
static uint8_t node_unique_id[UNIQUE_ID_LENGTH_BYTES];
|
|
|
|
static uint8_t transfer_id = 0;
|
|
|
|
|
|
|
|
//static uint32_t last_state_time = 0;
|
|
|
|
//extern QueueHandle_t uavcan_rev_queue;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
// FieldTypes
|
|
|
|
uint8_t id; // bit len 8
|
|
|
|
float pitch; // float16 Saturate
|
|
|
|
float roll; // float16 Saturate
|
|
|
|
float yaw; // float16 Saturate
|
|
|
|
|
|
|
|
} zrzk_equipment_uav_Euler;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef CANARD_INTERNAL_SATURATE
|
|
|
|
#define CANARD_INTERNAL_SATURATE(x, max) ( ((x) > max) ? max : ( (-(x) > max) ? (-max) : (x) ) );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef CANARD_INTERNAL_SATURATE_UNSIGNED
|
|
|
|
#define CANARD_INTERNAL_SATURATE_UNSIGNED(x, max) ( ((x) >= max) ? max : (x) );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__GNUC__)
|
|
|
|
# define CANARD_MAYBE_UNUSED(x) x __attribute__((unused))
|
|
|
|
#else
|
|
|
|
# define CANARD_MAYBE_UNUSED(x) x
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool shouldAcceptTransfer(const CanardInstance *ins,
|
|
|
|
uint64_t *out_data_type_signature,
|
|
|
|
uint16_t data_type_id,
|
|
|
|
CanardTransferType transfer_type,
|
|
|
|
uint8_t source_node_id)
|
|
|
|
{
|
|
|
|
// (void)source_node_id;
|
|
|
|
if (canardGetLocalNodeID(ins) == CANARD_BROADCAST_NODE_ID)
|
|
|
|
{
|
|
|
|
// If we're in the process of allocation of dynamic node ID, accept only relevant transfers.
|
|
|
|
|
|
|
|
if ((transfer_type == CanardTransferTypeBroadcast) &&
|
|
|
|
(data_type_id == UAVCAN_NODE_ID_ALLOCATION_DATA_TYPE_ID))
|
|
|
|
{
|
|
|
|
*out_data_type_signature = UAVCAN_NODE_ID_ALLOCATION_DATA_TYPE_SIGNATURE;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (data_type_id)
|
|
|
|
{
|
|
|
|
case UAVCAN_GET_NODE_INFO_DATA_TYPE_ID:
|
|
|
|
*out_data_type_signature = UAVCAN_GET_NODE_INFO_DATA_TYPE_SIGNATURE;
|
|
|
|
return true;
|
|
|
|
case ZRZK_EQUIPMENT_FLOW_WATER_ID:
|
|
|
|
*out_data_type_signature = ZRZK_EQUIPMENT_FLOW_WATER_SIGNATURE;
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void onTransferReceived(CanardInstance *ins, CanardRxTransfer *transfer)
|
|
|
|
{
|
|
|
|
if(transfer->transfer_type == CanardTransferTypeBroadcast)
|
|
|
|
{
|
|
|
|
action_transfer_received_broadcast(ins, transfer);
|
|
|
|
}
|
|
|
|
else if (transfer->transfer_type == CanardTransferTypeResponse)
|
|
|
|
{
|
|
|
|
action_transfer_received_response(ins, transfer);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
action_transfer_received_request(ins, transfer);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void action_transfer_received_request(CanardInstance *ins, CanardRxTransfer *transfer)
|
|
|
|
{
|
|
|
|
switch (transfer->data_type_id)
|
|
|
|
{
|
|
|
|
case UAVCAN_GET_NODE_INFO_DATA_TYPE_ID:
|
|
|
|
handle_canard_get_node_info(transfer);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void action_transfer_received_broadcast(CanardInstance *ins, CanardRxTransfer *transfer)
|
|
|
|
{
|
|
|
|
switch (transfer->data_type_id)
|
|
|
|
{
|
|
|
|
case UAVCAN_NODE_ID_ALLOCATION_DATA_TYPE_ID:
|
|
|
|
if (canardGetLocalNodeID(ins) == CANARD_BROADCAST_NODE_ID)
|
|
|
|
{
|
|
|
|
handle_allocation_data(&g_canard, transfer);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void action_transfer_received_response(CanardInstance *ins, CanardRxTransfer *transfer)
|
|
|
|
{
|
|
|
|
switch (transfer->data_type_id)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void receive_canard(void)
|
|
|
|
{
|
|
|
|
CanardCANFrame rx_frame;
|
|
|
|
uint32_t time_stame = HAL_GetTick();
|
|
|
|
while (canardSTM32Receive(&rx_frame) > 0)
|
|
|
|
{
|
|
|
|
canardHandleRxFrame(&g_canard, &rx_frame, HAL_GetTick());
|
|
|
|
|
|
|
|
if ((HAL_GetTick() - time_stame) > 100)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void handle_uavcan_rx_frame(const uavcan_rev_t *msg)
|
|
|
|
{
|
|
|
|
canardHandleRxFrame(&g_canard, &msg->canard_CAN_frame,msg->tick_ms*1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void handle_canard_get_node_info(CanardRxTransfer *transfer)
|
|
|
|
{
|
|
|
|
uint8_t buffer[UAVCAN_GET_NODE_INFO_RESPONSE_MAX_SIZE];
|
|
|
|
memset(buffer, 0, UAVCAN_GET_NODE_INFO_RESPONSE_MAX_SIZE);
|
|
|
|
uint16_t len = 0;
|
|
|
|
len = make_node_info_message(buffer);
|
|
|
|
int result = canardRequestOrRespond(&g_canard,
|
|
|
|
transfer->source_node_id,
|
|
|
|
UAVCAN_GET_NODE_INFO_DATA_TYPE_SIGNATURE,
|
|
|
|
UAVCAN_GET_NODE_INFO_DATA_TYPE_ID,
|
|
|
|
&transfer->transfer_id,
|
|
|
|
transfer->priority,
|
|
|
|
CanardResponse,
|
|
|
|
&buffer[0],
|
|
|
|
(uint16_t)len);
|
|
|
|
}
|
|
|
|
|
|
|
|
void uavcan_init(void)
|
|
|
|
{
|
|
|
|
set_unique_id("com.zr3d.proxi");
|
|
|
|
CanardSTM32CANTimings timings;
|
|
|
|
int result = canardSTM32ComputeCANTimings(HAL_RCC_GetPCLK1Freq(), 1000000, &timings);
|
|
|
|
if (result)
|
|
|
|
{
|
|
|
|
__ASM volatile("BKPT #01");
|
|
|
|
}
|
|
|
|
|
|
|
|
result = canardSTM32Init(&timings, CanardSTM32IfaceModeNormal);
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
{
|
|
|
|
__ASM volatile("BKPT #01");
|
|
|
|
}
|
|
|
|
|
|
|
|
canardInit(&g_canard, // Uninitialized library instance
|
|
|
|
g_canard_memory_pool, // Raw memory chunk used for dynamic allocation
|
|
|
|
sizeof(g_canard_memory_pool), // Size of the above, in bytes
|
|
|
|
onTransferReceived, // Callback, see CanardOnTransferReception
|
|
|
|
shouldAcceptTransfer, // Callback, see CanardShouldAcceptTransfer
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
canardSetLocalNodeID(&g_canard, uavcan_local_node);
|
|
|
|
|
|
|
|
if (can_setup_filters(canardGetLocalNodeID(&g_canard)) < 0)
|
|
|
|
{
|
|
|
|
can_setup_filters_none();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void uavcan_init_with_cubemx(void)
|
|
|
|
{
|
|
|
|
set_unique_id("com.zr3d.proxi");
|
|
|
|
|
|
|
|
initCanOnlyFilter();
|
|
|
|
|
|
|
|
canardInit(&g_canard, // Uninitialized library instance
|
|
|
|
g_canard_memory_pool, // Raw memory chunk used for dynamic allocation
|
|
|
|
sizeof(g_canard_memory_pool), // Size of the above, in bytes
|
|
|
|
onTransferReceived, // Callback, see CanardOnTransferReception
|
|
|
|
shouldAcceptTransfer, // Callback, see CanardShouldAcceptTransfer
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
canardSetLocalNodeID(&g_canard, uavcan_local_node);
|
|
|
|
|
|
|
|
if (can_setup_filters(canardGetLocalNodeID(&g_canard)) < 0)
|
|
|
|
{
|
|
|
|
can_setup_filters_none();
|
|
|
|
}
|
|
|
|
init_CAN_IRQ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_allocation(void)
|
|
|
|
{
|
|
|
|
set_unique_id("com.zr3d.proxi");
|
|
|
|
|
|
|
|
initCanOnlyFilter();
|
|
|
|
|
|
|
|
canardInit(&g_canard, // Uninitialized library instance
|
|
|
|
g_canard_memory_pool, // Raw memory chunk used for dynamic allocation
|
|
|
|
sizeof(g_canard_memory_pool), // Size of the above, in bytes
|
|
|
|
onTransferReceived, // Callback, see CanardOnTransferReception
|
|
|
|
shouldAcceptTransfer, // Callback, see CanardShouldAcceptTransfer
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
// if (can_setup_filters(canardGetLocalNodeID(&g_canard)) < 0)
|
|
|
|
// {
|
|
|
|
// can_setup_filters_none();
|
|
|
|
// }
|
|
|
|
init_CAN_IRQ();
|
|
|
|
|
|
|
|
//执行动态节点ID分配过程
|
|
|
|
|
|
|
|
static const uint8_t preferred_node_id = CANARD_BROADCAST_NODE_ID;
|
|
|
|
node_id_allocation_unique_id_offset = 0;
|
|
|
|
uint8_t node_id_allocation_transfer_id = 0;
|
|
|
|
|
|
|
|
while (canardGetLocalNodeID(&g_canard) == CANARD_BROADCAST_NODE_ID)
|
|
|
|
{
|
|
|
|
//puts("Waiting for dynamic node ID allocation...");
|
|
|
|
// vTaskDelay(50);
|
|
|
|
send_next_node_id_allocation_request_at =
|
|
|
|
HAL_GetTick() + UAVCAN_NODE_ID_ALLOCATION_REQUEST_DELAY_OFFSET_USEC +
|
|
|
|
(uint64_t)(get_random_float() * UAVCAN_NODE_ID_ALLOCATION_RANDOM_TIMEOUT_RANGE_USEC);
|
|
|
|
|
|
|
|
// (uint64_t)(0.1 * UAVCAN_NODE_ID_ALLOCATION_RANDOM_TIMEOUT_RANGE_USEC);
|
|
|
|
|
|
|
|
|
|
|
|
while ((HAL_GetTick() < send_next_node_id_allocation_request_at) &&
|
|
|
|
(canardGetLocalNodeID(&g_canard) == CANARD_BROADCAST_NODE_ID))
|
|
|
|
{
|
|
|
|
send_canard();
|
|
|
|
receive_canard();
|
|
|
|
osDelay(5);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (canardGetLocalNodeID(&g_canard) != CANARD_BROADCAST_NODE_ID)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Structure of the request is documented in the DSDL definition 请求的结构记录在DSDL定义中
|
|
|
|
// See http://uavcan.org/Specification/6._Application_level_functions/#dynamic-node-id-allocation
|
|
|
|
|
|
|
|
uint8_t allocation_request[CANARD_CAN_FRAME_MAX_DATA_LEN - 1];
|
|
|
|
allocation_request[0] = (uint8_t)(preferred_node_id << 1U);
|
|
|
|
|
|
|
|
if (node_id_allocation_unique_id_offset == 0)
|
|
|
|
{
|
|
|
|
allocation_request[0] |= 1; // First part of unique ID
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t my_unique_id[UNIQUE_ID_LENGTH_BYTES];
|
|
|
|
get_unique_id(my_unique_id);
|
|
|
|
|
|
|
|
static const uint8_t max_len_of_unique_id_in_request = 6;
|
|
|
|
uint8_t uid_size = (uint8_t)(UNIQUE_ID_LENGTH_BYTES - node_id_allocation_unique_id_offset);
|
|
|
|
if (uid_size > max_len_of_unique_id_in_request)
|
|
|
|
{
|
|
|
|
uid_size = max_len_of_unique_id_in_request;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Paranoia time
|
|
|
|
assert(node_id_allocation_unique_id_offset < UNIQUE_ID_LENGTH_BYTES);
|
|
|
|
assert(uid_size <= max_len_of_unique_id_in_request);
|
|
|
|
assert(uid_size > 0);
|
|
|
|
assert((uid_size + node_id_allocation_unique_id_offset) <= UNIQUE_ID_LENGTH_BYTES);
|
|
|
|
|
|
|
|
memmove(&allocation_request[1], &my_unique_id[node_id_allocation_unique_id_offset], uid_size);
|
|
|
|
|
|
|
|
// Broadcasting the request
|
|
|
|
const int16_t bcast_res = canardBroadcast(&g_canard,
|
|
|
|
UAVCAN_NODE_ID_ALLOCATION_DATA_TYPE_SIGNATURE,
|
|
|
|
UAVCAN_NODE_ID_ALLOCATION_DATA_TYPE_ID,
|
|
|
|
&node_id_allocation_transfer_id,
|
|
|
|
CANARD_TRANSFER_PRIORITY_LOW,
|
|
|
|
&allocation_request[0],
|
|
|
|
(uint16_t)(uid_size + 1));
|
|
|
|
if (bcast_res < 0)
|
|
|
|
{
|
|
|
|
//(void)fprintf(stderr, "Could not broadcast dynamic node ID allocation request; error %d\n", bcast_res); //TODO ////my_printf()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Preparing for timeout; if response is received, this value will be updated from the callback.
|
|
|
|
node_id_allocation_unique_id_offset = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//过滤设置
|
|
|
|
if (canardGetLocalNodeID(&g_canard) != 0) //TODO 其实这个判断可以删除,稳妥起见,再判断一次
|
|
|
|
{
|
|
|
|
if (can_setup_filters(canardGetLocalNodeID(&g_canard)) < 0)
|
|
|
|
{
|
|
|
|
can_setup_filters_none();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
init_CAN_IRQ();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void send_canard(void)
|
|
|
|
{
|
|
|
|
osStatus_t status;
|
|
|
|
if (uavcan_send_mutexHandle != NULL)
|
|
|
|
{
|
|
|
|
status = osMutexAcquire(uavcan_send_mutexHandle, 20U);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const CanardCANFrame *txf = NULL; (txf = canardPeekTxQueue(&g_canard)) != NULL;)
|
|
|
|
{
|
|
|
|
const int16_t tx_res = canardSTM32Transmit(txf);
|
|
|
|
if (tx_res < 0) // Failure - drop the frame and report
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (tx_res > 0) // Success - just drop the frame
|
|
|
|
{
|
|
|
|
canardPopTxQueue(&g_canard);
|
|
|
|
}
|
|
|
|
else // Timeout - just exit and try again later
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(status ==osOK && uavcan_send_mutexHandle != NULL)
|
|
|
|
{
|
|
|
|
status = osMutexRelease(uavcan_send_mutexHandle);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void publish_node_status(void)
|
|
|
|
{
|
|
|
|
if (HAL_GetTick() < spin_time + CANARD_SPIN_PERIOD)
|
|
|
|
return; // rate limiting
|
|
|
|
spin_time = HAL_GetTick();
|
|
|
|
|
|
|
|
uint8_t buffer[UAVCAN_NODE_STATUS_MESSAGE_SIZE];
|
|
|
|
static uint8_t transfer_id = 0; // This variable MUST BE STATIC; refer to the libcanard documentation for the background
|
|
|
|
make_node_status_message(buffer);
|
|
|
|
canardBroadcast(&g_canard,
|
|
|
|
UAVCAN_NODE_STATUS_DATA_TYPE_SIGNATURE,
|
|
|
|
UAVCAN_NODE_STATUS_DATA_TYPE_ID,
|
|
|
|
&transfer_id,
|
|
|
|
CANARD_TRANSFER_PRIORITY_LOW,
|
|
|
|
buffer,
|
|
|
|
UAVCAN_NODE_STATUS_MESSAGE_SIZE);
|
|
|
|
//some indication
|
|
|
|
}
|
|
|
|
|
|
|
|
void make_node_status_message(uint8_t buffer[UAVCAN_NODE_STATUS_MESSAGE_SIZE])
|
|
|
|
{
|
|
|
|
uint8_t node_health = UAVCAN_NODE_HEALTH_OK;
|
|
|
|
uint8_t node_mode = UAVCAN_NODE_MODE_OPERATIONAL;
|
|
|
|
|
|
|
|
memset(buffer, 0, UAVCAN_NODE_STATUS_MESSAGE_SIZE);
|
|
|
|
uint32_t uptime_sec = (HAL_GetTick() / 1000);
|
|
|
|
canardEncodeScalar(buffer, 0, 32, &uptime_sec);
|
|
|
|
canardEncodeScalar(buffer, 32, 2, &node_health);
|
|
|
|
canardEncodeScalar(buffer, 34, 3, &node_mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t make_node_info_message(uint8_t buffer[UAVCAN_GET_NODE_INFO_RESPONSE_MAX_SIZE])
|
|
|
|
{
|
|
|
|
memset(buffer, 0, UAVCAN_GET_NODE_INFO_RESPONSE_MAX_SIZE);
|
|
|
|
make_node_status_message(buffer);
|
|
|
|
|
|
|
|
buffer[7] = APP_VERSION_MAJOR;
|
|
|
|
buffer[8] = APP_VERSION_MINOR;
|
|
|
|
buffer[9] = 1; // Optional field flags, VCS commit is set
|
|
|
|
|
|
|
|
uint32_t githash = GIT_HASH;
|
|
|
|
canardEncodeScalar(buffer, 80, 32, &githash);
|
|
|
|
|
|
|
|
buffer[22] = 0;//get_hw_version_minor();
|
|
|
|
buffer[23] = 0;//get_hw_version_patch();
|
|
|
|
|
|
|
|
get_unique_id(&buffer[24]);
|
|
|
|
const size_t name_len = strlen(APP_NODE_NAME);
|
|
|
|
memcpy(&buffer[41], APP_NODE_NAME, name_len);
|
|
|
|
return 41 + name_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
//动态节点消息接收处理 //on_allocation_message
|
|
|
|
void handle_allocation_data(CanardInstance *ins, CanardRxTransfer *transfer)
|
|
|
|
{
|
|
|
|
// Rule C - updating the randomized time interval
|
|
|
|
send_next_node_id_allocation_request_at =
|
|
|
|
HAL_GetTick() + UAVCAN_NODE_ID_ALLOCATION_REQUEST_DELAY_OFFSET_USEC + //getMonotonicTimestampUSec()
|
|
|
|
(uint64_t)(get_random_float() * UAVCAN_NODE_ID_ALLOCATION_RANDOM_TIMEOUT_RANGE_USEC);
|
|
|
|
|
|
|
|
if (transfer->source_node_id == CANARD_BROADCAST_NODE_ID)
|
|
|
|
{
|
|
|
|
// puts("Allocation request from another allocatee");
|
|
|
|
node_id_allocation_unique_id_offset = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Copying the unique ID from the message unique_id_bit_offset:位偏移量 --uint8
|
|
|
|
static const uint8_t unique_id_bit_offset = 8;
|
|
|
|
uint8_t received_unique_id[UNIQUE_ID_LENGTH_BYTES];
|
|
|
|
uint8_t received_unique_id_len = 0;
|
|
|
|
|
|
|
|
for (; received_unique_id_len < (transfer->payload_len - (unique_id_bit_offset / 8U)); received_unique_id_len++)
|
|
|
|
{
|
|
|
|
assert(received_unique_id_len < UNIQUE_ID_LENGTH_BYTES);
|
|
|
|
const uint8_t bit_offset = (uint8_t)(unique_id_bit_offset + received_unique_id_len * 8U);
|
|
|
|
(void)canardDecodeScalar(transfer, bit_offset, 8, false, &received_unique_id[received_unique_id_len]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Obtaining the local unique ID 获取本地 unique ID
|
|
|
|
uint8_t my_unique_id[UNIQUE_ID_LENGTH_BYTES];
|
|
|
|
get_unique_id(my_unique_id);
|
|
|
|
|
|
|
|
// Matching the received UID against the local one
|
|
|
|
if (memcmp(received_unique_id, my_unique_id, received_unique_id_len) != 0)
|
|
|
|
{
|
|
|
|
node_id_allocation_unique_id_offset = 0;
|
|
|
|
|
|
|
|
return; // No match, return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (received_unique_id_len < UNIQUE_ID_LENGTH_BYTES)
|
|
|
|
{
|
|
|
|
// The allocator has confirmed part of unique ID, switching to the next stage and updating the timeout.
|
|
|
|
node_id_allocation_unique_id_offset = received_unique_id_len;
|
|
|
|
send_next_node_id_allocation_request_at -= UAVCAN_NODE_ID_ALLOCATION_REQUEST_DELAY_OFFSET_USEC;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Allocation complete - copying the allocated node ID from the message
|
|
|
|
uint8_t allocated_node_id = 0;
|
|
|
|
(void)canardDecodeScalar(transfer, 0, 7, false, &allocated_node_id);
|
|
|
|
assert(allocated_node_id <= 127);
|
|
|
|
canardSetLocalNodeID(ins, allocated_node_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void canard_get_node_info_handle(CanardRxTransfer *transfer)
|
|
|
|
{
|
|
|
|
uint8_t buffer[UAVCAN_GET_NODE_INFO_RESPONSE_MAX_SIZE];
|
|
|
|
memset(buffer, 0, UAVCAN_GET_NODE_INFO_RESPONSE_MAX_SIZE);
|
|
|
|
uint16_t len = 0;
|
|
|
|
|
|
|
|
len = make_node_info_message(buffer);
|
|
|
|
int result = canardRequestOrRespond(&g_canard,
|
|
|
|
transfer->source_node_id,
|
|
|
|
UAVCAN_GET_NODE_INFO_DATA_TYPE_SIGNATURE,
|
|
|
|
UAVCAN_GET_NODE_INFO_DATA_TYPE_ID,
|
|
|
|
&transfer->transfer_id,
|
|
|
|
// transfer->priority,
|
|
|
|
CANARD_TRANSFER_PRIORITY_HIGH,
|
|
|
|
CanardResponse,
|
|
|
|
&buffer[0],
|
|
|
|
(uint16_t)len);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a pseudo random float in the range [0, 1].
|
|
|
|
*/
|
|
|
|
static float get_random_float(void)
|
|
|
|
{
|
|
|
|
static bool initialized = false;
|
|
|
|
if (!initialized)
|
|
|
|
{
|
|
|
|
initialized = true;
|
|
|
|
// desig_get_unique_id((uint32_t*)&node_unique_id[0]);
|
|
|
|
|
|
|
|
// const uint32_t *unique_32 = (uint32_t *)&node_unique_id[0];
|
|
|
|
|
|
|
|
// srand(HAL_GetTick() ^ *unique_32);
|
|
|
|
srand(HAL_GetTick());
|
|
|
|
}
|
|
|
|
|
|
|
|
return (float)rand() / (float)RAND_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
void get_unique_id(uint8_t *out_uid)
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < UNIQUE_ID_LENGTH_BYTES; i++)
|
|
|
|
{
|
|
|
|
out_uid[i] = node_unique_id[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_unique_id(char *str_unique_id)
|
|
|
|
{
|
|
|
|
for (uint8_t i = 0; i < strlen(str_unique_id); i++)
|
|
|
|
{
|
|
|
|
|
|
|
|
node_unique_id[i] = str_unique_id[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void publish_log_message( uavcan_log_level_t log_level, const char *source, const char *text)
|
|
|
|
{
|
|
|
|
|
|
|
|
uint8_t buffer[UAVCAN_DEBUG_LOG_MESSAGE_MESSAGE_SIZE] ={0};
|
|
|
|
uint8_t source_len = strlen(source) & 31;
|
|
|
|
uint8_t msg_len = strlen(text);
|
|
|
|
static uint8_t transfer_id;
|
|
|
|
if(msg_len > 90)
|
|
|
|
{
|
|
|
|
msg_len = 90;
|
|
|
|
}
|
|
|
|
/* Use manual mutex locking here to lock the global buffer as well */
|
|
|
|
buffer[0] = (log_level << 5) | source_len;
|
|
|
|
memcpy(&buffer[1], source, source_len);
|
|
|
|
memcpy(&buffer[1+source_len], text, msg_len);
|
|
|
|
canardBroadcast(
|
|
|
|
&g_canard,
|
|
|
|
UAVCAN_DEBUG_LOG_MESSAGE_DATA_TYPE_SIGNATURE,
|
|
|
|
UAVCAN_DEBUG_LOG_MESSAGE_DATA_TYPE_ID,
|
|
|
|
&transfer_id,
|
|
|
|
CANARD_TRANSFER_PRIORITY_LOWEST,
|
|
|
|
buffer,
|
|
|
|
1 + source_len + msg_len
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void send_uavcan_data(uavcan_send_data_t *send_data)
|
|
|
|
{
|
|
|
|
switch (send_data->id)
|
|
|
|
{
|
|
|
|
case UAVCAN_PROTOCOL_DEBUG_LOGMESSAGE_ID:
|
|
|
|
/* code */
|
|
|
|
break;
|
|
|
|
//case ZRZK_EQUIPMENT_FLOW_WATERDEPTH_ID:
|
|
|
|
// publish_water_dapth(&send_data->content.water_depth_msg);
|
|
|
|
//break;
|
|
|
|
case UAVCAN_EQUIPMENT_DEVICE_TEMPERATURE_ID:
|
|
|
|
publish_device_temperature(&send_data->content.device_temp_msg);
|
|
|
|
break;
|
|
|
|
case UAVCAN_EQUIPMENT_RANGE_SENSOR_MEASUREMENT_ID:
|
|
|
|
publish_measurement_canard(&send_data->content.measurement_msg);
|
|
|
|
break;
|
|
|
|
case UAVCAN_NODE_STATUS_DATA_TYPE_ID:
|
|
|
|
publish_node_status();
|
|
|
|
break;
|
|
|
|
case ZRZK_EQUIPMENT_RANGE_SENSOR_PROXIMITY_ID:
|
|
|
|
publish_proximity(&send_data->content.proximity);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void publish_measurement_canard(uavcan_measurement_t *msg) //MEASUREMENT
|
|
|
|
{
|
|
|
|
uint8_t buffer[UAVCAN_EQUIPMENT_RANGE_SENSOR_MEASUREMENT_MAX_SIZE];
|
|
|
|
uint32_t len = uavcan_equipment_range_sensor_Measurement_encode(msg, &buffer[0]);
|
|
|
|
|
|
|
|
if (UAVCAN_EQUIPMENT_RANGE_SENSOR_MEASUREMENT_MAX_SIZE != len)
|
|
|
|
return;
|
|
|
|
|
|
|
|
canardBroadcast(&g_canard,
|
|
|
|
UAVCAN_EQUIPMENT_RANGE_SENSOR_MEASUREMENT_SIGNATURE,
|
|
|
|
UAVCAN_EQUIPMENT_RANGE_SENSOR_MEASUREMENT_ID,
|
|
|
|
&transfer_id,
|
|
|
|
CANARD_TRANSFER_PRIORITY_HIGH,
|
|
|
|
&buffer[0],
|
|
|
|
len);
|
|
|
|
// HAL_UART_AbortReceive(&huart1);
|
|
|
|
// HAL_NVIC_DisableIRQ(USART1_IRQn);
|
|
|
|
// send_canard();
|
|
|
|
// HAL_NVIC_EnableIRQ(USART1_IRQn);
|
|
|
|
}
|
|
|
|
|
|
|
|
void publish_device_temperature(uavcan_equipment_device_Temperature *data)
|
|
|
|
{
|
|
|
|
uint8_t buffer[UAVCAN_EQUIPMENT_DEVICE_TEMPERATURE_MAX_SIZE] = {0};
|
|
|
|
uint32_t len = uavcan_equipment_device_Temperature_encode(data, &buffer);
|
|
|
|
if (len > 0)
|
|
|
|
{
|
|
|
|
canardBroadcast(
|
|
|
|
&g_canard,
|
|
|
|
UAVCAN_EQUIPMENT_DEVICE_TEMPERATURE_SIGNATURE,
|
|
|
|
UAVCAN_EQUIPMENT_DEVICE_TEMPERATURE_ID,
|
|
|
|
&transfer_id,
|
|
|
|
CANARD_TRANSFER_PRIORITY_LOWEST,
|
|
|
|
buffer,
|
|
|
|
len);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void publish_proximity(uavcan_proximity_t *msg)
|
|
|
|
{
|
|
|
|
uint8_t buffer[ZRZK_EQUIPMENT_RANGE_SENSOR_PROXIMITY_MAX_SIZE] = {0};
|
|
|
|
uint32_t len = zrzk_equipment_range_sensor_Proximity_encode(msg, &buffer);
|
|
|
|
if (len > 0)
|
|
|
|
{
|
|
|
|
canardBroadcast(
|
|
|
|
&g_canard,
|
|
|
|
ZRZK_EQUIPMENT_RANGE_SENSOR_PROXIMITY_SIGNATURE,
|
|
|
|
ZRZK_EQUIPMENT_RANGE_SENSOR_PROXIMITY_ID,
|
|
|
|
&transfer_id,
|
|
|
|
CANARD_TRANSFER_PRIORITY_HIGH,
|
|
|
|
buffer,
|
|
|
|
len);
|
|
|
|
}
|
|
|
|
}
|