mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-06-30 18:30:34 +08:00
mc_pos_control: refactor to use ModuleBase
This commit is contained in:
@@ -34,17 +34,13 @@
|
||||
/**
|
||||
* @file mc_pos_control_main.cpp
|
||||
* Multicopter position controller.
|
||||
*
|
||||
* The controller has two loops: P loop for position error and PID loop for velocity error.
|
||||
* Output of velocity controller is thrust vector that is split to thrust direction
|
||||
* (i.e. rotation matrix for multicopter orientation) and thrust scalar (i.e. multicopter thrust itself).
|
||||
* Controller doesn't use Euler angles for work, they generated only for more human-friendly control and logging.
|
||||
*/
|
||||
|
||||
#include <px4_config.h>
|
||||
#include <px4_defines.h>
|
||||
#include <px4_module_params.h>
|
||||
#include <px4_tasks.h>
|
||||
#include <px4_module.h>
|
||||
#include <px4_posix.h>
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <systemlib/hysteresis/hysteresis.h>
|
||||
@@ -73,34 +69,34 @@
|
||||
|
||||
/**
|
||||
* Multicopter position control app start / stop handling function
|
||||
*
|
||||
* @ingroup apps
|
||||
*/
|
||||
extern "C" __EXPORT int mc_pos_control_main(int argc, char *argv[]);
|
||||
|
||||
class MulticopterPositionControl : public control::SuperBlock, public ModuleParams
|
||||
class MulticopterPositionControl : public ModuleBase<MulticopterPositionControl>, public control::SuperBlock,
|
||||
public ModuleParams
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
MulticopterPositionControl();
|
||||
|
||||
/**
|
||||
* Destructor, also kills task.
|
||||
*/
|
||||
~MulticopterPositionControl();
|
||||
|
||||
/**
|
||||
* Start task.
|
||||
*
|
||||
* @return OK on success.
|
||||
*/
|
||||
int start();
|
||||
/** @see ModuleBase */
|
||||
static int task_spawn(int argc, char *argv[]);
|
||||
|
||||
/** @see ModuleBase */
|
||||
static MulticopterPositionControl *instantiate(int argc, char *argv[]);
|
||||
|
||||
/** @see ModuleBase */
|
||||
static int custom_command(int argc, char *argv[]);
|
||||
|
||||
/** @see ModuleBase */
|
||||
static int print_usage(const char *reason = nullptr);
|
||||
|
||||
/** @see ModuleBase::run() */
|
||||
void run() override;
|
||||
|
||||
private:
|
||||
|
||||
bool _task_should_exit = false; /**<true if task should exit */
|
||||
bool _in_smooth_takeoff = false; /**<true if takeoff ramp is applied */
|
||||
|
||||
orb_advert_t _att_sp_pub{nullptr}; /**< attitude setpoint publication */
|
||||
@@ -109,7 +105,6 @@ private:
|
||||
orb_advert_t _pub_vehicle_command{nullptr}; /**< vehicle command publication */
|
||||
orb_id_t _attitude_setpoint_id{nullptr};
|
||||
|
||||
int _control_task{-1}; /**< task handle for task */
|
||||
int _vehicle_status_sub{-1}; /**< vehicle status subscription */
|
||||
int _vehicle_land_detected_sub{-1}; /**< vehicle land detected subscription */
|
||||
int _control_mode_sub{-1}; /**< vehicle control mode subscription */
|
||||
@@ -296,11 +291,32 @@ private:
|
||||
void task_main();
|
||||
};
|
||||
|
||||
namespace pos_control
|
||||
|
||||
int MulticopterPositionControl::print_usage(const char *reason)
|
||||
{
|
||||
MulticopterPositionControl *g_control;
|
||||
if (reason) {
|
||||
PX4_WARN("%s\n", reason);
|
||||
}
|
||||
|
||||
PRINT_MODULE_DESCRIPTION(
|
||||
R"DESCR_STR(
|
||||
### Description
|
||||
The controller has two loops: a P loop for position error and a PID loop for velocity error.
|
||||
Output of the velocity controller is thrust vector that is split to thrust direction
|
||||
(i.e. rotation matrix for multicopter orientation) and thrust scalar (i.e. multicopter thrust itself).
|
||||
|
||||
The controller doesn't use Euler angles for its work, they are generated only for more human-friendly control and
|
||||
logging.
|
||||
)DESCR_STR");
|
||||
|
||||
PRINT_MODULE_USAGE_NAME("mc_pos_control", "controller");
|
||||
PRINT_MODULE_USAGE_COMMAND("start");
|
||||
PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
MulticopterPositionControl::MulticopterPositionControl() :
|
||||
SuperBlock(nullptr, "MPC"),
|
||||
ModuleParams(nullptr),
|
||||
@@ -320,27 +336,6 @@ MulticopterPositionControl::~MulticopterPositionControl()
|
||||
if (_wv_controller != nullptr) {
|
||||
delete _wv_controller;
|
||||
}
|
||||
|
||||
if (_control_task != -1) {
|
||||
// task wakes up every 100ms or so at the longest
|
||||
_task_should_exit = true;
|
||||
|
||||
// wait for a second for the task to quit at our request
|
||||
unsigned i = 0;
|
||||
|
||||
do {
|
||||
// wait 20ms
|
||||
usleep(20000);
|
||||
|
||||
// if we have given up, kill it
|
||||
if (++i > 50) {
|
||||
px4_task_delete(_control_task);
|
||||
break;
|
||||
}
|
||||
} while (_control_task != -1);
|
||||
}
|
||||
|
||||
pos_control::g_control = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -444,13 +439,6 @@ MulticopterPositionControl::poll_subscriptions()
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MulticopterPositionControl::task_main_trampoline(int argc, char *argv[])
|
||||
{
|
||||
pos_control::g_control->task_main();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
MulticopterPositionControl::limit_altitude(vehicle_local_position_setpoint_s &setpoint)
|
||||
{
|
||||
@@ -547,7 +535,7 @@ MulticopterPositionControl::set_vehicle_states(const float &vel_sp_z)
|
||||
}
|
||||
|
||||
void
|
||||
MulticopterPositionControl::task_main()
|
||||
MulticopterPositionControl::run()
|
||||
{
|
||||
// do subscriptions
|
||||
_vehicle_status_sub = orb_subscribe(ORB_ID(vehicle_status));
|
||||
@@ -577,18 +565,15 @@ MulticopterPositionControl::task_main()
|
||||
fds[0].fd = _local_pos_sub;
|
||||
fds[0].events = POLLIN;
|
||||
|
||||
while (!_task_should_exit) {
|
||||
while (!should_exit()) {
|
||||
// wait for up to 20ms for data
|
||||
int pret = px4_poll(&fds[0], (sizeof(fds) / sizeof(fds[0])), 20);
|
||||
|
||||
// timed out - periodic check for _task_should_exit
|
||||
if (pret == 0) {
|
||||
// Go through the loop anyway to copy manual input at 50 Hz.
|
||||
}
|
||||
// pret == 0: go through the loop anyway to copy manual input at 50 Hz.
|
||||
|
||||
// this is undesirable but not much we can do
|
||||
if (pret < 0) {
|
||||
warn("poll error %d, %d", pret, errno);
|
||||
PX4_ERR("poll error %d, %d", pret, errno);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -785,7 +770,6 @@ MulticopterPositionControl::task_main()
|
||||
}
|
||||
}
|
||||
|
||||
_control_task = -1;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1135,25 +1119,6 @@ MulticopterPositionControl::publish_local_pos_sp(const vehicle_local_position_se
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MulticopterPositionControl::start()
|
||||
{
|
||||
// start the task
|
||||
_control_task = px4_task_spawn_cmd("mc_pos_control",
|
||||
SCHED_DEFAULT,
|
||||
SCHED_PRIORITY_POSITION_CONTROL,
|
||||
1900,
|
||||
(px4_main_t)&MulticopterPositionControl::task_main_trampoline,
|
||||
nullptr);
|
||||
|
||||
if (_control_task < 0) {
|
||||
warn("task start failed");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void MulticopterPositionControl::check_failure(bool task_failure, uint8_t nav_state)
|
||||
{
|
||||
if (!task_failure) {
|
||||
@@ -1205,59 +1170,34 @@ void MulticopterPositionControl::send_vehicle_cmd_do(uint8_t nav_state)
|
||||
}
|
||||
}
|
||||
|
||||
int MulticopterPositionControl::task_spawn(int argc, char *argv[])
|
||||
{
|
||||
_task_id = px4_task_spawn_cmd("mc_pos_control",
|
||||
SCHED_DEFAULT,
|
||||
SCHED_PRIORITY_POSITION_CONTROL,
|
||||
1900,
|
||||
(px4_main_t)&run_trampoline,
|
||||
(char *const *)argv);
|
||||
|
||||
if (_task_id < 0) {
|
||||
_task_id = -1;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MulticopterPositionControl *MulticopterPositionControl::instantiate(int argc, char *argv[])
|
||||
{
|
||||
return new MulticopterPositionControl();
|
||||
}
|
||||
|
||||
int MulticopterPositionControl::custom_command(int argc, char *argv[])
|
||||
{
|
||||
return print_usage("unknown command");
|
||||
}
|
||||
|
||||
int mc_pos_control_main(int argc, char *argv[])
|
||||
{
|
||||
if (argc < 2) {
|
||||
warnx("usage: mc_pos_control {start|stop|status}");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "start")) {
|
||||
|
||||
if (pos_control::g_control != nullptr) {
|
||||
warnx("already running");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pos_control::g_control = new MulticopterPositionControl;
|
||||
|
||||
if (pos_control::g_control == nullptr) {
|
||||
warnx("alloc failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (OK != pos_control::g_control->start()) {
|
||||
delete pos_control::g_control;
|
||||
pos_control::g_control = nullptr;
|
||||
warnx("start failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "stop")) {
|
||||
if (pos_control::g_control == nullptr) {
|
||||
warnx("not running");
|
||||
return 1;
|
||||
}
|
||||
|
||||
delete pos_control::g_control;
|
||||
pos_control::g_control = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "status")) {
|
||||
if (pos_control::g_control) {
|
||||
warnx("running");
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
warnx("not running");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
warnx("unrecognized command");
|
||||
return 1;
|
||||
return MulticopterPositionControl::main(argc, argv);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user