35 add_class<MotorDriver, MotorDriver>(0),
38 add_class<TMC_1, MotorDriver>(1),
41 add_class<MotorPWM, MotorDriver>(4),
44 add_class<ODriveCAN1,MotorDriver>(5),
47 add_class<VESC_1,MotorDriver>(7),
50 add_class<MotorSimplemotion1,MotorDriver>(9),
53 add_class<RmdMotorCAN1,MotorDriver>(11),
62 add_class<MotorDriver, MotorDriver>(0),
65 add_class<TMC_2, MotorDriver>(2),
68 add_class<MotorPWM, MotorDriver>(4),
71 add_class<ODriveCAN2,MotorDriver>(6),
74 add_class<VESC_2,MotorDriver>(8),
77 add_class<RmdMotorCAN2,MotorDriver>(12),
97 ADR_AXIS1_ENDSTOP, ADR_AXIS1_POWER, ADR_AXIS1_DEGREES,ADR_AXIS1_EFFECTS1,ADR_AXIS1_EFFECTS2,ADR_AXIS1_ENC_RATIO,
98 ADR_AXIS1_SPEEDACCEL_FILTER,ADR_AXIS1_POSTPROCESS1});
100 else if (
axis ==
'Y')
105 ADR_AXIS2_ENDSTOP, ADR_AXIS2_POWER, ADR_AXIS2_DEGREES,ADR_AXIS2_EFFECTS1,ADR_AXIS2_EFFECTS2, ADR_AXIS2_ENC_RATIO,
106 ADR_AXIS2_SPEEDACCEL_FILTER,ADR_AXIS2_POSTPROCESS1});
108 else if (
axis ==
'Z')
112 ADR_AXIS3_ENDSTOP, ADR_AXIS3_POWER, ADR_AXIS3_DEGREES,ADR_AXIS3_EFFECTS1,ADR_AXIS3_EFFECTS2,ADR_AXIS3_ENC_RATIO,
113 ADR_AXIS3_SPEEDACCEL_FILTER,ADR_AXIS3_POSTPROCESS1});
193 uint16_t esval,
power;
229 uint16_t filterStorage;
232 uint8_t profile = filterStorage & 0xFF;
275 if(
drv->hasIntegratedEncoder()){
285 if(this->
drv !=
nullptr){
286 drv->getEncoder()->setPos(val);
295 return drv->getEncoder();
317 if(abs(scaledEnc) < 0x7fff){
328 if (abs(scaledEnc) > 0xffff &&
drv->motorReady()){
337 }
else if(abs(scaledEnc) <= 0x7fff) {
365 if (torqueChanged &&
drv->motorReady()){
367 drv->turn(totalTorque);
397 this->
drv.reset(
nullptr);
403 this->drv = std::unique_ptr<MotorDriver>(
drv);
433 drv->setExternalEncoderAllowed(
true);
458 if(
drv && !
drv->hasIntegratedEncoder())
459 this->
drv->setEncoder(this->
enc);
488 return std::make_pair<int32_t,float>(0x7fff,0.0);
491 int32_t val = (0xffff / (float)
degrees) * angle;
492 float val_f = (2.0 / (float)
degrees) * angle;
494 return std::make_pair(val,val_f);
521 drv->emergencyStop(reset);
578 if(valToSet == 0 && val != 0)
610 float speedRampupCeil = 4096;
611 float rampupFactor = 1.0;
612 if (fabs (speed) < speedRampupCeil) {
613 float phaseRad = M_PI * ((fabs (speed) / speedRampupCeil) - 0.5);
614 rampupFactor = ( 1 + sin(phaseRad ) ) / 2;
616 int8_t sign = speed >= 0 ? 1 : -1;
617 float force = (float)
frictionIntensity * rampupFactor * sign * INTERNAL_AXIS_FRICTION_SCALER * 32;
673 float torquef = (float)
torque / (
float)0x7fff;
675 return -powf(-torquef,
expo) * 0x7fff;
677 return powf(torquef,
expo) * 0x7fff;
701 int8_t clipdir = cliptest<int32_t,int32_t>(
metric.
current.
pos, -0x7fff, 0x7fff);
707 addtorque *= -clipdir;
709 return clip<int32_t,int32_t>(addtorque,-0x7fff,0x7fff);
740 float torqueSign =
torque > 0 ? 1 : -1;
754 torqueReduction = clip<float,int32_t>(torqueReduction,0,
torque);
756 torqueReduction = clip<float,int32_t>(-torqueReduction,
torque,0);
759 torque -= torqueReduction;
788 return (torqueChanged);
816 val =
clip(val, -127, 127);
824 expo = 1.0f/(1.0f+valF);
837 replies.emplace_back(this->
power);
944 int32_t
pos = this->
drv->getEncoder()->getPos();
1027 if(this->
drv->getEncoder() !=
nullptr){
1028 cpr = this->
drv->getEncoder()->getCpr();
1037 replies.emplace_back(
cpr);
float effect_margin_scaler
void errorCallback(const Error &error, bool cleared) override
const std::array< biquad_constant_t, 4 > filterAccelCst
float getEncAngle(Encoder *enc)
uint8_t idlespringstrength
AxisFlashAddrs flashAddrs
void startForceFadeIn(float start=0, float fadeTime=0.5)
void setEffectTorque(int32_t torque)
uint16_t nextDegreesOfRotation
Axis(char axis, volatile Control_t *control)
ClassChooser< MotorDriver > drv_chooser
uint8_t frictionIntensity
void setFxStrengthAndFilter(uint8_t val, uint8_t &valToSet, Biquad &filter)
int32_t updateIdleSpringForce()
void setDegrees(uint16_t degrees)
void calculateAxisEffects(bool ffb_on)
bool updateTorque(int32_t *totalTorque)
volatile Control_t * control
std::pair< int32_t, float > scaleEncValue(float angle, uint16_t degrees)
void setIdleSpringStrength(uint8_t spring)
uint16_t lastdegreesOfRotation
const Error outOfBoundsError
void setPower(uint16_t power)
MotorDriver * getDriver()
static const std::vector< class_entry< MotorDriver > > axis1_drivers
static const std::vector< class_entry< MotorDriver > > axis2_drivers
void updateMetrics(float new_pos)
static uint16_t encodeConfToInt(AxisConfig conf)
void resetMetrics(float new_pos)
CommandStatus command(const ParsedCommand &cmd, std::vector< CommandReply > &replies)
void setFxRatio(uint8_t val)
ClassChooser< Encoder > enc_chooser
static ClassIdentifier info
void setEncType(uint8_t enctype)
void setPos(uint16_t val)
int32_t calculateExpoTorque(int32_t torque)
std::shared_ptr< Encoder > enc
int32_t getLastScaledEnc()
void restoreFlash() override
std::unique_ptr< MotorDriver > drv
void setGearRatio(uint8_t numerator, uint8_t denominator)
uint16_t degreesOfRotation
void setDrvType(uint8_t drvtype)
void saveFlash() override
const ClassIdentifier getInfo()
Command handlers always have class infos. Works well with ChoosableClass.
void emergencyStop(bool reset)
const float AXIS_DAMPER_RATIO
static AxisConfig decodeConfFromInt(uint16_t val)
const std::array< biquad_constant_t, 4 > filterSpeedCst
const float AXIS_INERTIA_RATIO
void updateTorqueScaler()
void registerCommand(const char *cmd, const ID cmdid, const char *help=nullptr, uint32_t flags=0)
static CommandStatus handleGetSet(const ParsedCommand &cmd, std::vector< CommandReply > &replies, TVal &value)
void setInstance(uint8_t instance)
static CommandStatus handleGetSetFunc(const ParsedCommand &cmd, std::vector< CommandReply > &replies, TVal &value, void(cls1::*setfunc)(TVal), cls *obj)
static void addError(const Error &error)
virtual void setEncoder(std::shared_ptr< Encoder > &encoder)
virtual void startMotor()
virtual bool hasIntegratedEncoder()
bool Flash_Write(uint16_t adr, uint16_t dat)
bool Flash_Read(uint16_t adr, uint16_t *buf, bool checkempty=true)
uint16_t speedAccelFilter