98 ADR_AXIS1_ENDSTOP, ADR_AXIS1_POWER, ADR_AXIS1_DEGREES,ADR_AXIS1_EFFECTS1,ADR_AXIS1_EFFECTS2,ADR_AXIS1_ENC_RATIO,
99 ADR_AXIS1_SPEEDACCEL_FILTER,ADR_AXIS1_POSTPROCESS1});
101 else if (
axis ==
'Y')
106 ADR_AXIS2_ENDSTOP, ADR_AXIS2_POWER, ADR_AXIS2_DEGREES,ADR_AXIS2_EFFECTS1,ADR_AXIS2_EFFECTS2, ADR_AXIS2_ENC_RATIO,
107 ADR_AXIS2_SPEEDACCEL_FILTER,ADR_AXIS2_POSTPROCESS1});
109 else if (
axis ==
'Z')
113 ADR_AXIS3_ENDSTOP, ADR_AXIS3_POWER, ADR_AXIS3_DEGREES,ADR_AXIS3_EFFECTS1,ADR_AXIS3_EFFECTS2,ADR_AXIS3_ENC_RATIO,
114 ADR_AXIS3_SPEEDACCEL_FILTER,ADR_AXIS3_POSTPROCESS1});
194 uint16_t esval,
power;
230 uint16_t filterStorage;
233 uint8_t profile = filterStorage & 0xFF;
272 return (uint8_t)this->
conf.drvtype;
276 if(
drv->hasIntegratedEncoder()){
279 return (uint8_t)this->
conf.enctype;
287 if(enc_p !=
nullptr){
297 if(!
drv)
return nullptr;
298 return drv->getEncoder();
320 if(abs(scaledEnc) < 0x7fff){
331 if (abs(scaledEnc) > 0xffff &&
drv->motorReady()){
340 }
else if(abs(scaledEnc) <= 0x7fff) {
368 if (torqueChanged &&
drv->motorReady()){
370 drv->turn(totalTorque);
410 if(!this->
drv->hasIntegratedEncoder()){
411 this->
drv->setEncoder(this->
enc);
437 drv->setExternalEncoderAllowed(
true);
462 if(
drv && !
drv->hasIntegratedEncoder())
463 this->
drv->setEncoder(this->
enc);
465 this->
conf.enctype = 0;
480 this->
gearRatio.denominator = denominator;
482 this->
gearRatio.gearRatio = ((float)numerator+1.0)/((
float)denominator+1.0);
492 return std::make_pair<int32_t,float>(0x7fff,0.0);
495 int32_t val = (0xffff / (float)
degrees) * angle;
496 float val_f = (2.0 / (float)
degrees) * angle;
498 return std::make_pair(val,val_f);
525 drv->emergencyStop(reset);
559 return clip(
metric.current.pos,-0x7fff,0x7fff);
582 if(valToSet == 0 && val != 0)
613 float speed =
metric.current.speed * INTERNAL_SCALER_FRICTION;
614 float speedRampupCeil = 4096;
615 float rampupFactor = 1.0;
616 if (fabs (speed) < speedRampupCeil) {
617 float phaseRad = M_PI * ((fabs (speed) / speedRampupCeil) - 0.5);
618 rampupFactor = ( 1 + sin(phaseRad ) ) / 2;
620 int8_t sign = speed >= 0 ? 1 : -1;
621 float force = (float)
frictionIntensity * rampupFactor * sign * INTERNAL_AXIS_FRICTION_SCALER * 32;
640 metric.current.posDegrees = new_pos;
655 metric.current.posDegrees = new_pos;
660 float currentSpeed = (new_pos -
metric.previous.posDegrees) * 1000.0;
677 float torquef = (float)
torque / (
float)0x7fff;
679 return -powf(-torquef,
expo) * 0x7fff;
681 return powf(torquef,
expo) * 0x7fff;
711 addtorque *= -clipdir;
744 float torqueSign =
torque > 0 ? 1 : -1;
763 torque -= torqueReduction;
785 bool torqueChanged =
metric.current.torque !=
metric.previous.torque;
792 return (torqueChanged);
820 val =
clip(val, -127, 127);
828 expo = 1.0f/(1.0f+valF);
841 replies.emplace_back(this->
power);
978 replies.emplace_back(this->
metric.current.pos);
981 replies.emplace_back(this->
metric.current.torque);
984 replies.emplace_back(this->
metric.current.speed);
987 replies.emplace_back(this->
metric.current.accel);
1041 replies.emplace_back(
cpr);
1070 conf.enctype = ((val)&0x3f);
1071 conf.drvtype = ((val >> 6) & 0x3f);
1077 uint16_t val = (uint8_t)
conf.enctype & 0x3f;
1078 val |= ((uint8_t)
conf.drvtype & 0x3f) << 6;
constexpr class_entry< B > add_class(std::optional< uint16_t > selectionId=std::nullopt)
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)
CommandHandler(const char *clsname, uint16_t clsid, uint8_t instance=0)
virtual uint32_t getCpr()
virtual void setPos(int32_t pos)
static void addError(const Error &error)
int8_t cliptest(T v, C l, C h)
bool Flash_Write(uint16_t adr, uint16_t dat)
bool Flash_Read(uint16_t adr, uint16_t *buf, bool checkempty=true)