创建命令
以speed_control为例,编写一个命令来控制速度的目标值。
注释下面代码,即之前写死的speed_setpoint删掉,以便我们在命令行中控制
/* 获取控制命令 暂时写死*/
speed_ctrl->speed_setpoint_ = 0.15f;
创建命令函数
mod_speed_control.hpp
在类内声明函数
注意一定要声明为静态,第一个参数为当前类的指针
static void SetSpeed(SpeedControl* ctrl, int argc, char* argv[]);
创建命令对象
使用当前类指针实例化一个命令模板,并作为SpeedControl的成员。
System::Term::Command<SpeedControl*> cmd_;
初始化命令
在SpeedControl的初始化列表里加入cmd_的初始化,即把SetSpeed函数映射到/dev/speed_control
cmd_(this, this->SetSpeed, "speed_control", System::Term::DevDir())
解析逻辑
argc为命令参数个数,argv为参数的字符串数组,第一个参数为命令名。
void SpeedControl::SetSpeed(SpeedControl* ctrl, int argc, char* argv[]) {
/* 参数应当为一个 */
if (argc != 2) {
ms_printf("参数错误");
return;
}
/* 获取参数并转为float */
float speed_setpoint = std::stof(argv[1]);
/* 写入目标速度 */
ctrl->speed_setpoint_ = speed_setpoint;
return;
}
运行
运行之后在命令行输入/dev/speed_control 0.2
尝试更改速度,再使用/dev/motor show 1000 10
查看电机反馈
示例代码
mod_speed_control.cpp
#include "mod_speed_control.hpp"
using namespace Module;
#define MOTOR_MAX_ROTATIONAL_SPEED (7000.0f)
SpeedControl::SpeedControl(Param& param)
: param_(param),
pid_(param.pid, 500),
motor_(param.motor, "motor"),
cmd_(this, this->SetSpeed, "speed_control", System::Term::DevDir()) {
/* 使用lambda创建控制线程函数 */
auto ctrl_thread = [](SpeedControl* speed_ctrl) {
while (1) {
/* 更新反馈 */
speed_ctrl->UpdateFeedback();
/* 控制电机 */
speed_ctrl->Control();
/* 等待下一次控制 */
speed_ctrl->thread_.SleepUntil(2);
}
};
/* 创建线程 */
this->thread_.Create(ctrl_thread, this, "speed_control", 384,
System::Thread::MEDIUM);
}
void SpeedControl::UpdateFeedback() { this->motor_.Update(); }
void SpeedControl::Control() {
/* 更新时间 */
this->now_ = bsp_time_get();
this->dt_ = this->now_ - this->lask_wakeup_;
this->lask_wakeup_ = this->now_;
/* 计算PID */
this->output_ = this->pid_.Calculate(
this->speed_setpoint_,
this->motor_.GetSpeed() / MOTOR_MAX_ROTATIONAL_SPEED, this->dt_);
/* 电机输出 */
this->motor_.Control(this->output_);
}
void SpeedControl::SetSpeed(SpeedControl* ctrl, int argc, char* argv[]) {
if (argc != 2) {
ms_printf("参数错误");
return;
}
float speed_setpoint = std::stof(argv[1]);
ctrl->speed_setpoint_ = speed_setpoint;
return;
}
mod_speed_control.hpp
#inclued <module.hpp>
#include "comp_pid.hpp"
#include "dev_rm_motor.hpp"
namespace Module {
class SpeedControl {
public:
typedef struct {
Component::PID::Param pid;
Device::RMMotor::Param motor;
} Param;
/* 构造函数 */
SpeedControl(Param& param);
/* 控制函数 */
void Control();
/* 更新电机反馈 */
void UpdateFeedback();
/* 设置目标速度 */
static void SetSpeed(SpeedControl* ctrl, int argc, char* argv[]);
private:
Param param_; /* 配置参数 */
float now_; /* 当前时间 */
float dt_; /* 距离上次控制的时间 */
float lask_wakeup_; /* 上次控制的时间 */
float speed_setpoint_; /* 速度目标值 */
float output_; /* 电机输出 */
Component::PID pid_; /* pid对象 */
Device::RMMotor motor_; /* motor对象 */
System::Thread thread_; /* 控制线程 */
System::Term::Command<SpeedControl*> cmd_;
};
} // namespace Module