mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-31 05:11:36 +08:00
UAVCAN: Fixed all compile errors
This commit is contained in:
@@ -31,14 +31,18 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <systemlib/err.h>
|
#include <systemlib/err.h>
|
||||||
#include <systemlib/systemlib.h>
|
#include <systemlib/systemlib.h>
|
||||||
|
#include <systemlib/mixer/mixer.h>
|
||||||
#include <arch/board/board.h>
|
#include <arch/board/board.h>
|
||||||
#include <arch/chip/chip.h>
|
#include <arch/chip/chip.h>
|
||||||
|
|
||||||
#include <drivers/device/device.h>
|
#include <drivers/drv_hrt.h>
|
||||||
|
#include <drivers/drv_pwm_output.h>
|
||||||
|
|
||||||
#include "uavcan_main.hpp"
|
#include "uavcan_main.hpp"
|
||||||
|
|
||||||
@@ -55,7 +59,13 @@
|
|||||||
*/
|
*/
|
||||||
UavcanNode *UavcanNode::_instance;
|
UavcanNode *UavcanNode::_instance;
|
||||||
|
|
||||||
UavcanNode(uavcan::ICanDriver &can_driver, uavcan::ISystemClock &system_clock) :
|
UavcanNode::UavcanNode(uavcan::ICanDriver &can_driver, uavcan::ISystemClock &system_clock) :
|
||||||
|
CDev("uavcan", UAVCAN_DEVICE_PATH),
|
||||||
|
_task(0),
|
||||||
|
_task_should_exit(false),
|
||||||
|
_armed_sub(-1),
|
||||||
|
_is_armed(false),
|
||||||
|
_output_count(0),
|
||||||
_node(can_driver, system_clock),
|
_node(can_driver, system_clock),
|
||||||
_controls({}),
|
_controls({}),
|
||||||
_poll_fds({})
|
_poll_fds({})
|
||||||
@@ -65,8 +75,37 @@ UavcanNode(uavcan::ICanDriver &can_driver, uavcan::ISystemClock &system_clock) :
|
|||||||
_control_topics[2] = ORB_ID(actuator_controls_2);
|
_control_topics[2] = ORB_ID(actuator_controls_2);
|
||||||
_control_topics[3] = ORB_ID(actuator_controls_3);
|
_control_topics[3] = ORB_ID(actuator_controls_3);
|
||||||
|
|
||||||
memset(_controls, 0, sizeof(_controls));
|
// memset(_controls, 0, sizeof(_controls));
|
||||||
memset(_poll_fds, 0, sizeof(_poll_fds));
|
// memset(_poll_fds, 0, sizeof(_poll_fds));
|
||||||
|
}
|
||||||
|
|
||||||
|
UavcanNode::~UavcanNode()
|
||||||
|
{
|
||||||
|
if (_task != -1) {
|
||||||
|
/* tell the task we want it to go away */
|
||||||
|
_task_should_exit = true;
|
||||||
|
|
||||||
|
unsigned i = 10;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* wait 50ms - it should wake every 100ms or so worst-case */
|
||||||
|
usleep(50000);
|
||||||
|
|
||||||
|
/* if we have given up, kill it */
|
||||||
|
if (--i == 0) {
|
||||||
|
task_delete(_task);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (_task != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up the alternate device node */
|
||||||
|
// unregister_driver(PWM_OUTPUT_DEVICE_PATH);
|
||||||
|
|
||||||
|
::close(_armed_sub);
|
||||||
|
|
||||||
|
_instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UavcanNode::start(uavcan::NodeID node_id, uint32_t bitrate)
|
int UavcanNode::start(uavcan::NodeID node_id, uint32_t bitrate)
|
||||||
@@ -123,6 +162,24 @@ int UavcanNode::start(uavcan::NodeID node_id, uint32_t bitrate)
|
|||||||
return node_init_res;
|
return node_init_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start the task. Normally it should never exit.
|
||||||
|
*/
|
||||||
|
static auto run_trampoline = [](int, char *[]) {return UavcanNode::_instance->run();};
|
||||||
|
_instance->_task = task_spawn_cmd("uavcan", SCHED_DEFAULT, SCHED_PRIORITY_DEFAULT, StackSize,
|
||||||
|
static_cast<main_t>(run_trampoline), nullptr);
|
||||||
|
|
||||||
|
if (_instance->_task < 0) {
|
||||||
|
warnx("start failed: %d", errno);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int UavcanNode::init(uavcan::NodeID node_id)
|
||||||
|
{
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* do regular cdev init */
|
/* do regular cdev init */
|
||||||
@@ -131,16 +188,6 @@ int UavcanNode::start(uavcan::NodeID node_id, uint32_t bitrate)
|
|||||||
if (ret != OK)
|
if (ret != OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/*
|
|
||||||
* Start the task. Normally it should never exit.
|
|
||||||
*/
|
|
||||||
static auto run_trampoline = [](int, char *[]) {return UavcanNode::_instance->run();};
|
|
||||||
return task_spawn_cmd("uavcan", SCHED_DEFAULT, SCHED_PRIORITY_DEFAULT, StackSize,
|
|
||||||
static_cast<main_t>(run_trampoline), nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
int UavcanNode::init(uavcan::NodeID node_id)
|
|
||||||
{
|
|
||||||
uavcan::protocol::SoftwareVersion swver;
|
uavcan::protocol::SoftwareVersion swver;
|
||||||
swver.major = 12; // TODO fill version info
|
swver.major = 12; // TODO fill version info
|
||||||
swver.minor = 34;
|
swver.minor = 34;
|
||||||
@@ -162,32 +209,35 @@ int UavcanNode::run()
|
|||||||
{
|
{
|
||||||
_node.setStatusOk();
|
_node.setStatusOk();
|
||||||
|
|
||||||
|
// XXX figure out the output count
|
||||||
|
_output_count = 2;
|
||||||
|
|
||||||
|
|
||||||
_armed_sub = orb_subscribe(ORB_ID(actuator_armed));
|
_armed_sub = orb_subscribe(ORB_ID(actuator_armed));
|
||||||
|
|
||||||
while (true) {
|
actuator_outputs_s outputs;
|
||||||
|
memset(&outputs, 0, sizeof(outputs));
|
||||||
|
|
||||||
|
while (!_task_should_exit) {
|
||||||
|
|
||||||
if (_groups_subscribed != _groups_required) {
|
if (_groups_subscribed != _groups_required) {
|
||||||
subscribe();
|
subscribe();
|
||||||
_groups_subscribed = _groups_required;
|
_groups_subscribed = _groups_required;
|
||||||
/* force setting update rate */
|
|
||||||
_current_update_rate = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = ::poll(_poll_fds, _poll_fds_num, 5/* 5 ms wait time */);
|
int ret = ::poll(_poll_fds, _poll_fds_num, 5/* 5 ms wait time */);
|
||||||
|
|
||||||
/* this would be bad... */
|
// this would be bad...
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
log("poll error %d", errno);
|
log("poll error %d", errno);
|
||||||
usleep(1000000);
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else if (ret == 0) {
|
} else if (ret == 0) {
|
||||||
/* timeout: no control data, switch to failsafe values */
|
// timeout: no control data, switch to failsafe values
|
||||||
// warnx("no PWM: failsafe");
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* get controls for required topics */
|
// get controls for required topics
|
||||||
unsigned poll_id = 0;
|
unsigned poll_id = 0;
|
||||||
for (unsigned i = 0; i < NUM_ACTUATOR_CONTROL_GROUPS; i++) {
|
for (unsigned i = 0; i < NUM_ACTUATOR_CONTROL_GROUPS; i++) {
|
||||||
if (_control_subs[i] > 0) {
|
if (_control_subs[i] > 0) {
|
||||||
@@ -198,7 +248,7 @@ int UavcanNode::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* can we mix? */
|
//can we mix?
|
||||||
if (_mixers != nullptr) {
|
if (_mixers != nullptr) {
|
||||||
|
|
||||||
// XXX one output group has 8 outputs max,
|
// XXX one output group has 8 outputs max,
|
||||||
@@ -209,9 +259,9 @@ int UavcanNode::run()
|
|||||||
outputs.noutputs = _mixers->mix(&outputs.output[0], num_outputs_max);
|
outputs.noutputs = _mixers->mix(&outputs.output[0], num_outputs_max);
|
||||||
outputs.timestamp = hrt_absolute_time();
|
outputs.timestamp = hrt_absolute_time();
|
||||||
|
|
||||||
/* iterate actuators */
|
// iterate actuators
|
||||||
for (unsigned i = 0; i < outputs.noutputs; i++) {
|
for (unsigned i = 0; i < outputs.noutputs; i++) {
|
||||||
/* last resort: catch NaN, INF and out-of-band errors */
|
// last resort: catch NaN, INF and out-of-band errors
|
||||||
if (!isfinite(outputs.output[i]) ||
|
if (!isfinite(outputs.output[i]) ||
|
||||||
outputs.output[i] < -1.0f ||
|
outputs.output[i] < -1.0f ||
|
||||||
outputs.output[i] > 1.0f) {
|
outputs.output[i] > 1.0f) {
|
||||||
@@ -224,25 +274,25 @@ int UavcanNode::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("CAN out: ")
|
printf("CAN out: ");
|
||||||
/* output to the bus */
|
/* output to the bus */
|
||||||
for (unsigned i = 0; i < outputs.noutputs; i++) {
|
for (unsigned i = 0; i < outputs.noutputs; i++) {
|
||||||
printf("%u: %8.4f ", i, outputs.output[i])
|
printf("%u: %8.4f ", i, outputs.output[i]);
|
||||||
// can_send_xxx
|
// can_send_xxx
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("%s\n", (_is_armed) ? "ARMED" : "DISARMED");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check arming state */
|
// Check arming state
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
orb_check(_armed_sub, &updated);
|
orb_check(_armed_sub, &updated);
|
||||||
|
|
||||||
if (updated) {
|
if (updated) {
|
||||||
orb_copy(ORB_ID(actuator_armed), _armed_sub, &_armed);
|
orb_copy(ORB_ID(actuator_armed), _armed_sub, &_armed);
|
||||||
|
|
||||||
/* update the armed status and check that we're not locked down */
|
// Update the armed status and check that we're not locked down
|
||||||
bool set_armed = _armed.armed && !_armed.lockdown;
|
bool set_armed = _armed.armed && !_armed.lockdown;
|
||||||
|
|
||||||
arm_actuators(set_armed);
|
arm_actuators(set_armed);
|
||||||
@@ -271,7 +321,7 @@ UavcanNode::control_callback(uintptr_t handle,
|
|||||||
{
|
{
|
||||||
const actuator_controls_s *controls = (actuator_controls_s *)handle;
|
const actuator_controls_s *controls = (actuator_controls_s *)handle;
|
||||||
|
|
||||||
input = _controls[control_group].control[control_index];
|
input = controls[control_group].control[control_index];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,22 +337,24 @@ UavcanNode::teardown()
|
|||||||
::close(_armed_sub);
|
::close(_armed_sub);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
UavcanNode::arm_actuators(bool arm)
|
UavcanNode::arm_actuators(bool arm)
|
||||||
{
|
{
|
||||||
bool changed = (_armed != arm);
|
bool changed = (_is_armed != arm);
|
||||||
|
|
||||||
_armed = arm;
|
_is_armed = arm;
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
// Propagate immediately to CAN bus
|
// Propagate immediately to CAN bus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
UavcanNode::subscribe()
|
UavcanNode::subscribe()
|
||||||
{
|
{
|
||||||
/* subscribe/unsubscribe to required actuator control groups */
|
// Subscribe/unsubscribe to required actuator control groups
|
||||||
uint32_t sub_groups = _groups_required & ~_groups_subscribed;
|
uint32_t sub_groups = _groups_required & ~_groups_subscribed;
|
||||||
uint32_t unsub_groups = _groups_subscribed & ~_groups_required;
|
uint32_t unsub_groups = _groups_subscribed & ~_groups_required;
|
||||||
_poll_fds_num = 0;
|
_poll_fds_num = 0;
|
||||||
@@ -326,7 +378,7 @@ UavcanNode::subscribe()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PX4FMU::pwm_ioctl(file *filp, int cmd, unsigned long arg)
|
UavcanNode::pwm_ioctl(file *filp, int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <uavcan_stm32/uavcan_stm32.hpp>
|
#include <uavcan_stm32/uavcan_stm32.hpp>
|
||||||
#include <drivers/drv_pwm_output.h>
|
#include <drivers/device/device.h>
|
||||||
|
|
||||||
|
#include <uORB/topics/actuator_controls.h>
|
||||||
|
#include <uORB/topics/actuator_outputs.h>
|
||||||
|
#include <uORB/topics/actuator_armed.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file uavcan_main.hpp
|
* @file uavcan_main.hpp
|
||||||
@@ -44,6 +50,9 @@
|
|||||||
* @author Pavel Kirienko <pavel.kirienko@gmail.com>
|
* @author Pavel Kirienko <pavel.kirienko@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define NUM_ACTUATOR_CONTROL_GROUPS_UAVCAN 4
|
||||||
|
#define UAVCAN_DEVICE_PATH "/dev/uavcan"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A UAVCAN node.
|
* A UAVCAN node.
|
||||||
*/
|
*/
|
||||||
@@ -57,21 +66,36 @@ public:
|
|||||||
typedef uavcan::Node<MemPoolSize> Node;
|
typedef uavcan::Node<MemPoolSize> Node;
|
||||||
typedef uavcan_stm32::CanInitHelper<RxQueueLenPerIface> CanInitHelper;
|
typedef uavcan_stm32::CanInitHelper<RxQueueLenPerIface> CanInitHelper;
|
||||||
|
|
||||||
UavcanNode(uavcan::ICanDriver &can_driver, uavcan::ISystemClock &system_clock);
|
UavcanNode(uavcan::ICanDriver &can_driver, uavcan::ISystemClock &system_clock);
|
||||||
|
|
||||||
static int start(uavcan::NodeID node_id, uint32_t bitrate);
|
virtual ~UavcanNode();
|
||||||
|
|
||||||
Node &getNode() { return _node; }
|
static int start(uavcan::NodeID node_id, uint32_t bitrate);
|
||||||
|
|
||||||
|
Node& getNode() { return _node; }
|
||||||
|
|
||||||
static int control_callback(uintptr_t handle,
|
static int control_callback(uintptr_t handle,
|
||||||
uint8_t control_group,
|
uint8_t control_group,
|
||||||
uint8_t control_index,
|
uint8_t control_index,
|
||||||
float &input);
|
float &input);
|
||||||
void subscribe();
|
|
||||||
|
void subscribe();
|
||||||
|
|
||||||
|
int teardown();
|
||||||
|
int arm_actuators(bool arm);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int init(uavcan::NodeID node_id);
|
int init(uavcan::NodeID node_id);
|
||||||
int run();
|
int run();
|
||||||
|
int pwm_ioctl(file *filp, int cmd, unsigned long arg);
|
||||||
|
|
||||||
|
int _task; ///< handle to the OS task
|
||||||
|
bool _task_should_exit; ///< flag to indicate to tear down the CAN driver
|
||||||
|
int _armed_sub; ///< uORB subscription of the arming status
|
||||||
|
actuator_armed_s _armed; ///< the arming request of the system
|
||||||
|
bool _is_armed; ///< the arming status of the actuators on the bus
|
||||||
|
|
||||||
|
unsigned _output_count; ///< number of actuators currently available
|
||||||
|
|
||||||
static UavcanNode *_instance; ///< pointer to the library instance
|
static UavcanNode *_instance; ///< pointer to the library instance
|
||||||
Node _node;
|
Node _node;
|
||||||
@@ -80,9 +104,9 @@ private:
|
|||||||
|
|
||||||
uint32_t _groups_required;
|
uint32_t _groups_required;
|
||||||
uint32_t _groups_subscribed;
|
uint32_t _groups_subscribed;
|
||||||
int _control_subs[NUM_ACTUATOR_CONTROL_GROUPS];
|
int _control_subs[NUM_ACTUATOR_CONTROL_GROUPS_UAVCAN];
|
||||||
actuator_controls_s _controls[NUM_ACTUATOR_CONTROL_GROUPS];
|
actuator_controls_s _controls[NUM_ACTUATOR_CONTROL_GROUPS_UAVCAN];
|
||||||
orb_id_t _control_topics[NUM_ACTUATOR_CONTROL_GROUPS];
|
orb_id_t _control_topics[NUM_ACTUATOR_CONTROL_GROUPS_UAVCAN];
|
||||||
pollfd _poll_fds[NUM_ACTUATOR_CONTROL_GROUPS];
|
pollfd _poll_fds[NUM_ACTUATOR_CONTROL_GROUPS_UAVCAN];
|
||||||
unsigned _poll_fds_num;
|
unsigned _poll_fds_num;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user