Skip to content

Releases: EZ-Robotics/EZ-Template

🐛v3.2.1🍠edamame

17 Dec 23:54
8e08987
Compare
Choose a tag to compare

Minor bug fix, swings will now work as expected when the autonomous routine is mirrored.

‼️ODOMETRY‼️
🎡TRACKING WHEELS🎡
🚗ODOM DRIVE SYNTAX🚗
🐷PURE PURSUIT🐷
🪀BOOMERANG🪀
🪀🐷BOOMERANG INJECTED INTO PURE PURSUITS🪀🐷
👉TURN TO POINT👉
💄MIRRORED AUTONS💄
🩰TURN BEHAVIOR🩰
🛹GLOBAL SLEW🛹
📺BLANK LCD PAGES📺

Download and Installation

Learn how to install and setup EZ-Template here!

Discord Server

Need extra assistance using EZ-Template? Feel free to join our Discord Server!

What's Changed

Full Changelog: v3.2.0...v3.2.1

v3.2.0 ‼️ODOMETRY‼️

17 Dec 05:59
bf917d3
Compare
Choose a tag to compare

🥳🥳🥳EZ-TEMPLATE'S LARGEST FEATURE UPGRADE🥳🥳🥳

‼️ODOMETRY‼️
🎡TRACKING WHEELS🎡
🚗ODOM DRIVE SYNTAX🚗
🐷PURE PURSUIT🐷
🪀BOOMERANG🪀
🪀🐷BOOMERANG INJECTED INTO PURE PURSUITS🪀🐷
👉TURN TO POINT👉
💄MIRRORED AUTONS💄
🩰TURN BEHAVIOR🩰
🛹GLOBAL SLEW🛹
📺BLANK LCD PAGES📺

Download and Installation

Learn how to install and setup EZ-Template here!

Discord Server

Need extra assistance using EZ-Template? Feel free to join our Discord Server!

What's Changed

New Contributors

  • @jemminiz made their first contribution in #183
  • @aayala04 was the cause of beta.4, beta.5, beta.6, beta.7, beta.8, and rc.1. Too good at finding bugs
  • Thank you @8pxl for the original measuring offsets function!

Full Changelog: v3.1.0...v3.2.0

v3.2.0-rc.2

15 Dec 20:42
Compare
Choose a tag to compare
v3.2.0-rc.2 Pre-release
Pre-release

Very minor update. Example project now contains a screen task and has been simplified further, general documentation clean up, and a bug fix for relative odom when x or y axis is flipped.

Full 3.2.0 will be released very shortly

What's Changed

Full Changelog: v3.2.0-rc.1...v3.2.0-rc.2


🎉ODOMETRY🎉

EZ-Template has odometry!! The easiest way to start messing with this is to start messing with it by downloading the example project below! You can also see the example project here.

🎡Tracking Wheels

You can create tracking wheels with EZ-Template using ADI Encoders (or 3rd party digital encoders) and rotation sensors.

// Are you using tracking wheels?  Comment out which ones you're using here!
//  `2.75` is the wheel diameter
//  `4.0` is the distance from the center of the wheel to the center of the robot
ez::tracking_wheel right_tracker({-'A', -'B'}, 2.75, 4.0);  // ADI Encoders
ez::tracking_wheel left_tracker(1, {'C', 'D'}, 2.75, 4.0);  // ADI Encoders plugged into a Smart port
ez::tracking_wheel horiz_tracker(1, 2.75, 4.0);             // Rotation sensors

To enable them, you'll need these lines of code in void initialize()

// Are you using tracking wheels?  Comment out which ones you're using here!
chassis.odom_tracker_right_set(&right_tracker);
chassis.odom_tracker_left_set(&left_tracker);
chassis.odom_tracker_back_set(&horiz_tracker);  // Replace `back` to `front` if your tracker is in the front!

🚗Odom Drive Syntax

If you have previous actions that you're porting over to 3.2.0 but you're not quite ready to retune odom stuff, you can try replacing .pid_drive_set with .pid_odom_set and it'll make your normal autons use odometry.

void drive_and_turn() {
  chassis.pid_odom_set(24_in, DRIVE_SPEED, true);
  chassis.pid_wait();

  chassis.pid_turn_set(45_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_turn_set(-45_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_turn_set(0_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_odom_set(-24_in, DRIVE_SPEED, true);
  chassis.pid_wait();
}

🐷Pure Pursuit

EZ-Template's Pure Pursuit is all done on the robot. chassis.pid_odom_set() will be your main function and covers all aspects of odom. You can input as many points as you'd like here and the robot will path through all of them.

// Drive to 0, 30 and pass through 6, 10 and 0, 20 on the way, with slew
chassis.pid_odom_set({{{6_in, 10_in}, fwd, 110},
                      {{0_in, 20_in}, fwd, 110},
                      {{0_in, 30_in}, fwd, 110}},
                     true);
chassis.pid_wait();

You can combine going forward and reverse in the same motion

chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                      {{24_in, 24_in}, rev, 110}},
                     true);
chassis.pid_wait();

And you can pid_wait_until a point has been reached

chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                      {{12_in, 24_in}, rev, 110},
                      {{24_in, 24_in}, rev, 110}},
                     true);
chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
Intake.move(127);
chassis.pid_wait();

🪀Boomerang

Boomerang will try to go to a point at a specific angle. You use this by specifying an angle while using pid_odom_set()

chassis.pid_odom_set({{0_in, 24_in, 45_deg}, fwd, 110},
                     true);
chassis.pid_wait();

🪀🐷Boomerang Injected into Pure Pursuits

Any point that the robot goes to, if you specify the angle it'll become a boomerang motion, even if it's during a pure pursuit path!

chassis.pid_odom_set({{{0_in, 24_in, 45_deg}, fwd, 110},
                      {{12_in, 24_in}, fwd, 110},
                      {{24_in, 24_in}, fwd, 110}},
                     true);
chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
Intake.move(127);
chassis.pid_wait();

👉Turn to Point

You can turn to face a point! All of the syntax for normal turning applies here, so you can do this:

chassis.pid_turn_set({12_in, 12_in}, fwd, 110, ez::longest, true);

Or you can keep it simple and do this

chassis.pid_turn_set({12_in, 12_in}, fwd, 110);

💄Mirrored Field Problem

To help with making unique autons for the left and right side of the field, EZ-Template 3.2.0 has a feature to flip what direction the X and Y axis face. By flipping these you're allowing 1 autonomous routine to work for red and blue.

odom_y_flip();
odom_x_flip();
odom_theta_flip();
odom_y_direction_get();  // True = down is positive Y, False = up is positive Y
odom_x_direction_get();  // True = left is positive X, False = right is positive X
odom_theta_direction_get(); // True = positive is counterclockwise, False = positive is counterclockwise

It is still suggested to make minor tweaks for both sides, nothing is perfect, but it'll be much easier to maintain with one base function.

void base() {
  ez::united_pose start_intaking_here;

  if (chassis.odom_x_direction_get() == false)
    start_intaking_here = {12_in, 24_in};  // If red
  else
    start_intaking_here = {15_in, 24_in};  // If blue

  chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                        {start_intaking_here, rev, 110},
                        {{24_in, 24_in}, rev, 110}},
                       true);
  chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
  Intake.move(127);
  chassis.pid_wait();

  chassis.pid_odom_set({{24_in, 48_in, 45_deg}, fwd, 110},
                       true);
  chassis.pid_wait();

  chassis.pid_turn_set(90_deg, 110, true);
  chassis.pid_wait();
}

void red() {
  base();
}

void blue() {
  chassis.odom_x_flip();
  chassis.odom_theta_flip();
  base();
}

🩰Turn Behavior

In every previous version of EZ-Template, turning used the raw IMU values. This was confusing to teams as turning to 360 and 0 were the same angle but would do different things. In 3.2.0 you can change the default behavior of turning for turns, swings, and odoms. You can choose between:
ez::raw - this is the behavior prior to 3.2.0
ez::left_turn / ez::ccw - this will always turn counterclockwise
ez::right_turn / ez::cw - this will always turn clockwise
ez::longest - this will always take the longest path there, capped at 360deg
ez::shortest - this will always take the shortest path there

You can call these in default_constants() in src/autons.cpp to change what the default behavior is. The 3.2.0 example project has it as ez::shortest.

pid_turn_behavior_set(ez::shortest);
pid_swing_behavior_set(ez::shortest);
pid_odom_behavior_set(ez::shortest);

Now you can change how the robot behaves in turns

void turn() {
  chassis.pid_turn_behavior_set(ez::shortest);

  chassis.pid_turn_set(90_deg, TURN_SPEED, ez::left_turn);
  chassis.pid_wait();

  chassis.pid_turn_set(45_deg, TURN_SPEED, ez::right_turn);
  chassis.pid_wait();

  chassis.pid_turn_set(0_deg, TURN_SPEED, ez::longest);
  chassis.pid_wait();

  // This will take the shortest route because that's the default behavior
  chassis.pid_turn_set(359_deg, TURN_SPEED);
  chassis.pid_wait();
}

🛹Global Slew

If you're tired of having true at the end of all of your motions, you can now globally enable slew for each motion type! You can override the default in each motion, but it won't change the default unless you explicitly change it.

slew_drive_set(true)
slew_swing_set(true)
slew_turn_set

🎸Adding PIDs to PID Tuner

ez::PID liftPID{0.45};

Adding this line of code to initialize() will add your PID to the tuner!

chassis.pid_tuner_pids.push_back({"Lift PID", &liftPID.constants});

🏃Opcontrol Max Speed

By calling this function before the while loop in opcontrol(0, you'll retain the full range of motion of the joystick but your maximum speed will be 63. This can be a number from 0 to 127.

chassis.opcontrol_speed_max_set(63);

📺Blank LCD Pages

All blank pages will come after the autonomous selector. You can check if you're on them with page_blank_is_on(x) and by doing so it'll create the page when you get to it on the selector.

if (ez::as::page_blank_is_on(0))
  ez::screen_print("this is our first blank page", 1);
else if (ez::as::page_blank_is_on(1))
  ez::screen_print("this is our second blank page", 1);

v3.2.0-rc.1

12 Dec 05:41
Compare
Choose a tag to compare
v3.2.0-rc.1 Pre-release
Pre-release

3.2.0-beta.8 has been stable for teams using it so we're ready for the first release candidate!

Notable Changes

  • front trackers now work
  • chassis.pid_odom_set(24_in, 110); now isn't boomerang and is way faster
  • much more complete example project
  • measuring_offsets() function that calculates your tracking wheel offsets for you. run the auton measuring offsets in driver control, and check the blank page after. the offsets you see there are the offsets you should use in code.

All Changes

Full Changelog: v3.2.0-beta.8...v3.2.0-rc.1


🎉ODOMETRY🎉

EZ-Template has odometry!! The easiest way to start messing with this is to start messing with it by downloading the example project below! You can also see the example project here.

🎡Tracking Wheels

You can create tracking wheels with EZ-Template using ADI Encoders (or 3rd party digital encoders) and rotation sensors.

// Are you using tracking wheels?  Comment out which ones you're using here!
//  `2.75` is the wheel diameter
//  `4.0` is the distance from the center of the wheel to the center of the robot
ez::tracking_wheel right_tracker({-'A', -'B'}, 2.75, 4.0);  // ADI Encoders
ez::tracking_wheel left_tracker(1, {'C', 'D'}, 2.75, 4.0);  // ADI Encoders plugged into a Smart port
ez::tracking_wheel horiz_tracker(1, 2.75, 4.0);             // Rotation sensors

To enable them, you'll need these lines of code in void initialize()

// Are you using tracking wheels?  Comment out which ones you're using here!
chassis.odom_tracker_right_set(&right_tracker);
chassis.odom_tracker_left_set(&left_tracker);
chassis.odom_tracker_back_set(&horiz_tracker);  // Replace `back` to `front` if your tracker is in the front!

🚗Odom Drive Syntax

If you have previous actions that you're porting over to 3.2.0 but you're not quite ready to retune odom stuff, you can try replacing .pid_drive_set with .pid_odom_set and it'll make your normal autons use odometry.

void drive_and_turn() {
  chassis.pid_odom_set(24_in, DRIVE_SPEED, true);
  chassis.pid_wait();

  chassis.pid_turn_set(45_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_turn_set(-45_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_turn_set(0_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_odom_set(-24_in, DRIVE_SPEED, true);
  chassis.pid_wait();
}

🐷Pure Pursuit

EZ-Template's Pure Pursuit is all done on the robot. chassis.pid_odom_set() will be your main function and covers all aspects of odom. You can input as many points as you'd like here and the robot will path through all of them.

// Drive to 0, 30 and pass through 6, 10 and 0, 20 on the way, with slew
chassis.pid_odom_set({{{6_in, 10_in}, fwd, 110},
                      {{0_in, 20_in}, fwd, 110},
                      {{0_in, 30_in}, fwd, 110}},
                     true);
chassis.pid_wait();

You can combine going forward and reverse in the same motion

chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                      {{24_in, 24_in}, rev, 110}},
                     true);
chassis.pid_wait();

And you can pid_wait_until a point has been reached

chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                      {{12_in, 24_in}, rev, 110},
                      {{24_in, 24_in}, rev, 110}},
                     true);
chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
Intake.move(127);
chassis.pid_wait();

🪀Boomerang

Boomerang will try to go to a point at a specific angle. You use this by specifying an angle while using pid_odom_set()

chassis.pid_odom_set({{0_in, 24_in, 45_deg}, fwd, 110},
                     true);
chassis.pid_wait();

🪀🐷Boomerang Injected into Pure Pursuits

Any point that the robot goes to, if you specify the angle it'll become a boomerang motion, even if it's during a pure pursuit path!

chassis.pid_odom_set({{{0_in, 24_in, 45_deg}, fwd, 110},
                      {{12_in, 24_in}, fwd, 110},
                      {{24_in, 24_in}, fwd, 110}},
                     true);
chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
Intake.move(127);
chassis.pid_wait();

👉Turn to Point

You can turn to face a point! All of the syntax for normal turning applies here, so you can do this:

chassis.pid_turn_set({12_in, 12_in}, fwd, 110, ez::longest, true);

Or you can keep it simple and do this

chassis.pid_turn_set({12_in, 12_in}, fwd, 110);

💄Mirrored Field Problem

To help with making unique autons for the left and right side of the field, EZ-Template 3.2.0 has a feature to flip what direction the X and Y axis face. By flipping these you're allowing 1 autonomous routine to work for red and blue.

odom_y_flip();
odom_x_flip();
odom_theta_flip();
odom_y_direction_get();  // True = down is positive Y, False = up is positive Y
odom_x_direction_get();  // True = left is positive X, False = right is positive X
odom_theta_direction_get(); // True = positive is counterclockwise, False = positive is counterclockwise

It is still suggested to make minor tweaks for both sides, nothing is perfect, but it'll be much easier to maintain with one base function.

void base() {
  ez::united_pose start_intaking_here;

  if (chassis.odom_x_direction_get() == false)
    start_intaking_here = {12_in, 24_in};  // If red
  else
    start_intaking_here = {15_in, 24_in};  // If blue

  chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                        {start_intaking_here, rev, 110},
                        {{24_in, 24_in}, rev, 110}},
                       true);
  chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
  Intake.move(127);
  chassis.pid_wait();

  chassis.pid_odom_set({{24_in, 48_in, 45_deg}, fwd, 110},
                       true);
  chassis.pid_wait();

  chassis.pid_turn_set(90_deg, 110, true);
  chassis.pid_wait();
}

void red() {
  base();
}

void blue() {
  chassis.odom_x_flip();
  chassis.odom_theta_flip();
  base();
}

🩰Turn Behavior

In every previous version of EZ-Template, turning used the raw IMU values. This was confusing to teams as turning to 360 and 0 were the same angle but would do different things. In 3.2.0 you can change the default behavior of turning for turns, swings, and odoms. You can choose between:
ez::raw - this is the behavior prior to 3.2.0
ez::left_turn / ez::ccw - this will always turn counterclockwise
ez::right_turn / ez::cw - this will always turn clockwise
ez::longest - this will always take the longest path there, capped at 360deg
ez::shortest - this will always take the shortest path there

You can call these in default_constants() in src/autons.cpp to change what the default behavior is. The 3.2.0 example project has it as ez::shortest.

pid_turn_behavior_set(ez::shortest);
pid_swing_behavior_set(ez::shortest);
pid_odom_behavior_set(ez::shortest);

Now you can change how the robot behaves in turns

void turn() {
  chassis.pid_turn_behavior_set(ez::shortest);

  chassis.pid_turn_set(90_deg, TURN_SPEED, ez::left_turn);
  chassis.pid_wait();

  chassis.pid_turn_set(45_deg, TURN_SPEED, ez::right_turn);
  chassis.pid_wait();

  chassis.pid_turn_set(0_deg, TURN_SPEED, ez::longest);
  chassis.pid_wait();

  // This will take the shortest route because that's the default behavior
  chassis.pid_turn_set(359_deg, TURN_SPEED);
  chassis.pid_wait();
}

🛹Global Slew

If you're tired of having true at the end of all of your motions, you can now globally enable slew for each motion type! You can override the default in each motion, but it won't change the default unless you explicitly change it.

slew_drive_set(true)
slew_swing_set(true)
slew_turn_set

🎸Adding PIDs to PID Tuner

ez::PID liftPID{0.45};

Adding this line of code to initialize() will add your PID to the tuner!

chassis.pid_tuner_pids.push_back({"Lift PID", &liftPID.constants});

🏃Opcontrol Max Speed

By calling this function before the while loop in opcontrol(0, you'll retain the full range of motion of the joystick but your maximum speed will be 63. This can be a number from 0 to 127.

chassis.opcontrol_speed_max_set(63);

📺Blank LCD Pages

All blank pages will come after the autonomous selector. You can check if you're on them with ...

Read more

v3.2.0-beta.8

02 Dec 23:57
Compare
Choose a tag to compare
v3.2.0-beta.8 Pre-release
Pre-release

Default constants have changed in this version to make pointing towards angles less "mushy". You can upgrade your beta 7 project with no breaking changes.

What's Changed

Full Changelog: v3.2.0-beta.7...v3.2.0-beta.8


🎉ODOMETRY🎉

EZ-Template has odometry!! The easiest way to start messing with this is to start messing with it by downloading the example project below! You can also see the example project here.

🎡Tracking Wheels

You can create tracking wheels with EZ-Template using ADI Encoders (or 3rd party digital encoders) and rotation sensors.

// Are you using tracking wheels?  Comment out which ones you're using here!
//  `2.75` is the wheel diameter
//  `4.0` is the distance from the center of the wheel to the center of the robot
ez::tracking_wheel right_tracker({-'A', -'B'}, 2.75, 4.0);  // ADI Encoders
ez::tracking_wheel left_tracker(1, {'C', 'D'}, 2.75, 4.0);  // ADI Encoders plugged into a Smart port
ez::tracking_wheel horiz_tracker(1, 2.75, 4.0);             // Rotation sensors

To enable them, you'll need these lines of code in void initialize()

// Are you using tracking wheels?  Comment out which ones you're using here!
chassis.odom_tracker_right_set(&right_tracker);
chassis.odom_tracker_left_set(&left_tracker);
chassis.odom_tracker_back_set(&horiz_tracker);  // Replace `back` to `front` if your tracker is in the front!

🚗Odom Drive Syntax

If you have previous actions that you're porting over to 3.2.0 but you're not quite ready to retune odom stuff, you can try replacing .pid_drive_set with .pid_odom_set and it'll make your normal autons use odometry.

void drive_and_turn() {
  chassis.pid_odom_set(24_in, DRIVE_SPEED, true);
  chassis.pid_wait();

  chassis.pid_turn_set(45_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_turn_set(-45_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_turn_set(0_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_odom_set(-24_in, DRIVE_SPEED, true);
  chassis.pid_wait();
}

🐷Pure Pursuit

EZ-Template's Pure Pursuit is all done on the robot. chassis.pid_odom_set() will be your main function and covers all aspects of odom. You can input as many points as you'd like here and the robot will path through all of them.

// Drive to 0, 30 and pass through 6, 10 and 0, 20 on the way, with slew
chassis.pid_odom_set({{{6_in, 10_in}, fwd, 110},
                      {{0_in, 20_in}, fwd, 110},
                      {{0_in, 30_in}, fwd, 110}},
                     true);
chassis.pid_wait();

You can combine going forward and reverse in the same motion

chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                      {{24_in, 24_in}, rev, 110}},
                     true);
chassis.pid_wait();

And you can pid_wait_until a point has been reached

chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                      {{12_in, 24_in}, rev, 110},
                      {{24_in, 24_in}, rev, 110}},
                     true);
chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
Intake.move(127);
chassis.pid_wait();

🪀Boomerang

Boomerang will try to go to a point at a specific angle. You use this by specifying an angle while using pid_odom_set()

chassis.pid_odom_set({{0_in, 24_in, 45_deg}, fwd, 110},
                     true);
chassis.pid_wait();

🪀🐷Boomerang Injected into Pure Pursuits

Any point that the robot goes to, if you specify the angle it'll become a boomerang motion, even if it's during a pure pursuit path!

chassis.pid_odom_set({{{0_in, 24_in, 45_deg}, fwd, 110},
                      {{12_in, 24_in}, fwd, 110},
                      {{24_in, 24_in}, fwd, 110}},
                     true);
chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
Intake.move(127);
chassis.pid_wait();

👉Turn to Point

You can turn to face a point! All of the syntax for normal turning applies here, so you can do this:

chassis.pid_turn_set({12_in, 12_in}, fwd, 110, ez::longest, true);

Or you can keep it simple and do this

chassis.pid_turn_set({12_in, 12_in}, fwd, 110);

💄Mirrored Field Problem

To help with making unique autons for the left and right side of the field, EZ-Template 3.2.0 has a feature to flip what direction the X and Y axis face. By flipping these you're allowing 1 autonomous routine to work for red and blue.

odom_y_flip();
odom_x_flip();
odom_theta_flip();
odom_y_direction_get();  // True = down is positive Y, False = up is positive Y
odom_x_direction_get();  // True = left is positive X, False = right is positive X
odom_theta_direction_get(); // True = positive is counterclockwise, False = positive is counterclockwise

It is still suggested to make minor tweaks for both sides, nothing is perfect, but it'll be much easier to maintain with one base function.

void base() {
  ez::united_pose start_intaking_here;

  if (chassis.odom_x_direction_get() == false)
    start_intaking_here = {12_in, 24_in};  // If red
  else
    start_intaking_here = {15_in, 24_in};  // If blue

  chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                        {start_intaking_here, rev, 110},
                        {{24_in, 24_in}, rev, 110}},
                       true);
  chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
  Intake.move(127);
  chassis.pid_wait();

  chassis.pid_odom_set({{24_in, 48_in, 45_deg}, fwd, 110},
                       true);
  chassis.pid_wait();

  chassis.pid_turn_set(90_deg, 110, true);
  chassis.pid_wait();
}

void red() {
  base();
}

void blue() {
  chassis.odom_x_flip();
  chassis.odom_theta_flip();
  base();
}

🩰Turn Behavior

In every previous version of EZ-Template, turning used the raw IMU values. This was confusing to teams as turning to 360 and 0 were the same angle but would do different things. In 3.2.0 you can change the default behavior of turning for turns, swings, and odoms. You can choose between:
ez::raw - this is the behavior prior to 3.2.0
ez::left_turn / ez::ccw - this will always turn counterclockwise
ez::right_turn / ez::cw - this will always turn clockwise
ez::longest - this will always take the longest path there, capped at 360deg
ez::shortest - this will always take the shortest path there

You can call these in default_constants() in src/autons.cpp to change what the default behavior is. The 3.2.0 example project has it as ez::shortest.

pid_turn_behavior_set(ez::shortest);
pid_swing_behavior_set(ez::shortest);
pid_odom_behavior_set(ez::shortest);

Now you can change how the robot behaves in turns

void turn() {
  chassis.pid_turn_behavior_set(ez::shortest);

  chassis.pid_turn_set(90_deg, TURN_SPEED, ez::left_turn);
  chassis.pid_wait();

  chassis.pid_turn_set(45_deg, TURN_SPEED, ez::right_turn);
  chassis.pid_wait();

  chassis.pid_turn_set(0_deg, TURN_SPEED, ez::longest);
  chassis.pid_wait();

  // This will take the shortest route because that's the default behavior
  chassis.pid_turn_set(359_deg, TURN_SPEED);
  chassis.pid_wait();
}

🛹Global Slew

If you're tired of having true at the end of all of your motions, you can now globally enable slew for each motion type! You can override the default in each motion, but it won't change the default unless you explicitly change it.

slew_drive_set(true)
slew_swing_set(true)
slew_turn_set

🎸Adding PIDs to PID Tuner

ez::PID liftPID{0.45};

Adding this line of code to initialize() will add your PID to the tuner!

chassis.pid_tuner_pids.push_back({"Lift PID", &liftPID.constants});

🏃Opcontrol Max Speed

By calling this function before the while loop in opcontrol(0, you'll retain the full range of motion of the joystick but your maximum speed will be 63. This can be a number from 0 to 127.

chassis.opcontrol_speed_max_set(63);

📺Blank LCD Pages

All blank pages will come after the autonomous selector. You can check if you're on them with page_blank_is_on(x) and by doing so it'll create the page when you get to it on the selector.

if (ez::as::page_blank_is_on(0))
  ez::screen_print("this is our first blank page", 1);
else if (ez::as::page_blank_is_on(1))
  ez::screen_print("this is our second blank page", 1);

v3.2.0-beta.7

29 Nov 22:10
Compare
Choose a tag to compare
v3.2.0-beta.7 Pre-release
Pre-release

What do you do with your code?

There is a breaking change! odom_x_direction_flip and odom_y_direction_flip have been renamed to odom_x_flip and odom_y_flip. Besides that, you won't have to change anything else with your project.

What's Changed

Bugs

Features

Full Changelog: v3.2.0-beta.6...v3.2.0-beta.7


🎉ODOMETRY🎉

EZ-Template has odometry!! The easiest way to start messing with this is to start messing with it by downloading the example project below! You can also see the example project here.

🎡Tracking Wheels

You can create tracking wheels with EZ-Template using ADI Encoders (or 3rd party digital encoders) and rotation sensors.

// Are you using tracking wheels?  Comment out which ones you're using here!
//  `2.75` is the wheel diameter
//  `4.0` is the distance from the center of the wheel to the center of the robot
ez::tracking_wheel right_tracker({-'A', -'B'}, 2.75, 4.0);  // ADI Encoders
ez::tracking_wheel left_tracker(1, {'C', 'D'}, 2.75, 4.0);  // ADI Encoders plugged into a Smart port
ez::tracking_wheel horiz_tracker(1, 2.75, 4.0);             // Rotation sensors

To enable them, you'll need these lines of code in void initialize()

// Are you using tracking wheels?  Comment out which ones you're using here!
chassis.odom_tracker_right_set(&right_tracker);
chassis.odom_tracker_left_set(&left_tracker);
chassis.odom_tracker_back_set(&horiz_tracker);  // Replace `back` to `front` if your tracker is in the front!

🚗Odom Drive Syntax

If you have previous actions that you're porting over to 3.2.0 but you're not quite ready to retune odom stuff, you can try replacing .pid_drive_set with .pid_odom_set and it'll make your normal autons use odometry.

void drive_and_turn() {
  chassis.pid_odom_set(24_in, DRIVE_SPEED, true);
  chassis.pid_wait();

  chassis.pid_turn_set(45_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_turn_set(-45_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_turn_set(0_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_odom_set(-24_in, DRIVE_SPEED, true);
  chassis.pid_wait();
}

🐷Pure Pursuit

EZ-Template's Pure Pursuit is all done on the robot. chassis.pid_odom_set() will be your main function and covers all aspects of odom. You can input as many points as you'd like here and the robot will path through all of them.

// Drive to 0, 30 and pass through 6, 10 and 0, 20 on the way, with slew
chassis.pid_odom_set({{{6_in, 10_in}, fwd, 110},
                      {{0_in, 20_in}, fwd, 110},
                      {{0_in, 30_in}, fwd, 110}},
                     true);
chassis.pid_wait();

You can combine going forward and reverse in the same motion

chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                      {{24_in, 24_in}, rev, 110}},
                     true);
chassis.pid_wait();

And you can pid_wait_until a point has been reached

chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                      {{12_in, 24_in}, rev, 110},
                      {{24_in, 24_in}, rev, 110}},
                     true);
chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
Intake.move(127);
chassis.pid_wait();

🪀Boomerang

Boomerang will try to go to a point at a specific angle. You use this by specifying an angle while using pid_odom_set()

chassis.pid_odom_set({{0_in, 24_in, 45_deg}, fwd, 110},
                     true);
chassis.pid_wait();

🪀🐷Boomerang Injected into Pure Pursuits

Any point that the robot goes to, if you specify the angle it'll become a boomerang motion, even if it's during a pure pursuit path!

chassis.pid_odom_set({{{0_in, 24_in, 45_deg}, fwd, 110},
                      {{12_in, 24_in}, fwd, 110},
                      {{24_in, 24_in}, fwd, 110}},
                     true);
chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
Intake.move(127);
chassis.pid_wait();

👉Turn to Point

You can turn to face a point! All of the syntax for normal turning applies here, so you can do this:

chassis.pid_turn_set({12_in, 12_in}, fwd, 110, ez::longest, true);

Or you can keep it simple and do this

chassis.pid_turn_set({12_in, 12_in}, fwd, 110);

💄Mirrored Field Problem

To help with making unique autons for the left and right side of the field, EZ-Template 3.2.0 has a feature to flip what direction the X and Y axis face. By flipping these you're allowing 1 autonomous routine to work for red and blue.

odom_y_flip();
odom_x_flip();
odom_theta_flip();
odom_y_direction_get();  // True = down is positive Y, False = up is positive Y
odom_x_direction_get();  // True = left is positive X, False = right is positive X
odom_theta_direction_get(); // True = positive is counterclockwise, False = positive is counterclockwise

It is still suggested to make minor tweaks for both sides, nothing is perfect, but it'll be much easier to maintain with one base function.

void base() {
  ez::united_pose start_intaking_here;

  if (chassis.odom_x_direction_get() == false)
    start_intaking_here = {12_in, 24_in};  // If red
  else
    start_intaking_here = {15_in, 24_in};  // If blue

  chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                        {start_intaking_here, rev, 110},
                        {{24_in, 24_in}, rev, 110}},
                       true);
  chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
  Intake.move(127);
  chassis.pid_wait();

  chassis.pid_odom_set({{24_in, 48_in, 45_deg}, fwd, 110},
                       true);
  chassis.pid_wait();

  chassis.pid_turn_set(90_deg, 110, true);
  chassis.pid_wait();
}

void red() {
  base();
}

void blue() {
  chassis.odom_x_flip();
  chassis.odom_theta_flip();
  base();
}

🩰Turn Behavior

In every previous version of EZ-Template, turning used the raw IMU values. This was confusing to teams as turning to 360 and 0 were the same angle but would do different things. In 3.2.0 you can change the default behavior of turning for turns, swings, and odoms. You can choose between:
ez::raw - this is the behavior prior to 3.2.0
ez::left_turn / ez::ccw - this will always turn counterclockwise
ez::right_turn / ez::cw - this will always turn clockwise
ez::longest - this will always take the longest path there, capped at 360deg
ez::shortest - this will always take the shortest path there

You can call these in default_constants() in src/autons.cpp to change what the default behavior is. The 3.2.0 example project has it as ez::shortest.

pid_turn_behavior_set(ez::shortest);
pid_swing_behavior_set(ez::shortest);
pid_odom_behavior_set(ez::shortest);

Now you can change how the robot behaves in turns

void turn() {
  chassis.pid_turn_behavior_set(ez::shortest);

  chassis.pid_turn_set(90_deg, TURN_SPEED, ez::left_turn);
  chassis.pid_wait();

  chassis.pid_turn_set(45_deg, TURN_SPEED, ez::right_turn);
  chassis.pid_wait();

  chassis.pid_turn_set(0_deg, TURN_SPEED, ez::longest);
  chassis.pid_wait();

  // This will take the shortest route because that's the default behavior
  chassis.pid_turn_set(359_deg, TURN_SPEED);
  chassis.pid_wait();
}

🛹Global Slew

If you're tired of having true at the end of all of your motions, you can now globally enable slew for each motion type! You can override the default in each motion, but it won't change the default unless you explicitly change it.

slew_drive_set(true)
slew_swing_set(true)
slew_turn_set

🎸Adding PIDs to PID Tuner

ez::PID liftPID{0.45};

Adding this line of code to initialize() will add your PID to the tuner!

chassis.pid_tuner_pids.push_back({"Lift PID", &liftPID.constants});

🏃Opcontrol Max Speed

By calling this function before the while loop in opcontrol(0, you'll retain the full range of motion of the joystick but your maximum speed will be 63. This can be a number from 0 to 127.

chassis.opcontrol_speed_max_set(63);

📺Blank LCD Pages

All blank pages will come after the autonomous selector. You can check if you're on them with page_blank_is_on(x) and by doing so it'll create the page when you get to it on the selector.

if (ez::as::page_blank_is_on(0))
  ez::screen_print("this is our first blank page", 1);
else if (ez::as::page_blank_is_on(1))
  ez::screen_print("this is our second blank page", 1);

v3.2.0-beta.6

29 Nov 06:28
Compare
Choose a tag to compare
v3.2.0-beta.6 Pre-release
Pre-release

Small bug fixes. beta.5 seems like it's performing very well with teams, this should be one of the last releases before a full 3.2.0 release!

What do you do with your code?

If you tuned PID constants for beta 5, you might have to adjust them slightly for beta 6. Making odom_turn_bias(0.5) a larger number, like 0.8 or 0.9, will probably fix it for you. xyPID during pure pursuit now calculates derivative correctly, so it has "larger brakes". Increasing turn bias will lower the brakes that EZ-Template applies to xyPID when entering a turn.

What's Changed Changed since beta.5

  • Turn to point now respects angle behavior by @ssejrog in #193
  • Robot will now successfully face points in quadrant 3 @ssejrog in #194

Special thank you to @aayala04 for helping debug and spend time testing beta.3, beta.4, and beta.5!

Full Changelog: v3.2.0-beta.5...v3.2.0-beta.6


🎉ODOMETRY🎉

EZ-Template has odometry!! The easiest way to start messing with this is to start messing with it by downloading the example project below! You can also see the example project here.

🎡Tracking Wheels

You can create tracking wheels with EZ-Template using ADI Encoders (or 3rd party digital encoders) and rotation sensors.

// Are you using tracking wheels?  Comment out which ones you're using here!
//  `2.75` is the wheel diameter
//  `4.0` is the distance from the center of the wheel to the center of the robot
ez::tracking_wheel right_tracker({-'A', -'B'}, 2.75, 4.0);  // ADI Encoders
ez::tracking_wheel left_tracker(1, {'C', 'D'}, 2.75, 4.0);  // ADI Encoders plugged into a Smart port
ez::tracking_wheel horiz_tracker(1, 2.75, 4.0);             // Rotation sensors

To enable them, you'll need these lines of code in void initialize()

// Are you using tracking wheels?  Comment out which ones you're using here!
chassis.odom_tracker_right_set(&right_tracker);
chassis.odom_tracker_left_set(&left_tracker);
chassis.odom_tracker_back_set(&horiz_tracker);  // Replace `back` to `front` if your tracker is in the front!

🚗Odom Drive Syntax

If you have previous actions that you're porting over to 3.2.0 but you're not quite ready to retune odom stuff, you can try replacing .pid_drive_set with .pid_odom_set and it'll make your normal autons use odometry.

void drive_and_turn() {
  chassis.pid_odom_set(24_in, DRIVE_SPEED, true);
  chassis.pid_wait();

  chassis.pid_turn_set(45_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_turn_set(-45_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_turn_set(0_deg, TURN_SPEED);
  chassis.pid_wait();

  chassis.pid_odom_set(-24_in, DRIVE_SPEED, true);
  chassis.pid_wait();
}

🐷Pure Pursuit

EZ-Template's Pure Pursuit is all done on the robot. chassis.pid_odom_set() will be your main function and covers all aspects of odom. You can input as many points as you'd like here and the robot will path through all of them.

// Drive to 0, 30 and pass through 6, 10 and 0, 20 on the way, with slew
chassis.pid_odom_set({{{6_in, 10_in}, fwd, 110},
                      {{0_in, 20_in}, fwd, 110},
                      {{0_in, 30_in}, fwd, 110}},
                     true);
chassis.pid_wait();

You can combine going forward and reverse in the same motion

chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                      {{24_in, 24_in}, rev, 110}},
                     true);
chassis.pid_wait();

And you can pid_wait_until a point has been reached

chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                      {{12_in, 24_in}, rev, 110},
                      {{24_in, 24_in}, rev, 110}},
                     true);
chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
Intake.move(127);
chassis.pid_wait();

🪀Boomerang

Boomerang will try to go to a point at a specific angle. You use this by specifying an angle while using pid_odom_set()

chassis.pid_odom_set({{0_in, 24_in, 45_deg}, fwd, 110},
                     true);
chassis.pid_wait();

🪀🐷Boomerang Injected into Pure Pursuits

Any point that the robot goes to, if you specify the angle it'll become a boomerang motion, even if it's during a pure pursuit path!

chassis.pid_odom_set({{{0_in, 24_in, 45_deg}, fwd, 110},
                      {{12_in, 24_in}, fwd, 110},
                      {{24_in, 24_in}, fwd, 110}},
                     true);
chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
Intake.move(127);
chassis.pid_wait();

👉Turn to Point

You can turn to face a point! All of the syntax for normal turning applies here, so you can do this:

chassis.pid_turn_set({12_in, 12_in}, fwd, 110, ez::longest, true);

Or you can keep it simple and do this

chassis.pid_turn_set({12_in, 12_in}, fwd, 110);

💄Mirrored Field Problem

To help with making unique autons for the left and right side of the field, EZ-Template 3.2.0 has a feature to flip what direction the X and Y axis face. By flipping these you're allowing 1 autonomous routine to work for red and blue.

odom_y_direction_flip();
odom_x_direction_flip();
odom_y_direction_get();  // True = down is positive Y, false = up is positive Y
odom_x_direction_get();  // True = left is positive x, false = right is positive x

It is still suggested to make minor tweaks for both sides, nothing is perfect, but it'll be much easier to maintain with one base function.

void base() {
  ez::united_pose start_intaking_here;

  if (chassis.odom_x_direction_get() == false)
    start_intaking_here = {12_in, 24_in};  // If red
  else
    start_intaking_here = {15_in, 24_in};  // If blue

  chassis.pid_odom_set({{{0_in, 24_in}, fwd, 110},
                        {start_intaking_here, rev, 110},
                        {{24_in, 24_in}, rev, 110}},
                       true);
  chassis.pid_wait_until_index(1);  // Waits until the robot passes 12, 24
  Intake.move(127);
  chassis.pid_wait();
}

void red() {
  base();
}

void blue() {
  chassis.odom_x_direction_flip();
  base();
}

🩰Turn Behavior

In every previous version of EZ-Template, turning used the raw IMU values. This was confusing to teams as turning to 360 and 0 were the same angle but would do different things. In 3.2.0 you can change the default behavior of turning for turns, swings, and odoms. You can choose between:
ez::raw - this is the behavior prior to 3.2.0
ez::left_turn / ez::ccw - this will always turn counterclockwise
ez::right_turn / ez::cw - this will always turn clockwise
ez::longest - this will always take the longest path there, capped at 360deg
ez::shortest - this will always take the shortest path there

You can call these in default_constants() in src/autons.cpp to change what the default behavior is. The 3.2.0 example project has it as ez::shortest.

pid_turn_behavior_set(ez::shortest);
pid_swing_behavior_set(ez::shortest);
pid_odom_behavior_set(ez::shortest);

Now you can change how the robot behaves in turns

void turn() {
  chassis.pid_turn_behavior_set(ez::shortest);

  chassis.pid_turn_set(90_deg, TURN_SPEED, ez::left_turn);
  chassis.pid_wait();

  chassis.pid_turn_set(45_deg, TURN_SPEED, ez::right_turn);
  chassis.pid_wait();

  chassis.pid_turn_set(0_deg, TURN_SPEED, ez::longest);
  chassis.pid_wait();

  // This will take the shortest route because that's the default behavior
  chassis.pid_turn_set(359_deg, TURN_SPEED);
  chassis.pid_wait();
}

🛹Global Slew

If you're tired of having true at the end of all of your motions, you can now globally enable slew for each motion type! You can override the default in each motion, but it won't change the default unless you explicitly change it.

slew_drive_set(true)
slew_swing_set(true)
slew_turn_set

🎸Adding PIDs to PID Tuner

ez::PID liftPID{0.45};

Adding this line of code to initialize() will add your PID to the tuner!

chassis.pid_tuner_pids.push_back({"Lift PID", &liftPID.constants});

🏃Opcontrol Max Speed

By calling this function before the while loop in opcontrol(0, you'll retain the full range of motion of the joystick but your maximum speed will be 63. This can be a number from 0 to 127.

chassis.opcontrol_speed_max_set(63);

📺Blank LCD Pages

All blank pages will come after the autonomous selector. You can check if you're on them with page_blank_is_on(x) and by doing so it'll create the page when you get to it on the selector.

if (ez::as::page_blank_is_on(0))
  ez::screen_print("this is our first blank page", 1);
else if (ez::as::page_blank_is_on(1))
  ez::screen_print("this is our second blank page", 1);

v3.2.0-beta.5 - Tracking Wheels! (frfr this time)

27 Nov 04:50
Compare
Choose a tag to compare

beta.4 worked great with IMEs, but as soon as you stated to use trackers it became hit or miss. beta.5 solves this and aims to give consistent behavior between using trackers and imes.

This includes breaking changes from beta.4

PID constants for odom will have to be retuned along with trackers being renamed from odom_left_tracker to odom_tracker_left. If you have autons on previous betas, I would suggest testing the beta.5 example project out before you upgrade your main project.

What's Changed since beta.4

New Contributors

Full Changelog: v3.2.0-beta.4...v3.2.0-beta.5

v3.2.0-beta.4 - Tracking Wheels! (fr this time)

08 Sep 07:13
Compare
Choose a tag to compare

Full Changelog: v3.2.0-beta.3...v3.2.0-beta.4

v3.2.0-beta.4

This version is stable

This is very close to what RC1 will be. This is being released now for testing while extra documentation is made in drive.hpp. There is still a chance breaking changes happen between this and RC1 / the full 3.2.0 release.

Features since beta.3

  • you can now remove blank pages

Bug fixed since beta.3

  • rotation sensors will actually reverse in tracking wheels
  • fixed typos in example project

Refactoring

  • drive.hpp now has comments

Missing Features

Once this bug is fixed/figured out, the new drive constructor will work and will allow you to input track width into the constructor. Additional comments are needed in drive.hpp, and new example autonomous routines are needed to show how odom works.

What should you test?

Something cool about this version is pid_odom_set now supports the same syntax as pid_drive_set. So you can take one of your autos from a previous 3.x version, change pid_drive_set to pid_odom_set, and you'd have tracking in your autons! This will not be as good as telling the robot what points to go to, as accumulative error will still happen, but each motion should be more accurate with this.

v3.2.0-beta.3 - Tracking Wheels!

07 Sep 01:19
Compare
Choose a tag to compare
Pre-release

Full Changelog: v3.2.0-beta.2...v3.2.0-beta.3

v3.2.0-beta.3

This version is stable

This is very close to what RC1 will be. This is being released now for testing while extra documentation is made in drive.hpp. There is still a chance breaking changes happen between this and RC1 / the full 3.2.0 release.

Features since beta.2

  • tracking wheel support
  • turn directions
  • pid_drive_set syntax is compatible with pid_odom_set
  • blank pages can be added to the auton selector
  • "mirrored field problem" is solved
  • blanket enables for slew
  • odom units
  • clamp() now has an option for 2 parameters
  • slew reenables when speed increases during pure pursuits
  • you can add custom stuff to pid tuner

Bug fixed since beta.2

  • disabling PID now turns the drive motors off

Missing Features

Once this bug is fixed/figured out, the new drive constructor will work and will allow you to input track width into the constructor. Additional comments are needed in drive.hpp, and new example autonomous routines are needed to show how odom works.

What should you test?

Something cool about this version is pid_odom_set now supports the same syntax as pid_drive_set. So you can take one of your autos from a previous 3.x version, change pid_drive_set to pid_odom_set, and you'd have tracking in your autons! This will not be as good as telling the robot what points to go to, as accumulative error will still happen, but each motion should be more accurate with this.