mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-16 09:13:35 +08:00
Merge remote-tracking branch 'upstream/master' into ros_messagelayer_merge_attctlposctl
This commit is contained in:
@@ -43,6 +43,6 @@ SRCS = attitude_estimator_ekf_main.cpp \
|
||||
|
||||
MODULE_STACKSIZE = 1200
|
||||
|
||||
EXTRACFLAGS = -Wno-float-equal -Wframe-larger-than=3600
|
||||
EXTRACFLAGS = -Wno-float-equal -Wframe-larger-than=3700
|
||||
|
||||
EXTRACXXFLAGS = -Wframe-larger-than=2400
|
||||
|
||||
@@ -435,7 +435,7 @@ MavlinkReceiver::handle_message_hil_optical_flow(mavlink_message_t *msg)
|
||||
|
||||
/* Use distance value for range finder report */
|
||||
struct range_finder_report r;
|
||||
memset(&r, 0, sizeof(f));
|
||||
memset(&r, 0, sizeof(r));
|
||||
|
||||
r.timestamp = hrt_absolute_time();
|
||||
r.error_count = 0;
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
* @file mc_att_control_main.cpp
|
||||
* Multicopter attitude controller.
|
||||
*
|
||||
* Publication for the desired attitude tracking:
|
||||
* Daniel Mellinger and Vijay Kumar. Minimum Snap Trajectory Generation and Control for Quadrotors.
|
||||
* Int. Conf. on Robotics and Automation, Shanghai, China, May 2011.
|
||||
*
|
||||
* @author Tobias Naegeli <naegelit@student.ethz.ch>
|
||||
* @author Lorenz Meier <lm@inf.ethz.ch>
|
||||
* @author Anton Babushkin <anton.babushkin@me.com>
|
||||
|
||||
@@ -35,6 +35,12 @@
|
||||
* @file mc_pos_control_main.cpp
|
||||
* Multicopter position controller.
|
||||
*
|
||||
* Original publication for the desired attitude generation:
|
||||
* Daniel Mellinger and Vijay Kumar. Minimum Snap Trajectory Generation and Control for Quadrotors.
|
||||
* Int. Conf. on Robotics and Automation, Shanghai, China, May 2011
|
||||
*
|
||||
* Also inspired by https://pixhawk.org/firmware/apps/fw_pos_control_l1
|
||||
*
|
||||
* The controller has two loops: P loop for position error and PID loop for velocity error.
|
||||
* Output of velocity controller is thrust vector that splitted to thrust direction
|
||||
* (i.e. rotation matrix for multicopter orientation) and thrust module (i.e. multicopter thrust itself).
|
||||
@@ -727,11 +733,18 @@ MulticopterPositionControl::control_auto(float dt)
|
||||
reset_alt_sp();
|
||||
}
|
||||
|
||||
//Poll position setpoint
|
||||
bool updated;
|
||||
orb_check(_pos_sp_triplet_sub, &updated);
|
||||
|
||||
if (updated) {
|
||||
orb_copy(ORB_ID(position_setpoint_triplet), _pos_sp_triplet_sub, &_pos_sp_triplet);
|
||||
|
||||
//Make sure that the position setpoint is valid
|
||||
if (!isfinite(_pos_sp_triplet.current.lat) ||
|
||||
!isfinite(_pos_sp_triplet.current.lon) ||
|
||||
!isfinite(_pos_sp_triplet.current.alt)) {
|
||||
_pos_sp_triplet.current.valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_pos_sp_triplet.current.valid) {
|
||||
|
||||
@@ -58,17 +58,17 @@
|
||||
static const int ERROR = -1;
|
||||
|
||||
Geofence::Geofence() :
|
||||
SuperBlock(NULL, "GF"),
|
||||
_fence_pub(-1),
|
||||
_altitude_min(0),
|
||||
_altitude_max(0),
|
||||
_verticesCount(0),
|
||||
_param_geofence_on(this, "ON"),
|
||||
_param_altitude_mode(this, "ALTMODE"),
|
||||
_param_source(this, "SOURCE"),
|
||||
_param_counter_threshold(this, "COUNT"),
|
||||
_outside_counter(0),
|
||||
_mavlinkFd(-1)
|
||||
SuperBlock(NULL, "GF"),
|
||||
_fence_pub(-1),
|
||||
_altitude_min(0),
|
||||
_altitude_max(0),
|
||||
_verticesCount(0),
|
||||
_param_geofence_on(this, "ON"),
|
||||
_param_altitude_mode(this, "ALTMODE"),
|
||||
_param_source(this, "SOURCE"),
|
||||
_param_counter_threshold(this, "COUNT"),
|
||||
_outside_counter(0),
|
||||
_mavlinkFd(-1)
|
||||
{
|
||||
/* Load initial params */
|
||||
updateParams();
|
||||
@@ -92,22 +92,26 @@ bool Geofence::inside(const struct vehicle_global_position_s &global_position, f
|
||||
|
||||
|
||||
bool Geofence::inside(const struct vehicle_global_position_s &global_position,
|
||||
const struct vehicle_gps_position_s &gps_position,float baro_altitude_amsl) {
|
||||
const struct vehicle_gps_position_s &gps_position, float baro_altitude_amsl)
|
||||
{
|
||||
updateParams();
|
||||
|
||||
if (getAltitudeMode() == Geofence::GF_ALT_MODE_WGS84) {
|
||||
if (getSource() == Geofence::GF_SOURCE_GLOBALPOS) {
|
||||
return inside(global_position);
|
||||
|
||||
} else {
|
||||
return inside((double)gps_position.lat * 1.0e-7, (double)gps_position.lon * 1.0e-7,
|
||||
(double)gps_position.alt * 1.0e-3);
|
||||
(double)gps_position.alt * 1.0e-3);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (getSource() == Geofence::GF_SOURCE_GLOBALPOS) {
|
||||
return inside(global_position, baro_altitude_amsl);
|
||||
|
||||
} else {
|
||||
return inside((double)gps_position.lat * 1.0e-7, (double)gps_position.lon * 1.0e-7,
|
||||
baro_altitude_amsl);
|
||||
baro_altitude_amsl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,9 +124,12 @@ bool Geofence::inside(double lat, double lon, float altitude)
|
||||
_outside_counter = 0;
|
||||
return inside_fence;
|
||||
} {
|
||||
|
||||
_outside_counter++;
|
||||
if(_outside_counter > _param_counter_threshold.get()) {
|
||||
|
||||
if (_outside_counter > _param_counter_threshold.get()) {
|
||||
return inside_fence;
|
||||
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
@@ -133,8 +140,9 @@ bool Geofence::inside(double lat, double lon, float altitude)
|
||||
bool Geofence::inside_polygon(double lat, double lon, float altitude)
|
||||
{
|
||||
/* Return true if geofence is disabled */
|
||||
if (_param_geofence_on.get() != 1)
|
||||
if (_param_geofence_on.get() != 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (valid()) {
|
||||
|
||||
@@ -159,20 +167,22 @@ bool Geofence::inside_polygon(double lat, double lon, float altitude)
|
||||
if (dm_read(DM_KEY_FENCE_POINTS, i, &temp_vertex_i, sizeof(struct fence_vertex_s)) != sizeof(struct fence_vertex_s)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (dm_read(DM_KEY_FENCE_POINTS, j, &temp_vertex_j, sizeof(struct fence_vertex_s)) != sizeof(struct fence_vertex_s)) {
|
||||
break;
|
||||
}
|
||||
|
||||
// skip vertex 0 (return point)
|
||||
if (((double)temp_vertex_i.lon >= lon) != ((double)temp_vertex_j.lon >= lon) &&
|
||||
(lat <= (double)(temp_vertex_j.lat - temp_vertex_i.lat) * (lon - (double)temp_vertex_i.lon) /
|
||||
(double)(temp_vertex_j.lon - temp_vertex_i.lon) + (double)temp_vertex_i.lat)) {
|
||||
c = !c;
|
||||
(lat <= (double)(temp_vertex_j.lat - temp_vertex_i.lat) * (lon - (double)temp_vertex_i.lon) /
|
||||
(double)(temp_vertex_j.lon - temp_vertex_i.lon) + (double)temp_vertex_i.lat)) {
|
||||
c = !c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return c;
|
||||
|
||||
} else {
|
||||
/* Empty fence --> accept all points */
|
||||
return true;
|
||||
@@ -188,8 +198,9 @@ bool
|
||||
Geofence::valid()
|
||||
{
|
||||
// NULL fence is valid
|
||||
if (isEmpty())
|
||||
if (isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise
|
||||
if ((_verticesCount < 4) || (_verticesCount > GEOFENCE_MAX_VERTICES)) {
|
||||
@@ -214,26 +225,33 @@ Geofence::addPoint(int argc, char *argv[])
|
||||
return;
|
||||
}
|
||||
|
||||
if (argc < 3)
|
||||
if (argc < 3) {
|
||||
errx(1, "Specify: -clear | sequence latitude longitude [-publish]");
|
||||
}
|
||||
|
||||
ix = atoi(argv[0]);
|
||||
if (ix >= DM_KEY_FENCE_POINTS_MAX)
|
||||
|
||||
if (ix >= DM_KEY_FENCE_POINTS_MAX) {
|
||||
errx(1, "Sequence must be less than %d", DM_KEY_FENCE_POINTS_MAX);
|
||||
}
|
||||
|
||||
lat = strtod(argv[1], &end);
|
||||
lon = strtod(argv[2], &end);
|
||||
|
||||
last = 0;
|
||||
if ((argc > 3) && (strcmp(argv[3], "-publish") == 0))
|
||||
|
||||
if ((argc > 3) && (strcmp(argv[3], "-publish") == 0)) {
|
||||
last = 1;
|
||||
}
|
||||
|
||||
vertex.lat = (float)lat;
|
||||
vertex.lon = (float)lon;
|
||||
|
||||
if (dm_write(DM_KEY_FENCE_POINTS, ix, DM_PERSIST_POWER_ON_RESET, &vertex, sizeof(vertex)) == sizeof(vertex)) {
|
||||
if (last)
|
||||
if (last) {
|
||||
publishFence((unsigned)ix + 1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -243,10 +261,12 @@ Geofence::addPoint(int argc, char *argv[])
|
||||
void
|
||||
Geofence::publishFence(unsigned vertices)
|
||||
{
|
||||
if (_fence_pub == -1)
|
||||
if (_fence_pub == -1) {
|
||||
_fence_pub = orb_advertise(ORB_ID(fence), &vertices);
|
||||
else
|
||||
|
||||
} else {
|
||||
orb_publish(ORB_ID(fence), _fence_pub, &vertices);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@@ -257,26 +277,29 @@ Geofence::loadFromFile(const char *filename)
|
||||
int pointCounter = 0;
|
||||
bool gotVertical = false;
|
||||
const char commentChar = '#';
|
||||
int rc = ERROR;
|
||||
|
||||
/* Make sure no data is left in the datamanager */
|
||||
clearDm();
|
||||
|
||||
/* open the mixer definition file */
|
||||
fp = fopen(GEOFENCE_FILENAME, "r");
|
||||
|
||||
if (fp == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* create geofence points from valid lines and store in DM */
|
||||
for (;;) {
|
||||
|
||||
/* get a line, bail on error/EOF */
|
||||
if (fgets(line, sizeof(line), fp) == NULL)
|
||||
if (fgets(line, sizeof(line), fp) == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Trim leading whitespace */
|
||||
size_t textStart = 0;
|
||||
while((textStart < sizeof(line)/sizeof(char)) && isspace(line[textStart])) textStart++;
|
||||
|
||||
while ((textStart < sizeof(line) / sizeof(char)) && isspace(line[textStart])) { textStart++; }
|
||||
|
||||
/* if the line starts with #, skip */
|
||||
if (line[textStart] == commentChar) {
|
||||
@@ -299,55 +322,56 @@ Geofence::loadFromFile(const char *filename)
|
||||
|
||||
if (sscanf(line, "DMS %f %f %f %f %f %f", &lat_d, &lat_m, &lat_s, &lon_d, &lon_m, &lon_s) != 6) {
|
||||
warnx("Scanf to parse DMS geofence vertex failed.");
|
||||
return ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
// warnx("Geofence DMS: %.5f %.5f %.5f ; %.5f %.5f %.5f", (double)lat_d, (double)lat_m, (double)lat_s, (double)lon_d, (double)lon_m, (double)lon_s);
|
||||
|
||||
vertex.lat = lat_d + lat_m/60.0f + lat_s/3600.0f;
|
||||
vertex.lon = lon_d + lon_m/60.0f + lon_s/3600.0f;
|
||||
vertex.lat = lat_d + lat_m / 60.0f + lat_s / 3600.0f;
|
||||
vertex.lon = lon_d + lon_m / 60.0f + lon_s / 3600.0f;
|
||||
|
||||
} else {
|
||||
/* Handle decimal degree format */
|
||||
if (sscanf(line, "%f %f", &(vertex.lat), &(vertex.lon)) != 2) {
|
||||
warnx("Scanf to parse geofence vertex failed.");
|
||||
return ERROR;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (dm_write(DM_KEY_FENCE_POINTS, pointCounter, DM_PERSIST_POWER_ON_RESET, &vertex, sizeof(vertex)) != sizeof(vertex))
|
||||
return ERROR;
|
||||
if (dm_write(DM_KEY_FENCE_POINTS, pointCounter, DM_PERSIST_POWER_ON_RESET, &vertex, sizeof(vertex)) != sizeof(vertex)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
warnx("Geofence: point: %d, lat %.5f: lon: %.5f", pointCounter, (double)vertex.lat, (double)vertex.lon);
|
||||
warnx("Geofence: point: %d, lat %.5f: lon: %.5f", pointCounter, (double)vertex.lat, (double)vertex.lon);
|
||||
|
||||
pointCounter++;
|
||||
|
||||
} else {
|
||||
/* Parse the line as the vertical limits */
|
||||
if (sscanf(line, "%f %f", &_altitude_min, &_altitude_max) != 2)
|
||||
return ERROR;
|
||||
|
||||
if (sscanf(line, "%f %f", &_altitude_min, &_altitude_max) != 2) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
warnx("Geofence: alt min: %.4f, alt_max: %.4f", (double)_altitude_min, (double)_altitude_max);
|
||||
gotVertical = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
/* Check if import was successful */
|
||||
if(gotVertical && pointCounter > 0)
|
||||
{
|
||||
if (gotVertical && pointCounter > 0) {
|
||||
_verticesCount = pointCounter;
|
||||
warnx("Geofence: imported successfully");
|
||||
mavlink_log_info(_mavlinkFd, "Geofence imported");
|
||||
rc = OK;
|
||||
|
||||
} else {
|
||||
warnx("Geofence: import error");
|
||||
mavlink_log_critical(_mavlinkFd, "#audio: Geofence import error");
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
error:
|
||||
fclose(fp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int Geofence::clearDm()
|
||||
|
||||
@@ -877,6 +877,7 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
float w_xy_gps_p = params.w_xy_gps_p * w_gps_xy;
|
||||
float w_xy_gps_v = params.w_xy_gps_v * w_gps_xy;
|
||||
float w_z_gps_p = params.w_z_gps_p * w_gps_z;
|
||||
float w_z_gps_v = params.w_z_gps_v * w_gps_z;
|
||||
|
||||
float w_xy_vision_p = params.w_xy_vision_p;
|
||||
float w_xy_vision_v = params.w_xy_vision_v;
|
||||
@@ -907,6 +908,7 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
|
||||
if (use_gps_z) {
|
||||
accel_bias_corr[2] -= corr_gps[2][0] * w_z_gps_p * w_z_gps_p;
|
||||
accel_bias_corr[2] -= corr_gps[2][1] * w_z_gps_v;
|
||||
}
|
||||
|
||||
/* transform error vector from NED frame to body frame */
|
||||
@@ -991,6 +993,7 @@ int position_estimator_inav_thread_main(int argc, char *argv[])
|
||||
epv = fminf(epv, gps.epv);
|
||||
|
||||
inertial_filter_correct(corr_gps[2][0], dt, z_est, 0, w_z_gps_p);
|
||||
inertial_filter_correct(corr_gps[2][1], dt, z_est, 1, w_z_gps_v);
|
||||
}
|
||||
|
||||
if (use_vision_z) {
|
||||
|
||||
@@ -63,6 +63,17 @@ PARAM_DEFINE_FLOAT(INAV_W_Z_BARO, 0.5f);
|
||||
*/
|
||||
PARAM_DEFINE_FLOAT(INAV_W_Z_GPS_P, 0.005f);
|
||||
|
||||
/**
|
||||
* Z velocity weight for GPS
|
||||
*
|
||||
* Weight (cutoff frequency) for GPS altitude velocity measurements.
|
||||
*
|
||||
* @min 0.0
|
||||
* @max 10.0
|
||||
* @group Position Estimator INAV
|
||||
*/
|
||||
PARAM_DEFINE_FLOAT(INAV_W_Z_GPS_V, 0.0f);
|
||||
|
||||
/**
|
||||
* Z axis weight for vision
|
||||
*
|
||||
@@ -281,6 +292,7 @@ int parameters_init(struct position_estimator_inav_param_handles *h)
|
||||
{
|
||||
h->w_z_baro = param_find("INAV_W_Z_BARO");
|
||||
h->w_z_gps_p = param_find("INAV_W_Z_GPS_P");
|
||||
h->w_z_gps_v = param_find("INAV_W_Z_GPS_V");
|
||||
h->w_z_vision_p = param_find("INAV_W_Z_VIS_P");
|
||||
h->w_z_sonar = param_find("INAV_W_Z_SONAR");
|
||||
h->w_xy_gps_p = param_find("INAV_W_XY_GPS_P");
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
struct position_estimator_inav_params {
|
||||
float w_z_baro;
|
||||
float w_z_gps_p;
|
||||
float w_z_gps_v;
|
||||
float w_z_vision_p;
|
||||
float w_z_sonar;
|
||||
float w_xy_gps_p;
|
||||
@@ -68,6 +69,7 @@ struct position_estimator_inav_params {
|
||||
struct position_estimator_inav_param_handles {
|
||||
param_t w_z_baro;
|
||||
param_t w_z_gps_p;
|
||||
param_t w_z_gps_v;
|
||||
param_t w_z_vision_p;
|
||||
param_t w_z_sonar;
|
||||
param_t w_xy_gps_p;
|
||||
|
||||
@@ -47,7 +47,8 @@
|
||||
#ifdef CONFIG_ARCH_CHIP_STM32
|
||||
#include <up_arch.h>
|
||||
|
||||
#define DBGMCU_IDCODE 0xE0042000
|
||||
#define DBGMCU_IDCODE 0xE0042000 //STM DocID018909 Rev 8 Sect 38.18 (MCU device ID code)
|
||||
#define UNIQUE_ID 0x1FFF7A10 //STM DocID018909 Rev 8 Sect 39.1 (Unique device ID Register)
|
||||
|
||||
#define STM32F40x_41x 0x413
|
||||
#define STM32F42x_43x 0x419
|
||||
@@ -57,7 +58,13 @@
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/** Copy the 96bit MCU Unique ID into the provided pointer */
|
||||
void mcu_unique_id(uint32_t *uid_96_bit)
|
||||
{
|
||||
uid_96_bit[0] = getreg32(UNIQUE_ID);
|
||||
uid_96_bit[1] = getreg32(UNIQUE_ID+4);
|
||||
uid_96_bit[2] = getreg32(UNIQUE_ID+8);
|
||||
}
|
||||
|
||||
int mcu_version(char* rev, char** revstr)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* magic numbers from reference manual */
|
||||
enum MCU_REV {
|
||||
MCU_REV_STM32F4_REV_A = 0x1000,
|
||||
@@ -42,6 +44,15 @@ enum MCU_REV {
|
||||
MCU_REV_STM32F4_REV_3 = 0x2001
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reports the microcontroller unique id.
|
||||
*
|
||||
* This ID is guaranteed to be unique for every mcu.
|
||||
* @param uid_96_bit A uint32_t[3] array to copy the data to.
|
||||
*/
|
||||
__EXPORT void mcu_unique_id(uint32_t *uid_96_bit);
|
||||
|
||||
/**
|
||||
* Reports the microcontroller version of the main CPU.
|
||||
*
|
||||
|
||||
@@ -49,6 +49,13 @@ UavcanEscController::UavcanEscController(uavcan::INode &node) :
|
||||
_uavcan_sub_status(node),
|
||||
_orb_timer(node)
|
||||
{
|
||||
if (_perfcnt_invalid_input == nullptr) {
|
||||
errx(1, "uavcan: couldn't allocate _perfcnt_invalid_input");
|
||||
}
|
||||
|
||||
if (_perfcnt_scaling_error == nullptr) {
|
||||
errx(1, "uavcan: couldn't allocate _perfcnt_scaling_error");
|
||||
}
|
||||
}
|
||||
|
||||
UavcanEscController::~UavcanEscController()
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
MODULE_COMMAND = uavcan
|
||||
|
||||
MAXOPTIMIZATION = -Os
|
||||
MAXOPTIMIZATION = -O3
|
||||
|
||||
# Main
|
||||
SRCS += uavcan_main.cpp \
|
||||
@@ -57,7 +57,7 @@ SRCS += sensors/sensor_bridge.cpp \
|
||||
#
|
||||
# libuavcan
|
||||
#
|
||||
include $(PX4_LIB_DIR)/uavcan/libuavcan/include.mk
|
||||
include $(PX4_LIB_DIR)uavcan/libuavcan/include.mk
|
||||
SRCS += $(LIBUAVCAN_SRC)
|
||||
INCLUDE_DIRS += $(LIBUAVCAN_INC)
|
||||
# Since actual compiler mode is C++11, the library will default to UAVCAN_CPP11, but it will fail to compile
|
||||
@@ -67,7 +67,7 @@ override EXTRADEFINES := $(EXTRADEFINES) -DUAVCAN_CPP_VERSION=UAVCAN_CPP03 -DUAV
|
||||
#
|
||||
# libuavcan drivers for STM32
|
||||
#
|
||||
include $(PX4_LIB_DIR)/uavcan/libuavcan_drivers/stm32/driver/include.mk
|
||||
include $(PX4_LIB_DIR)uavcan/libuavcan_drivers/stm32/driver/include.mk
|
||||
SRCS += $(LIBUAVCAN_STM32_SRC)
|
||||
INCLUDE_DIRS += $(LIBUAVCAN_STM32_INC)
|
||||
override EXTRADEFINES := $(EXTRADEFINES) -DUAVCAN_STM32_NUTTX -DUAVCAN_STM32_NUM_IFACES=2
|
||||
|
||||
@@ -81,6 +81,18 @@ UavcanNode::UavcanNode(uavcan::ICanDriver &can_driver, uavcan::ISystemClock &sys
|
||||
if (res < 0) {
|
||||
std::abort();
|
||||
}
|
||||
|
||||
if (_perfcnt_node_spin_elapsed == nullptr) {
|
||||
errx(1, "uavcan: couldn't allocate _perfcnt_node_spin_elapsed");
|
||||
}
|
||||
|
||||
if (_perfcnt_esc_mixer_output_elapsed == nullptr) {
|
||||
errx(1, "uavcan: couldn't allocate _perfcnt_esc_mixer_output_elapsed");
|
||||
}
|
||||
|
||||
if (_perfcnt_esc_mixer_total_elapsed == nullptr) {
|
||||
errx(1, "uavcan: couldn't allocate _perfcnt_esc_mixer_total_elapsed");
|
||||
}
|
||||
}
|
||||
|
||||
UavcanNode::~UavcanNode()
|
||||
@@ -118,6 +130,10 @@ UavcanNode::~UavcanNode()
|
||||
}
|
||||
|
||||
_instance = nullptr;
|
||||
|
||||
perf_free(_perfcnt_node_spin_elapsed);
|
||||
perf_free(_perfcnt_esc_mixer_output_elapsed);
|
||||
perf_free(_perfcnt_esc_mixer_total_elapsed);
|
||||
}
|
||||
|
||||
int UavcanNode::start(uavcan::NodeID node_id, uint32_t bitrate)
|
||||
@@ -265,10 +281,12 @@ int UavcanNode::init(uavcan::NodeID node_id)
|
||||
|
||||
void UavcanNode::node_spin_once()
|
||||
{
|
||||
perf_begin(_perfcnt_node_spin_elapsed);
|
||||
const int spin_res = _node.spin(uavcan::MonotonicTime());
|
||||
if (spin_res < 0) {
|
||||
warnx("node spin error %i", spin_res);
|
||||
}
|
||||
perf_end(_perfcnt_node_spin_elapsed);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -344,8 +362,12 @@ int UavcanNode::run()
|
||||
// Mutex is unlocked while the thread is blocked on IO multiplexing
|
||||
(void)pthread_mutex_unlock(&_node_mutex);
|
||||
|
||||
perf_end(_perfcnt_esc_mixer_total_elapsed); // end goes first, it's not a mistake
|
||||
|
||||
const int poll_ret = ::poll(_poll_fds, _poll_fds_num, PollTimeoutMs);
|
||||
|
||||
perf_begin(_perfcnt_esc_mixer_total_elapsed);
|
||||
|
||||
(void)pthread_mutex_lock(&_node_mutex);
|
||||
|
||||
node_spin_once(); // Non-blocking
|
||||
@@ -430,7 +452,9 @@ int UavcanNode::run()
|
||||
}
|
||||
// Output to the bus
|
||||
_outputs.timestamp = hrt_absolute_time();
|
||||
perf_begin(_perfcnt_esc_mixer_output_elapsed);
|
||||
_esc_controller.update_outputs(_outputs.output, _outputs.noutputs);
|
||||
perf_end(_perfcnt_esc_mixer_output_elapsed);
|
||||
}
|
||||
|
||||
|
||||
@@ -484,7 +508,7 @@ UavcanNode::teardown()
|
||||
_control_subs[i] = -1;
|
||||
}
|
||||
}
|
||||
return ::close(_armed_sub);
|
||||
return (_armed_sub >= 0) ? ::close(_armed_sub) : 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <uavcan_stm32/uavcan_stm32.hpp>
|
||||
#include <drivers/device/device.h>
|
||||
#include <systemlib/perf_counter.h>
|
||||
|
||||
#include <uORB/topics/actuator_controls.h>
|
||||
#include <uORB/topics/actuator_outputs.h>
|
||||
@@ -66,7 +66,7 @@
|
||||
*/
|
||||
class UavcanNode : public device::CDev
|
||||
{
|
||||
static constexpr unsigned MemPoolSize = 10752;
|
||||
static constexpr unsigned MemPoolSize = 10752; ///< Refer to the libuavcan manual to learn why
|
||||
static constexpr unsigned RxQueueLenPerIface = 64;
|
||||
static constexpr unsigned StackSize = 3000;
|
||||
|
||||
@@ -107,11 +107,11 @@ private:
|
||||
int _task = -1; ///< handle to the OS task
|
||||
bool _task_should_exit = false; ///< flag to indicate to tear down the CAN driver
|
||||
int _armed_sub = -1; ///< uORB subscription of the arming status
|
||||
actuator_armed_s _armed; ///< the arming request of the system
|
||||
actuator_armed_s _armed = {}; ///< the arming request of the system
|
||||
bool _is_armed = false; ///< the arming status of the actuators on the bus
|
||||
|
||||
int _test_motor_sub = -1; ///< uORB subscription of the test_motor status
|
||||
test_motor_s _test_motor;
|
||||
test_motor_s _test_motor = {};
|
||||
bool _test_in_progress = false;
|
||||
|
||||
unsigned _output_count = 0; ///< number of actuators currently available
|
||||
@@ -135,11 +135,15 @@ private:
|
||||
unsigned _poll_fds_num = 0;
|
||||
|
||||
int _actuator_direct_sub = -1; ///< uORB subscription of the actuator_direct topic
|
||||
uint8_t _actuator_direct_poll_fd_num;
|
||||
actuator_direct_s _actuator_direct;
|
||||
uint8_t _actuator_direct_poll_fd_num = 0;
|
||||
actuator_direct_s _actuator_direct = {};
|
||||
|
||||
actuator_outputs_s _outputs;
|
||||
actuator_outputs_s _outputs = {};
|
||||
|
||||
// index into _poll_fds for each _control_subs handle
|
||||
uint8_t _poll_ids[NUM_ACTUATOR_CONTROL_GROUPS_UAVCAN];
|
||||
|
||||
perf_counter_t _perfcnt_node_spin_elapsed = perf_alloc(PC_ELAPSED, "uavcan_node_spin_elapsed");
|
||||
perf_counter_t _perfcnt_esc_mixer_output_elapsed = perf_alloc(PC_ELAPSED, "uavcan_esc_mixer_output_elapsed");
|
||||
perf_counter_t _perfcnt_esc_mixer_total_elapsed = perf_alloc(PC_ELAPSED, "uavcan_esc_mixer_total_elapsed");
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user