Skip to content

File syn_motor_ctrl.c

FileList > motor > syn_motor_ctrl.c

Go to the source code of this file

Closed-loop motor controller implementation. More...

  • #include "../util/syn_assert.h"
  • #include "syn_motor_ctrl.h"
  • #include "../system/syn_errlog.h"
  • #include <string.h>
  • #include "../util/syn_qmath.h"

Public Functions

Type Name
void syn_motor_ctrl_clear_stall (SYN_MotorCtrl * ctrl)
Clear a stall condition and return to idle.
void syn_motor_ctrl_estop (SYN_MotorCtrl * ctrl)
Emergency stop — immediate brake/coast.
SYN_Status syn_motor_ctrl_init (SYN_MotorCtrl * ctrl, const SYN_MotorCtrl_Config * cfg)
Initialize the closed-loop controller.
void syn_motor_ctrl_move_to (SYN_MotorCtrl * ctrl, int32_t target, int32_t max_velocity, int32_t acceleration)
Move to position with a built-in trapezoidal velocity profile.
void syn_motor_ctrl_move_to_scurve (SYN_MotorCtrl * ctrl, int32_t target, int32_t max_velocity, int32_t max_accel, int32_t max_jerk)
Move to position with a built-in jerk-limited S-curve profile.
void syn_motor_ctrl_on_stall (SYN_MotorCtrl * ctrl, SYN_MotorCtrl_StallCallback cb, void * ctx)
Register stall callback.
void syn_motor_ctrl_on_target (SYN_MotorCtrl * ctrl, SYN_MotorCtrl_TargetCallback cb, void * ctx)
Register on-target callback (position mode).
void syn_motor_ctrl_reset_metrics (SYN_MotorCtrl * ctrl)
Reset move metrics. Call before starting a move you want to measure.
int32_t syn_motor_ctrl_rms_error (const SYN_MotorCtrl * ctrl)
Compute RMS tracking error from accumulated metrics.
void syn_motor_ctrl_set_datalog (SYN_MotorCtrl * ctrl, SYN_DataLog * log)
Attach a datalog for tuning capture.
void syn_motor_ctrl_set_ff_gains (SYN_MotorCtrl * ctrl, int32_t ff_kv, int32_t ff_ka)
Update feedforward gains at runtime.
void syn_motor_ctrl_set_gains (SYN_MotorCtrl * ctrl, int32_t kp, int32_t ki, int32_t kd)
Update PID gains at runtime.
void syn_motor_ctrl_set_output (SYN_MotorCtrl * ctrl, int32_t output)
Drive the motor at a fixed output level (open-loop).
void syn_motor_ctrl_set_position (SYN_MotorCtrl * ctrl, int32_t target)
Set position target (absolute feedback units).
void syn_motor_ctrl_set_trajectory (SYN_MotorCtrl * ctrl, const SYN_MotorCtrl_Trajectory * traj)
Feed a trajectory point for feedforward + PID tracking.
void syn_motor_ctrl_set_velocity (SYN_MotorCtrl * ctrl, int32_t units_per_sec)
Set velocity target (units/second).
void syn_motor_ctrl_stop (SYN_MotorCtrl * ctrl)
Stop the motor and enter idle mode.
SYN_MotorCtrl_State syn_motor_ctrl_update (SYN_MotorCtrl * ctrl)
Run the control loop. Call at cfg.update_hz rate.

Public Static Functions

Type Name
void apply_output (SYN_MotorCtrl * ctrl, int32_t output)
Drive the motor at the given output level via the vtable.
bool at_limit (const SYN_MotorCtrl * ctrl, int32_t pos, int32_t output)
Check if position is at a soft limit in the given direction.
void brake_motor (SYN_MotorCtrl * ctrl)
Active-brake the motor.
bool limits_enabled (const SYN_MotorCtrl * ctrl)
Check if soft position limits are configured.
int32_t read_position (SYN_MotorCtrl * ctrl)
Read the current position from the encoder/sensor.
void stop_motor (SYN_MotorCtrl * ctrl)
Coast/stop the motor (no active braking).

Macros

Type Name
define SYN_MCTRL_ERR_LIMIT 0x0101
define SYN_MCTRL_ERR_STALL 0x0100

Detailed Description

Control loop: * Read feedback via read_pos() function pointer * Compute velocity = delta × update_hz * Compute PID error (velocity or position mode) * Enforce soft position limits * Apply PID output to motor via SYN_MotorOutput interface * Check stall condition

Public Functions Documentation

function syn_motor_ctrl_clear_stall

Clear a stall condition and return to idle.

void syn_motor_ctrl_clear_stall (
    SYN_MotorCtrl * ctrl
) 

After a stall, the controller locks in STALLED state until this is called.

Parameters:

  • ctrl Controller instance.

function syn_motor_ctrl_estop

Emergency stop — immediate brake/coast.

void syn_motor_ctrl_estop (
    SYN_MotorCtrl * ctrl
) 

Parameters:

  • ctrl Controller instance.

function syn_motor_ctrl_init

Initialize the closed-loop controller.

SYN_Status syn_motor_ctrl_init (
    SYN_MotorCtrl * ctrl,
    const SYN_MotorCtrl_Config * cfg
) 

Parameters:

  • ctrl Controller instance to initialize.
  • cfg Configuration (copied internally).

Returns:

SYN_OK on success.


function syn_motor_ctrl_move_to

Move to position with a built-in trapezoidal velocity profile.

void syn_motor_ctrl_move_to (
    SYN_MotorCtrl * ctrl,
    int32_t target,
    int32_t max_velocity,
    int32_t acceleration
) 

This is the "batteries included" path — no external profile generator needed. The controller internally generates a trapezoidal ramp (accelerate → cruise → decelerate) and feeds it through the normal trajectory/feedforward path each update() call.

Equivalent to manually calling syn_ramp_set_target_trapezoid() and feeding the output into set_trajectory() each tick, but with zero user-side wiring.

Parameters:

  • ctrl Controller instance.
  • target Target position in feedback units.
  • max_velocity Maximum velocity (units/second).
  • acceleration Acceleration (units/second²).

function syn_motor_ctrl_move_to_scurve

Move to position with a built-in jerk-limited S-curve profile.

void syn_motor_ctrl_move_to_scurve (
    SYN_MotorCtrl * ctrl,
    int32_t target,
    int32_t max_velocity,
    int32_t max_accel,
    int32_t max_jerk
) 

Like move_to(), but uses a 7-phase S-curve trajectory that bounds jerk for the smoothest possible motion. The S-curve natively provides position, velocity, and acceleration — all three are fed into the trajectory/feedforward path.

All kinematic limits are in per-second units: * max_velocity: units/second * max_accel: units/second² * max_jerk: units/second³

Parameters:

  • ctrl Controller instance.
  • target Target position in feedback units.
  • max_velocity Maximum velocity (units/second).
  • max_accel Maximum acceleration (units/second²).
  • max_jerk Maximum jerk (units/second³).

function syn_motor_ctrl_on_stall

Register stall callback.

void syn_motor_ctrl_on_stall (
    SYN_MotorCtrl * ctrl,
    SYN_MotorCtrl_StallCallback cb,
    void * ctx
) 

Parameters:

  • ctrl Controller instance.
  • cb Callback function, or NULL to unregister.
  • ctx User context passed to callback.

function syn_motor_ctrl_on_target

Register on-target callback (position mode).

void syn_motor_ctrl_on_target (
    SYN_MotorCtrl * ctrl,
    SYN_MotorCtrl_TargetCallback cb,
    void * ctx
) 

Parameters:

  • ctrl Controller instance.
  • cb Callback function, or NULL to unregister.
  • ctx User context passed to callback.

function syn_motor_ctrl_reset_metrics

Reset move metrics. Call before starting a move you want to measure.

void syn_motor_ctrl_reset_metrics (
    SYN_MotorCtrl * ctrl
) 

Parameters:

  • ctrl Controller instance.

function syn_motor_ctrl_rms_error

Compute RMS tracking error from accumulated metrics.

int32_t syn_motor_ctrl_rms_error (
    const SYN_MotorCtrl * ctrl
) 

Returns the integer square root of (error_sq_sum / sample_count). Only valid if sample_count > 0.

Parameters:

  • ctrl Controller instance.

Returns:

RMS tracking error in feedback units.


function syn_motor_ctrl_set_datalog

Attach a datalog for tuning capture.

void syn_motor_ctrl_set_datalog (
    SYN_MotorCtrl * ctrl,
    SYN_DataLog * log
) 

When attached, every update() writes a SYN_MotorCtrl_Sample frame to the datalog at full control-loop rate.

Parameters:

  • ctrl Controller.
  • log Datalog instance (caller-owned), or NULL to detach.

function syn_motor_ctrl_set_ff_gains

Update feedforward gains at runtime.

void syn_motor_ctrl_set_ff_gains (
    SYN_MotorCtrl * ctrl,
    int32_t ff_kv,
    int32_t ff_ka
) 

Parameters:

  • ctrl Controller instance.
  • ff_kv Velocity feedforward gain (÷ 1 << ff_scale).
  • ff_ka Acceleration feedforward gain (÷ 1 << ff_scale).

function syn_motor_ctrl_set_gains

Update PID gains at runtime.

void syn_motor_ctrl_set_gains (
    SYN_MotorCtrl * ctrl,
    int32_t kp,
    int32_t ki,
    int32_t kd
) 

Parameters:

  • ctrl Controller instance.
  • kp Proportional gain (÷ 1 << pid_scale).
  • ki Integral gain (÷ 1 << pid_scale).
  • kd Derivative gain (÷ 1 << pid_scale).

function syn_motor_ctrl_set_output

Drive the motor at a fixed output level (open-loop).

void syn_motor_ctrl_set_output (
    SYN_MotorCtrl * ctrl,
    int32_t output
) 

Bypasses PID — the output value is passed directly to the motor. Useful for manual jogging, testing motor wiring, or when simple open-loop control is sufficient. Position feedback is still read (for soft limits and stall detection) but not used for control.

Parameters:

  • ctrl Controller instance.
  • output Output level (clamped to [output_min, output_max]).

function syn_motor_ctrl_set_position

Set position target (absolute feedback units).

void syn_motor_ctrl_set_position (
    SYN_MotorCtrl * ctrl,
    int32_t target
) 

Switches to position mode. Controller drives toward target and enters ON_TARGET state when within deadband.

Parameters:

  • ctrl Controller instance.
  • target Absolute position in feedback units.

function syn_motor_ctrl_set_trajectory

Feed a trajectory point for feedforward + PID tracking.

void syn_motor_ctrl_set_trajectory (
    SYN_MotorCtrl * ctrl,
    const SYN_MotorCtrl_Trajectory * traj
) 

Call this each update with the current output of your trajectory generator (syn_ramp, syn_scurve, or application code). The controller uses PID on position error plus feedforward from the trajectory's velocity and acceleration.

Parameters:

  • ctrl Controller instance.
  • traj Trajectory point (position, velocity, acceleration).

function syn_motor_ctrl_set_velocity

Set velocity target (units/second).

void syn_motor_ctrl_set_velocity (
    SYN_MotorCtrl * ctrl,
    int32_t units_per_sec
) 

Switches to velocity mode. Positive = forward, negative = reverse.

Parameters:

  • ctrl Controller instance.
  • units_per_sec Target velocity in feedback units per second.

function syn_motor_ctrl_stop

Stop the motor and enter idle mode.

void syn_motor_ctrl_stop (
    SYN_MotorCtrl * ctrl
) 

Parameters:

  • ctrl Controller instance.

function syn_motor_ctrl_update

Run the control loop. Call at cfg.update_hz rate.

SYN_MotorCtrl_State syn_motor_ctrl_update (
    SYN_MotorCtrl * ctrl
) 

Reads feedback, computes PID, drives motor output. If a datalog is attached, writes a SYN_MotorCtrl_Sample each call.

Parameters:

  • ctrl Controller instance.

Returns:

Current controller state.


Public Static Functions Documentation

function apply_output

Drive the motor at the given output level via the vtable.

static void apply_output (
    SYN_MotorCtrl * ctrl,
    int32_t output
) 

Parameters:

  • ctrl Motor controller.
  • output Signed output value.

function at_limit

Check if position is at a soft limit in the given direction.

static bool at_limit (
    const SYN_MotorCtrl * ctrl,
    int32_t pos,
    int32_t output
) 

Parameters:

  • ctrl Motor controller.
  • pos Current position.
  • output Intended output (sign indicates direction).

Returns:

true if movement would exceed a limit.


function brake_motor

Active-brake the motor.

static void brake_motor (
    SYN_MotorCtrl * ctrl
) 

Parameters:

  • ctrl Motor controller.

function limits_enabled

Check if soft position limits are configured.

static bool limits_enabled (
    const SYN_MotorCtrl * ctrl
) 

Parameters:

  • ctrl Motor controller.

Returns:

true if limits are set.


function read_position

Read the current position from the encoder/sensor.

static int32_t read_position (
    SYN_MotorCtrl * ctrl
) 

Parameters:

  • ctrl Motor controller.

Returns:

Current position.


function stop_motor

Coast/stop the motor (no active braking).

static void stop_motor (
    SYN_MotorCtrl * ctrl
) 

Parameters:

  • ctrl Motor controller.

Macro Definition Documentation

define SYN_MCTRL_ERR_LIMIT

#define SYN_MCTRL_ERR_LIMIT `0x0101`

Soft position limit hit.


define SYN_MCTRL_ERR_STALL

#define SYN_MCTRL_ERR_STALL `0x0100`

Stall condition detected.



The documentation for this class was generated from the following file src/syntropic/motor/syn_motor_ctrl.c