Skip to content

Conversation

@lthall
Copy link
Contributor

@lthall lthall commented Jan 4, 2026

This updates the existing Sqrt Controller used for the attitude command model with the new Real Time S-Curve algorithm.

This results in a jerk limited response on both leaving the current attitude and approaching the new set point.

Current problems are all related to lack of strict handling of command model parameters.

  • Heli can send zero acceleration with ff still on.
  • Plane sends a zero dt
  • Copter doesn't necessarily prevent these problems either.

I still have a little work to ensure the acceleration state is recorded correctly and converted to the correct frame before use.

I have separated the comment improvements here #31867

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@lthall lthall force-pushed the 20260104_NewCommandModel branch 4 times, most recently from 94ddcf4 to 7ee49bf Compare January 5, 2026 01:51
@lthall lthall requested a review from Copilot January 5, 2026 02:19
@lthall lthall force-pushed the 20260104_NewCommandModel branch from 3cd2f28 to b44d4e8 Compare January 5, 2026 02:25
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@lthall lthall force-pushed the 20260104_NewCommandModel branch from e04d231 to e383b0c Compare January 5, 2026 13:23
@lthall lthall force-pushed the 20260104_NewCommandModel branch 2 times, most recently from f2c8d40 to 717a136 Compare January 7, 2026 01:56
@lthall lthall requested review from peterbarker and rmackay9 January 7, 2026 01:59
@lthall lthall force-pushed the 20260104_NewCommandModel branch 5 times, most recently from 498a9d8 to ca431d8 Compare January 25, 2026 03:02
_ang_vel_target_rads.z = input_shaping_angle(wrap_PI(attitude_error_angle.z), _input_tc, get_accel_yaw_max_radss(), _ang_vel_target_rads.z, ang_vel_target.z, radians(_ang_vel_yaw_max_degs), _dt_s);
attitude_command_model(wrap_PI(attitude_error_angle.x), 0.0, _ang_vel_target_rads.x, _ang_accel_target_rads.x, radians(_ang_vel_roll_max_degs), get_accel_roll_max_radss(), _input_tc, _dt_s);
attitude_command_model(wrap_PI(attitude_error_angle.y), 0.0, _ang_vel_target_rads.y, _ang_accel_target_rads.y, radians(_ang_vel_pitch_max_degs), get_accel_pitch_max_radss(), _input_tc, _dt_s);
attitude_command_model(wrap_PI(attitude_error_angle.z), 0.0, _ang_vel_target_rads.z, _ang_accel_target_rads.z, radians(_ang_vel_yaw_max_degs), get_accel_yaw_max_radss(), _rate_y_tc, _dt_s);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently yaw uses _input_tc this changes it to _rate_y_tc

ang_vel_to_euler_rate(_attitude_target, _ang_accel_target_rads, euler_accel_target_rads);
attitude_command_model(wrap_PI(euler_roll_angle_rad - _euler_angle_target_rad.x), 0.0, _euler_rate_target_rads.x, euler_accel_target_rads.x, fabsf(euler_rate_max_rads.x), euler_accel.x, _input_tc, _dt_s);
attitude_command_model(wrap_PI(euler_pitch_angle_rad - _euler_angle_target_rad.y), 0.0, _euler_rate_target_rads.y, euler_accel_target_rads.y, fabsf(euler_rate_max_rads.y), euler_accel.y, _input_tc, _dt_s);
float yaw_rate_max_rads = euler_rate_max_rads.z;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
float yaw_rate_max_rads = euler_rate_max_rads.z;
float yaw_rate_max_rads = fabsf(euler_rate_max_rads.z);

ABS needs to be done here for the slew yaw min to make sense.

// translate the roll pitch and yaw acceleration limits to the euler axis
// translate the roll pitch and yaw rate and acceleration limits to the euler axis
const Vector3f euler_accel = euler_accel_limit(_attitude_target, Vector3f{get_accel_roll_max_radss(), get_accel_pitch_max_radss(), get_accel_yaw_max_radss()});
const Vector3f euler_rate_max_rads = euler_accel_limit(_attitude_target, Vector3f{radians(_ang_vel_roll_max_degs), radians(_ang_vel_pitch_max_degs), radians(_ang_vel_yaw_max_degs)});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the slew yaw limit should be done before the conversion to euler axis?

_euler_rate_target_rads.z = constrain_float(_euler_rate_target_rads.z, -slew_yaw_max_rads, slew_yaw_max_rads);
yaw_rate_max_rads = MIN(yaw_rate_max_rads, slew_yaw_max_rads);
}
attitude_command_model(wrap_PI(euler_yaw_angle_rad - _euler_angle_target_rad.z), 0.0, _euler_rate_target_rads.z, euler_accel_target_rads.z, fabsf(yaw_rate_max_rads), euler_accel.z, _input_tc, _dt_s);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
attitude_command_model(wrap_PI(euler_yaw_angle_rad - _euler_angle_target_rad.z), 0.0, _euler_rate_target_rads.z, euler_accel_target_rads.z, fabsf(yaw_rate_max_rads), euler_accel.z, _input_tc, _dt_s);
attitude_command_model(wrap_PI(euler_yaw_angle_rad - _euler_angle_target_rad.z), 0.0, _euler_rate_target_rads.z, euler_accel_target_rads.z, yaw_rate_max_rads, euler_accel.z, _input_tc, _dt_s);

ang_vel_limit(_ang_vel_target_rads, radians(_ang_vel_roll_max_degs), radians(_ang_vel_pitch_max_degs), slew_yaw_max_rads);
attitude_command_model(attitude_error.x, 0.0, _ang_vel_target_rads.x, _ang_accel_target_rads.x, radians(_ang_vel_roll_max_degs), get_accel_roll_max_radss(), _input_tc, _dt_s);
attitude_command_model(attitude_error.y, 0.0, _ang_vel_target_rads.y, _ang_accel_target_rads.y, radians(_ang_vel_pitch_max_degs), get_accel_pitch_max_radss(), _input_tc, _dt_s);
attitude_command_model(attitude_error.z, heading_rate_rads, _ang_vel_target_rads.z, _ang_accel_target_rads.z, radians(_ang_vel_yaw_max_degs), get_accel_yaw_max_radss(), _rate_y_tc, _dt_s);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is currently _input_tc

@lthall lthall force-pushed the 20260104_NewCommandModel branch from ca431d8 to ddad33e Compare January 25, 2026 22:58
@lthall lthall force-pushed the 20260104_NewCommandModel branch from ddad33e to f53f7e2 Compare January 27, 2026 00:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants