Last year we had a few problems with motion profile generators because they were either difficult to use or they could not handle complex paths that we wanted to use. We used Vannaka’s motion profile generator for all of our paths last year, but we couldn’t make a path with a turn in the middle without driving at a slow speed. To solve this problem, I made a generator for my team and any others that would like to use it with the goal of being simple to use, but having many quality of life features.

Here are some of the main features:

Paths are made using bezier curves, so you can get the exact path shape you want

The generator will automatically slow the robot when going into a turn too fast. If this is still not enough, a custom maximum velocity can be set at each point in the path

Paths can be previewed in real time to see what the robot will do

Paths can be generated as CSV files or as an array (Java, C++, or Python)

Paths can be saved to a file to edit them later

The generation output can be customized to include the data you want and in the order you want

Generated CSV files can be deployed directly to the RoboRIO from the app

Cross-platform. Works on Windows, MacOS, and Linux

Automatic updates for some versions, all others will have a notification that a new update was released

More information and downloads can be found at the GitHub repo

It does not. I started working off of code I found used in another unfinished generator I found last season and customized it from there. I would link to this generator but it appears that it was deleted because I can’t find the repository.

Awesome tool you have here. My only issue is that on my windows 10 machine by default the output format is set to P,V,A,H which throws an invalid format error, replacing it with lowercase solves the issue.

One thing you might consider adding is the ability to drive backward through some of the path. Right now, as far as I can see, you have to make a 180° turn in order to back up after scoring.

Thanks for the feedback! This can currently be done by making another path that moves away after scoring and toggling the reversed switch when generating that path. If what you want is to drive back in a straight line I would recommend using something like pathfinder to do this to avoid over-complicating things.

Hello, i’m new to Motion Profiling…just trying to get started as an off-season exercise. Do the Motion Profile Generators generate 2 different output files (one for left wheels and another for right wheels)? If so, is the code then ran simulataneously and synchronously on both sides of the drive train? Otherwise, how does the robot handle curves and such if there is only one motion profile output file? Can someone post a screen capture of one of their motion profile outputs (both sides, if indeed that is how it works)?

How it’s generated depends on how you want to use it. This generator defaults to generating two paths for the left and right side of the drive train. The way my team did the code for this was to run a PD loop for each side to minimize the error. There’s a good video from 254 on how this works here: https://youtu.be/8319J1BEHwM
Another option is to generate one path and follow curves using an imu on the robot. The pure pursuit algorithm is a good example of this but I don’t have much experience with it and this generator isn’t built for it. I have been thinking about adding a pure pursuit mode to make using it easier. I don’t have a screenshot of the output files since I’m on my phone right now but the files are just a big list of information about every point in time along the path such as the target position, velocity, acceleration, etc. This also depends on what values you choose to use.

thanks for the quick reply. I just downloaded and ran the generator and then noticed that it does indeed generate a file for each side! cool! I’m looking forward to trying it tonight on my mini-bot!

i watched the 254 video about a month ago before i started building. Build is done now and its time to get motion profile auton going!

Are you planning on adding a middle “source” path for other trajectory followers like ramsete (and to be able to choose if you want left, middle, and/or right paths)?
Also is there any future plans to add “jerk” as an option of the outputted data like velocity and acceleration?
I used to use Vannaka’s generator but we stopped because the developer removed the middle path feature that was present in the older versions. We used Pathweaver which was more painful in terms of organization but our only option since it exported a middle path.

I’m not familiar with ramsete so I’m unsure of what you mean by “source” path. There’s an option to output the center path before it is split into left and right paths but I don’t know if that’s the same thing. I’ll add the option to choose center, left, right, or both as an output to my list of things to do. It’s possible to add jerk as an output option but I haven’t been able to figure out how to add a maximum jerk to the generation. There’s not an equation that I know of that would allow me to limit jerk and still play nice with the rest of the generation. I’ll probably try to figure out again at some point.

From how I understand it, the “source” path describes how the entire robot (the “chassis state”) moves instead of how individual wheels (the “wheel state”) move. I believe that the option for the centre path before it is split fit into this definition, but it would be rather hard to follow this path because it doesn’t give us the curvature of the path in the output. If we have the curvature, we can get the angular velocity (in rad/s) and angular acceleration (in rad/s^{2}) by just multiplying the curvature with linear velocity and linear acceleration respectively. Once we have these numbers, we can easily turn it into wheel velocities (and accelerations), where left side is linear - angular * wheelBaseRadius and right side is linear + angular * wheelBaseRadius. For me, there is really no need to have individual wheel speeds in the path; every time I need them; I just call a function with the above calculations.

Many feedback control algorithms, including pure pursuit and ramsete, rely on manipulating the above linear and angular velocity in response to setpoint errors. It’s much easier to model the robot as a unit instead of two individual sides. For example, the actual ramsete formula then becomes much simpler to implement:

k = 2.0 * kZeta * sqrt(kBeta * linear ** 2 + angular ** 2)
sinXOverX = 1.0 if epsilonEquals(error.rotation, 0.0, 1E-2) else math.sin(error.rotation) / error.rotation
adjustedLinear = linear * math.cos(error.rotation) + k * error.translation.x
adjustedAngular = angular + k * error.rotation + linear * kBeta * sinXOverX * error.translation.y

So I think something like this is what @tekunalogy was referring to as the “source” path.

As for the jerk part, I believe @tekunalogy was suggesting to have the jerk value available as part of the output format, not jerk limiting, which is easy to do by dividing the change in acceleration by the change in time. I have tried to implement jerk limiting myself, but havn’t found a good way of doing it either; the best that I came up with was to generate the path first, find all the points that violate the jerk constraint, and change the acceleration values before and after those points so that they ramp up; and finally regenerate the velocity and dt for each point based on the new acceleration values.

You don’t need to use the curvature to get the angular velocity. The angular velocity (dθ/dt) is simply the rate of change of the angle w.r.t time at a reference point on the trajectory. You can calculate this by diving the difference of the “heading” (θ) values (bounding the difference between -PI and PI) by the dt.

I used this method to get the Ramsete path tracking algorithm working with Pathfinder generated “source paths” last year.

Multiplying curvature (dθ/ds) by the linear velocity (ds/dt) will also give you the angular velocity (dθ/dt) by the chain rule.

Although this is true for angular velocity, it is not true for angular acceleration:

Angular acceleration = dω/dt where ω is the angular velocity.
We know that ω is equal to the linear velocity (v) times the curvature (k).

Differentiating ω = v * k, we get

dω/dt = d/dt (v * k)

By product rule, dω/dt = dv/dt * k + v * dk/dt [1]

We don’t have dk/dt, but we do have dk/ds* and ds/dt dk/ds * ds/dt = dk/dt [2]

Substituting [2] in [1], we get dω/dt = dv/dt * k + ds / dt * ds/dt * dk/ds dω/dt = acceleration * curvature + velocity * velocity * d_curvature

*this assumes that you can calculate the derivative of curvature with respect to arc length for a trajectory (254’s 2018 Library and Pathfinder v2 can do this).