Tipping Point - Season code request

Worlds for the tipping point season is over.

Preserve your amazing autonomous and driver control programming forever !

As I do every year, I would like any teams that think their programing may help future generations to send me the code or (preferably) a link to a git repo I can fork, I will add to a github organization as I have done in previous years. The code can be programmed using any development system, not just VEXcode, as long as I can create a git repo for it (so blocks programs may be difficult to archive). FYI, the names of these old archives actually have nothing to do with what we now call VEXcode, I started setting these up years before we even thought of that.

code from the past six years is here

Nothing but Net - github.com/vexcode-2015
Starstruck - github.com/vexcode-2016
In the Zone - github.com/vexcode-2017
Turning point - github.com/vexcode-2018
Tower Takeover - github.com/vexcode-2019
Change Up - github.com/vexcode-2020

23 Likes

Well, I guess I will kick it off this year.

We are 4253B from Taipei Taiwan. The code is written by me and my teammate Jason. I worked mainly on the control algorithms, while he worked on pathing the autonomous on field. The repository below contains our code this year, which actually won us the Think Award at the Live Remote Worlds this year.

Here are some of the videos of our code:



Features (More information can be found on the readme.md file on github)

  1. Rather than using traditional tank or arcade control, we used something called curvature drive instead. Essentially, the left stick controls the throttle and the right stick controls the curvature (inverse of radius) the robot drives in. You basically control how large of an arc your robot drives in, and increasing speed doesn’t affect the rate you’re curving. (The implementation can be found in src/ryanlib/ExpandedSkidSteerModel.cpp)

  2. For autonomous, we controlled our chassis using what is called an S Curve Motion Profile. By inputting the desired distance to travel, as well as the robot’s max velocity, acceleration and jerk, it is able to generate a set of velocity that respects the robot’s kinematic constraints and travels the desired distance when followed perfectly. Since the kinematic constraints are obeyed, minimal slipping will occur, improving the overall accuracy and precision of the chassis.

  3. Our code also allows curved motions by creating trajectories. Our trajectories are generated given a bezier curve and the robot’s kinematic constraints. Similar to the S Curve Motion Profile above, it also generates a set of velocity that when followed, will follow the bezier curve perfectly. Since the trajectories are generated from our computers, then pasted into this code, so you won’t see any trajectory generation code here.

  4. Because the S Curve Motion Profiles output target velocity and acceleration, we needed some way to feed the output to the motor. We used a mainly feedforward based controller that takes into consideration the target velocity, acceleration, and position as well as the current motor state to accurately control the motor velocities. With motion profiles and our velocity controller, we were able to get our control to be within 0.1" of accuracy and basically 0 variance.

  5. Another feature of our code is that all the subsystems are asynchronous. By using threads, the control functions are all non-blocking, meaning we are able to control multiple subsystems at once, improving the efficiency of our runs. The code is also thread safe through the use of mutexes.

  6. We also made an auton selector that uses an SD Card.

  7. The code is unit checked using the unit framework included in okapi to make sure that dimensional analysis matches up.

  8. Very clean code, with everything documented and written in classes. Most of our motion control codes are contained within the ryanlib folder (which is built upon okapilib). By simply applying the library and giving new system constraints, we are able to use the same code again on different robots. For example, below are the code we use to create our S Curve Motion Profile controllers:

MotorGroup leftDrive({-3, -2});
MotorGroup rightDrive({17, 20});
ProfileConstraint moveLimit({3_ftps, 7_ftps2, 7_ftps2, 30_ftps3});

auto chassis = ChassisControllerBuilder()
    .withMotors(leftDrive, rightDrive)
    .withDimensions({AbstractMotor::gearset::green, 5.0/7.0}, {{3.25_in, 1.294_ft}, imev5BlueTPR})
    .build();

auto profiler = AsyncMotionProfilerBuilder()
    .withOutput(chassis)
    .withProfiler(std::make_unique<SCurveMotionProfile>(moveLimit))
    .build();

Future Plans

Our team is made up of 4 juniors and 1 sophomore. However, we are not sure if we will compete next year. I might just move on and mentor younger teams and continue developing my code. Most of the reusable code written this year will be incorporated into lib4253, another programming library I’ve been developing since around February last year. It includes powerful features such as pure pursuit, RAMSETE (and hopefully custom trajectory generation too), and I plan on finishing the code around summer / early Spin Up and releasing it to the public.

31 Likes

This is fantastic code @Ryan_4253B ! Roboteers would be well advised to include your library and learn the programming techniques you have employed!

1 Like

Thanks @Ryan_4253B
The new collection is now here.

Any code is welcome, if it’s just a VEXcode project with no repo then zip up the project and I will handle making a suitable repo for it.

4 Likes

Wow, amazing code! Taiwan always has the best programming.

We use PID with heading correction. Not as good as any Taiwanese powerhouse teams, but it works. (sort of)

12 Likes

Here’s the code from VEXU Team USC over the last few years. Not the cleanest, but it got the job done!

https://github.com/uscvex/RobotCode

4 Likes

While our code has no major robotics innovation, I think it’s a nice basic PROS codebase. It’s also the first major robot codebase that I put together myself, so it will always be special to me.

Here are some of the cool features:

Also, HUGE THANKS to:

  1. OkapiLib folks (for literally all the complex drive, PID, odometry this does and UNITS are RAD!!!)
  2. PROS makers (for the framework and toolchain)
  3. EZ-Template (for the auton-selector and ideas about stuck monitoring (cool feature #3))
  4. PROS-Grafana-CLI (I used this a little bit here, I’m really excited about its potential for my spin up code)
  5. Belton High School for funding this, @pietro.giustino for teaching us and helping us do this, and my entire team for making the bot I put this code on
  6. Vex and RECF for making this even be a thing

Repo

Custom OkapiLib required for this to work:

Edit after @Mentor_355v’s post:

Yes, with OkapiLib, adding a tile = 24 inches unit can be really useful for autonomous.
I’d recommend everyone copy the following into your Okapi projects. I’ll see if they want to upstream it

namespace okapi
{
    constexpr QLength tile = 24 * inch;
    namespace literals
    {
        constexpr QLength operator"" _tile(unsigned long long int x)
        {
            return static_cast<double>(x) * tile;
        }

        constexpr QLength operator"" _tile(long double x)
        {
            return static_cast<double>(x) * tile;
        }
    }
}
6 Likes

is there a reason why you guys chose to use the S curve motion profiloling over pure pursuit?

1 Like

I really like your usage of units, including your custom “tile” unit of distance!

5 Likes

What exactly is a ramsete controller? I’ve heard it mentioned before in random papers I’ve read, but I’ve never found anything that actually explains how it works

1 Like

not very creative or useful, but it exists

3 Likes

Here’s one example implementation:

Basic idea:

Given a current Pose (x, y, heading) and a desired Pose (x1, y1, h1) and a desired velocity and curvature, return left and right wheel speeds that correct for the error between current and desired poses. Generally, the desired poses will be generated via motion profiling and include at least Pose, Velocity, Curvature (e.g. how much the robot is turning)

6 Likes

Got it, thank you.

1 Like

This is what I always post when someone asks what RAMSETE is. This comes from my teammate asking questions on the FRC discord.

“If it works it works”, but essentially when given a trajectory and your robot’s current position, it can modify the trajectory’s output to help better follow the path. It has gained popularity in the past few years in FRC as it is extremely robust and effective.

5 Likes