Skip to content

v3.2.0-beta.6

Pre-release
Pre-release
Compare
Choose a tag to compare
@ssejrog ssejrog released this 29 Nov 06:28
· 92 commits to dev since this 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);