9namespace roboctrl::utils::kinematics {
22 .left_front = velocity.x - velocity.y - rotate_speed,
23 .right_front = velocity.x + velocity.y + rotate_speed,
24 .left_rear = velocity.x + velocity.y - rotate_speed,
25 .right_rear = velocity.x - velocity.y + rotate_speed};
26 const fp32 peak = std::max({std::fabs(result.left_front), std::fabs(result.right_front),
27 std::fabs(result.left_rear), std::fabs(result.right_rear)});
28 if (peak > max_wheel_speed && peak > 0.0f) {
29 const fp32 scale = max_wheel_speed / peak;
30 result.left_front *= scale; result.right_front *= scale;
31 result.left_rear *= scale; result.right_rear *= scale;
37inline std::array<fp32, 4> mecanum_motor_targets(
38 vectorf velocity, fp32 rotate_speed, fp32 max_wheel_speed,
39 const std::array<int, 4>& directions)
41 if (!std::isfinite(velocity.x) || !std::isfinite(velocity.y) ||
42 !std::isfinite(rotate_speed) || !std::isfinite(max_wheel_speed) || max_wheel_speed <= 0.0f ||
43 !std::all_of(directions.begin(), directions.end(), [](
int value) { return value == -1 || value == 1; }))
45 const auto wheels = inverse_mecanum(velocity, rotate_speed, max_wheel_speed);
46 return {wheels.left_front * directions[0], wheels.right_front * directions[1],
47 wheels.left_rear * directions[2], wheels.right_rear * directions[3]};