LabVIEW trajectory library

Hello everyone

I realize it is late in the season for something new, but…

Here is a link to a LabVIEW library, sample robot projects, and utility programs that implement the FRC WPILIB ramsete, spline, trajectory, and associated routines in LabVIEW. While the library, utilities, and robot projects have been tested, this should be considered “beta” software.

The following are included:

  • Utility programs to create trajectories. There are two utility programs. One uses Jaci’s pathfinder library. The other uses the Trajectory library. Both of these programs show the results graphically for review, then allow the trajectory to be written to a text file. The file can
    then be read by a robot program for use. Here are some screen shots of the utility programs. The utility programs can be built into executable files for execution on windows computers without LabVIEW installed.

  • The trajectory library. This library implements most, but not all, of the FRC WPILIB routines to create and use trajectories. Currently the library is only imeplemented for differential drive robots (tank and arcade drive). Swerve and mechanum drives are not yet implemented. The
    differential drive motor voltage constaint is not implemented. The ramsete controller is implemented to set left and right drive speed demands based on the trajectory.

  • Sample Robot project 1. This contains both a simulated and real robot. The robot code creates a trajectory as part of the BEGIN routine. The trajectory can then be executed in TELEOP by pressing the “A” button on an xbox style controller, or equivalent button on any controller.

  • Sample Robot project 2. This contains both a simulated and real robot. The robot code reads a trajectory from a file as part of the BEGIN routine. The trajectory can then be executed in TELEOP by pressing the “A” button on an xbox style controller, or equivalent button on any controller. For the simulated robot, the .CSV file needs to be copied to the “\Documents\LabVIEW Data” directory before running the simulated robot. Likewise on a real robot, the file needs to be copied to the roboRIO prior to execution. See the subVI that reads the file
    to get the default directory.

Here is a link the zip file with these projects.

Here is a sample screenshot of the trajectory creation utility.

Here is a screenshot of one of the sample robot project’s

Here is a screen shot of the trajectory create front panel from robot sample 1.

Here is a screen shot of the network table variables from the sample robot


Finally a screen shot of the Trajectory library

The VI documentation is incomplete, but the routines closely follow the C++/Java implementation.

Please let me know if you find any errors or issues, or if you find this useful…

It just seemed like the LabVIEW teams should have the same capabilities as teams using other languages…

Hopefully this will end up in a chapter in the Secret Book of FRC LabVIEW.

Happy roboting…




Truly excellent work. Thank you for making this resource available to labview teams.

1 Like

Awesome. Thank you!

1 Like

Thank you for the work put into both of these resources. I have been trying to find a good labview way of doing motion profiling and this will help us in the future. The book will be great for training our kids and also my future development.

1 Like

Hello everyone

Well… I found a bug in the trajectory creation utility that used pathfinder. At the beginning and the end of the trajectory, the distance between samples was too small causing a divide by zero error when executing the trajectory file. I updated the utility to remove trajectory samples that are too close together (keeping the first and last sample). The zip file on the google drive has been updated. If you happened to download the original, I suggest getting the newer one. The link is the same.
Jim S.


Any plans on releasing a version of this that will work with swerve?

Hey Jim - I was looking through the code and noticed that the VIs to set motor power were in periodic tasks, not teleop. Our team has always put these in teleop - is there any reason to put them in one versus the other?

@BCR-Jim - So I don’t know much about swerve drive. I also haven’t thought too much about next steps. I thought I would maybe 0) concentrate on getting the teams I help through there competitions… 1) fix bugs anyone found, 2) document the VI’s, 3) set the VI properties to make them more efficient (subroutine, and inline where useful), 4) implement things more of the things that were left out. For 4) I was thinking of the missing differential drive constraint; maybe adding an acceleration limiting constraint like pathfinder has (“jerk”), although I’m uncertain it this had real world benefits or not (I think it might); seeing what others thought would be useful – like swerve drive or whatever. I’d also be happy to have help with the implementation…

@MazeOfEncryption - On a different subject, the through bore encoders work really nicely…

There are a couple of reasons for putting common code in Periodic Tasks and using global variables with wrapper subVI’s to write “demands” to the the Periodic Tasks code.

  1. so not to duplicate code…
  2. More importantly, to not get into interaction issues when switching from autonomous to teleop. For example if the drive system is taking a “target” then rate limiting it to get actual “demand”, the rate limiting depends on remembering its previous state. Putting the code in Auto and in teleop might cause an un-wanted step change when switching between the two. Same thing with a state machine to control a shooter. (And last year there was some blurring of the two modes.)
  3. I just think it is easier. (Not very scientific.)
  4. Maybe to keep the teleop more “lightweight” so it can’t fall behind. (Also note that I put the network table writes in a different loop in periodic tasks so not to affect the control loop. LabVIEW may be running this in a different thread, although it may run code in the same loop in different threads too … I think.)

I have been teaching Acquire, Decide, Act method. (Acquire reads, scales and filters sensor values – include joysticks. Decide uses this data to decide what to ask each system to do – what drive speed do we want, what elevator height do we want, what ball shooter/gatherer system mode do we want. Act takes the desired things set by Decide and runs the low level control code, rate limiting, position control, state machines, whatever to turn these demands into actuator outputs (motor demands, solenoids demands, etc…) This makes it easier to compartmentalize the code and allows more people to work on coding.

The detriments of this separation are perhaps a little bit of extra latency. (at most 20 milliseconds). Generally this didn’t seem to be enough to worry about.

In the end – either way would work okay.

1 Like

Ah, that makes a lot of sense. I didn’t think about the fact that periodic tasks would be running during auto too. Thank you!

Edit: Also, what about through-bore encoders?

If I have your team correct, I noticed your robot at the GOS week zero event. Specifically noticed the through bore encoders. We ended up getting these to help see what our shooter is doing and control the speed. (We were the team scaring others with our shooter… I hope we have some of the that fixed. :slight_smile: )

We were at the GoS week 0 scrimmage, but our team doesn’t have any through-bore encoders on our robot. I’m from the Titanium Titans.

Awesome to see more resources like this developed for LabVIEW teams.
1712 built our own path drawer to work with our pure pursuit controller in 2018. The lead programmer on that effort (now an alumni) wrote a whitepaper on the effort. The actual code can be found here, and here are specific links to the robot simulator, pure pursuit controller, and path drawer.
Huge thanks to 2168 for supplying one of the underlying algorithms and for 254’s 2014 autonomous routines being the original inspiration to implement pure pursuit and motion profiling.

Here’s a presentation that was given at 272’s 2018 Comcast Bootcamp
pure-pursuit(1).pdf (13.0 MB)

And our 2019 control system’s handout
Dawgma2019ControlSystemsHandout.pdf (509.4 KB)

I did a bit of black magic with property nodes…

That’s really fun.

1 Like

Our team is playing with your trajectory generator and follower code. I have to say - this is some awesomely clean LabVIEW code.

If we weren’t locked out of the school, we were planning on getting it running on the robot this weekend.

I had a couple questions. Is the ‘reverse’ function of the WPI trajectory code in there somewhere that I missed? Or are running backwards trajectories not implemented?

Next - what’s the difference between Max_Velocity and “Real Max Speed”?

Last - is there an easy way to remove a point once you’ve added it?

We were planning on hacking in a swerve trajectory follower in as quickly as possible in the leadup to our competition scheduled for this weekend. Under the circumstances, I might now do a proper port of all the WPIlib swerve and mecanum classes, following your style.


Sorry, I haven’t looked at this in a couple of days.

I’ll try and answer your questions.

  1. reverse. This does exist in the trajectory config data structure. There isn’t a method to set this other than using cluster pack/unpack. Reverse is not implemented in the trajectory creation tool yet. I haven’t tested any of the reverse logic yet. (Initially I only implemented enough to get things working. I’ve gone back to add missing compatibility, but it is far from complete. The first things implemented, ramsete and odometry were the least “identicial” with the java/c++. I’ve updated the ramsete, but not the odometry. I’ve also updated the splines so that cubic and quintic are implemented. I updated the tool too. I haven’t published these updates yet. I was trying to get a little more done before doing this.)

  2. Max Velocity and Real Max Speed. – The trajectory creation utility that uses pathfinder didn’t have a method to constrain the speed of the individual wheels of differential drive robot (or any other kind of robot.) I added “real max speed” to be the top actual physical speed of the robot. The trajectory is created using “max speed”.

Then the trajectory is divided into individual wheel demands. If any of these exceeds “real max speed”, an indicator lights shows this. Max speed can be reduced and the trajectory re-created. (Not a very elegant solution, but it worked for me…)

  1. In the utilities, you can delete an array element or entire data set. Run the program. (It might even work when the program isn’t running.) Right click on the data, and select “Delete element” (I found this after getting frustrated and playing around some…)
    If you select the entire array, you can delete all the data elements.

If I misinterpreted the questions, let me know. Hope this helps.

Let me know if you are interested in the newest version of this code. If so, I’ll try and I’ll package and post.

I really briefly looked at the swerve stuff. It looked like some or all of the following three classes would need to be implemented.
Kinematics directory

  • swerveDriveKinematics
  • swerveDriveOdometry
  • swerveModuleState
    Trajectory\Constraint directory
  • swerveDriveKinematics (Note that constraints are implemented somewhat differently, organizationally, than the java/c++)

I’ve made some significant changes to the libraries. I’ll try and post the updated code so you can use that as the base.

If you implement the swerve, I’d really like to include it with the rest of the library if you are willing to provide it.