217 lines
6.3 KiB
C++
217 lines
6.3 KiB
C++
//
|
|
// Created by xtkuang on 2025/7/30.
|
|
//
|
|
|
|
#ifndef CMVR_ES_ABSTRACT_MOTOR_H
|
|
#define CMVR_ES_ABSTRACT_MOTOR_H
|
|
|
|
#pragma once
|
|
|
|
#include "../abstract_device.h"
|
|
#include "common/base/logging/logger.h"
|
|
#include "motor/motor_protocol_interface.h"
|
|
#include <mutex>
|
|
|
|
namespace cmvr::device{
|
|
|
|
class AbstractMotor: public AbstractDevice {
|
|
|
|
typedef struct {
|
|
|
|
|
|
} MotorProfile;
|
|
|
|
struct MotorInfo {
|
|
int id;
|
|
std::string joint_name;
|
|
double limit_q_lb;
|
|
double limit_q_ub;
|
|
double limit_qd;
|
|
double limit_qdd;
|
|
};
|
|
|
|
typedef struct {
|
|
double position;
|
|
double velocity;
|
|
double acceleration;
|
|
double torque;
|
|
double temperature;
|
|
double voltage;
|
|
double current;
|
|
std::string error_msg;
|
|
} JointStatus;
|
|
|
|
public:
|
|
AbstractMotor() = default;
|
|
explicit AbstractMotor(uint8_t node_id): node_id_(node_id) {}
|
|
~AbstractMotor() override = default;
|
|
|
|
DeviceKind kind() const noexcept override { return DeviceKind::Motor; }
|
|
|
|
virtual void setMode(msgs::RunMode mode) {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return;
|
|
}
|
|
protocol_->setMode(node_id_, mode);
|
|
}
|
|
|
|
virtual msgs::RunMode getMode() {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return msgs::RUN_MODE_UNSPECIFIED;
|
|
}
|
|
return protocol_->getMode(node_id_);
|
|
}
|
|
|
|
void torqueOff() {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return;
|
|
}
|
|
protocol_->torqueOff(node_id_);
|
|
}
|
|
|
|
virtual void setLimitQ(double ub, double lb) {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return;
|
|
}
|
|
protocol_->setLimitQ(node_id_, ub,lb);
|
|
}
|
|
virtual void setLimitQd(double qd) {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return;
|
|
}
|
|
protocol_->setLimitQd(node_id_, qd);
|
|
}
|
|
virtual void setLimitQdd(double u_qdd,double l_qdd) {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return;
|
|
}
|
|
protocol_->setLimitQdd(node_id_, u_qdd,l_qdd);
|
|
}
|
|
// virtual void setLimitTau(double tau) = 0;
|
|
// virtual void setLimitCurrent(double tau) = 0;
|
|
virtual void brake() {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return;
|
|
}
|
|
protocol_->brake(node_id_);
|
|
}
|
|
/**
|
|
*
|
|
* @param q unit : rad
|
|
*/
|
|
virtual void setQ(double q) {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return;
|
|
}
|
|
protocol_->setQ(node_id_, q);
|
|
}
|
|
|
|
virtual void setTarget(double q,double qd) {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return;
|
|
}
|
|
protocol_->setTarget(node_id_,q, qd);
|
|
}
|
|
|
|
virtual void setTarget(double qd) {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return;
|
|
}
|
|
protocol_->setTarget(node_id_, qd);
|
|
}
|
|
|
|
virtual bool calibrateZeroQ() {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return false;
|
|
}
|
|
return protocol_->calibrateZeroQ(node_id_);
|
|
}
|
|
|
|
virtual bool reachedTargetQ() {
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return false;
|
|
}
|
|
return protocol_->reachedTargetQ(node_id_);
|
|
}
|
|
// rad /s
|
|
virtual void setQd(double qd) {
|
|
std::scoped_lock lock(mtx_);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return;
|
|
}
|
|
return protocol_->setQd(node_id_,qd);
|
|
}
|
|
// virtual void setQdd(double qdd) = 0; // rad /s^2
|
|
// virtual void setTau(double tau) = 0; // N m
|
|
// virtual void clear_err() = 0;
|
|
// virtual void getStatus() = 0;
|
|
// virtual MotorProfile getProfile() = 0;
|
|
|
|
virtual double getQ() {
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return 0.0;
|
|
}
|
|
return protocol_->getQ(node_id_);
|
|
}
|
|
|
|
virtual double getQd() {
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return 0.0;
|
|
}
|
|
return protocol_->getQd(node_id_);
|
|
}
|
|
|
|
|
|
// 使用的通讯协议
|
|
virtual void setProtocol(std::shared_ptr<MotorProtocolInterface> protocol) {
|
|
std::scoped_lock lock(mtx_);
|
|
protocol_ = std::move(protocol);
|
|
if (!protocol_) {
|
|
CMVR_LOG(ERROR) << "Protocol not set for motor";
|
|
return;
|
|
}
|
|
protocol_->initNode(node_id_);
|
|
}
|
|
|
|
uint8_t id() const {
|
|
return node_id_;
|
|
}
|
|
std::string jointName() const {
|
|
return info_.joint_name;
|
|
}
|
|
protected:
|
|
mutable std::mutex mtx_;
|
|
MotorInfo info_{};
|
|
uint8_t node_id_;
|
|
// 使用的通讯协议
|
|
std::shared_ptr<MotorProtocolInterface> protocol_;
|
|
};
|
|
}
|
|
#endif //CMVR_ES_ABSTRACT_MOTOR_H
|