Get Your Motor Running – VESC – Jetson RACECAR Build

After finishing the installation of the ROS packages on the Jetson RACECAR, we need to program the VESC, an electronic speed controller, for use in the Jetson RACECAR. Looky here:


As discussed in Part 3 – ESC Motor Controller, the TRAXXAS steering servo and the drive motor Electronic Speed Controller (ESC) are controlled by PWM signals sent from an on board radio receiver.

For the Jetson RACECAR, we replace the stock TRAXXAS ESC with a Vedder Electronic Speed Controller (VESC). The major reason for the change is to gain full control at low speeds. The stock ESC puts the minimum vehicle speed at around 6 mph. Another reason is that the VESC is open source, which allows the curious to explore the motor controller implementation.

Architecturally, the VESC has a STM32 ARM Cortex processor. The STM32 runs ChibiOS, a real-time operating system. The default firmware flashed on the VESC-X is ‘Servo-in’, which allows a remote controller to set the motor speed. For the Jetson RACECAR application, the VESC servo port needs to be programmed as ‘Servo-out’, which allows commands to be sent to the robot steering servo.

Fortunately there is a compiled binary of the version of the VESC firmware that includes the Servo-out setting. We can flash the STM32 directly from the Jetson using a program called ‘bldc-tool’. BLDC is an acronym for BrushLess DC motor.

Note: There are also compiled versions of the bldc-tool for x86 machines, if you prefer that route.

Once the bldc-tool loads the servo-out firmware on to the VESC, we then load a configuration file which matches the VESC configuration to control a TRAXXAS Velineon 3500 motor.

Note: The actual VESC firmware is available in binary form in the bldc-tool firmwares directory. If you are interested in building the VESC firmware from source, you can compile it from the bldc firmware source tree on Github.


The VESC is wired to the Jetson using a micro USB to USB-A cable. The USB cable normally communicates motor speed and steering angles between the Jetson and the VESC. The TRAXXAS steering servo is wired to the VESC servo header. In this application, a 90 degree, 3 pin female header helps with the wiring.

VESC Wiring
USB input from Jetson on left, steering servo center. Front of robot is to the left.

The JetsonHacks account on Github contains a repository named installBLDC. To build the bldc-tool:

$ git clone
$ cd installBLDC
$ ./

This will build the bldc-tool and download the RACECAR motor configuration files. The RACECAR motor configuration files are downloaded from the Github mit-racecar repository, and are stored in ~/hardware/vesc.

Before starting the bldc-tool, connect the VESC to the vehicle battery. Then:

$ cd ~/bldc-tool
$ ./BLDC_Tool

This will bring up the GUI to interact with the VESC. Before flashing the firmware, hit the ‘Connect’ button to communicate with the VESC. The VESC should be at ttyACM0 (more formally, /dev/ttyACM0). The current firmware revision will display in the lower right hand corner on connection.

Use the ‘Firmware’ tab to flash the firmware binary, the configuration can be loaded from the ‘Load XML’ button. Important Note: You must select the correct version of firmware to match the VESC that you are using, otherwise damage and other bad things can happen. In the video, we flashed the firmware ‘VESC_servout.bin’ for version 4.12 of the hardware.

The configuration file is located in ~/hardware/vesc. The configuration file shown in the video is ‘6.141_bldc_VESC_X_hw_30k_erpm.xml’ which is for the VESC-X. If you are using a regular VESC, you will probably want to use the configuration file ‘/6.141_bldc_old_hw_30k_erpm.xml’.

Note: You should use the updated bldc configurations, the configurations lower the min and max erpm values to avoid damaging the VESC when connected to the TRAXXAS motor.


Once the firmware and configuration files are in place, the Jetson RACECAR is ready for teleoperation. The game controller used in the video is a Logitech Gamepad F710.

The Logitech F710 connects to the Jetson over a wireless USB dongle. The dongle should be plugged into the USB Hub which is connected to the Jetson. In order to connect to the Jetson, power the F710 on (using the center button labeled ‘Logitech’). You can press the ‘VIBRATION’ button to tell if the F710 is powered on. The ‘VIBRATION’ button should cause the game controller to rumble in your hand.

In order for the Jetson to recognize the F710, the small switch on the back of the game controller must be in the ‘D’ position. If the game controller is in the ‘X’ position, it will not be detected.

Once connected, the game controller should show up as /dev/input/js0

The F710 has two modes, selected by the button labeled ‘MODE’. The correct mode for the Jetson RACECAR is the one which the left joystick controls axis 0 and 1, and the right joystick controls axis 2 and 3. There is an LED next to the MODE button. If the LED is green, then it is in the wrong mode, the light should be off.

You can test a game controller to make sure it is working with the Jetson using the jstest program.

$ sudo jstest /dev/input/js0

Note: jstest is located in the joystick debian package. If it is missing you can install it:

$ sudo apt-get install joystick

Once the game pad works, you can teleoperate the robot. Make sure that the wheels are clear of any obstructions.

$ cd racercar-ws
$ source devel/setup.bash
$ roslaunch racecar teleop.launch

The robot has a deadman switch, the upper button (labeled LB) on the left horn of the game pad. Holding the deadman button, you can control the throttle with the left joystick, and the steering with the right joystick.


At this point, we have a working robot platform. We’ll have a couple of more articles on the Jetson RACECAR. As we go forward, we will build the final prototype hardware platform, which we are calling RACECAR/J.


    • Currently we’re working with suppliers for the custom parts such as the deck platforms, wiring, and a version of the VESC that has the proper bullet connectors. We’ve been through a couple of revisions, getting closer. The idea is that you’ll be able to buy the custom, long tent pole items as a kit. This should cut down the amount of time needed to wrangle the long lead time items. There also won’t be a need to do soldering. There are options beyond that, such as a kit of everything needed to build the robot and a fully functioning robot. Once the parts have been specified, we’ll be able to create a BOM. Thanks for reading!

  1. Hello Jim,

    Thanks for all the time and effort you’re putting into these. I’m following along with every article and currently working on my own RACECAR build. I’ve found that the VESC-X can take a while to obtain, so i’m thinking of just buying the original VESC and using that (as you did in your earlier prototype). Will i have any trouble following along with this video installing the software and drivers on the older VESC model?


    • Hi Ryan,
      The software is the same, the only difference in the install is that you should select a different VESC configuration file from the MIT RACECAR repository: 6.141_bldc_old_hw_30k_erpm.xml
      I hope you can share your build with us! Thanks for reading!

      • How did you know you were flashing the proper firmware version? I’ve been looking through the BLDC firmware github, but that’s mostly information about compiling my own firmware from source (as you pointed out). I’d just like to know what VESC models match up with which firmwares provided with the BLDC tool install. Are you sure the firmware you used will work on the original VESC model?

        • Not quite sure what the question is. If you look in the firmware directory of the BLDC tool:

          There are versions that match with each version of the VESC hardware. The VESC-X, for example, is hw 4.12, so I looked in the hw_410_411_412 directory. There is a default version, which works with any of the 4.10 to 4.12 models. There is a version for what looks like a resistor substitution. There’s one for the servo-out. The normal setting for the VESC is Servo in, as the long boarders use wifi/bt controllers to control the motor speed. Servo out is for controlling a servo from the VESC. I don’t know what the 2811 version does, but I’m sure it’s in the forums somewhere. So am I sure? Nope. If I was making a moon shot, then I would research more deeply. But an educated guess after reading the VESC forum leads me to believe that works. When I flashed a VESC, it works. Is it absolutely 100% correct. Dunno.

          • Just my two cent here. I once built my own Ambilight device. I used RGB addressable LED strip, where you have full control for every pixel in that strip. They came with variety of IC chips. One of them is ws2811. Mine was ws2812b.
            I think Vedder add those .bin because he can connect the nunchuk and the ws2812 LEDs directly without any external microcontroller and with a minimal amount of external components.

  2. I’m currently doing the work for a company i’m interning for, i’ll run it by and if it’s okay with them i would love to share! We’re still early in the build now but as we get closer to a working car (provided i get the proper permissions) i’d be happy to share our progress with you What is the best way to get in touch with you? Via youtube/article comments or the “Contact Us” portion of your website?

  3. Great project. How are the game pad commands routed from TX1 to VESC? Does the bldc-tool have game pad support, or do you have a custom communication over USB for this?

    • Hi Erwin,
      The Logitech Gamepad F710 has a wireless dongle that plugs into the USB hub. It’s pretty painless. An alternative is to use a Bluetooth controller and pair it to the Bluetooth onboard the Jetson. The Jetson reads the Gamepad controller as input, and the outputs to the VESC over USB throttle and steering commands. Thanks for reading!

  4. Thanks! How is the USB communication done exactly? Using libusb sending the VESC commands directly? Is there a pointer to this part of the code?

  5. Also, is there a pointer to the C source code diff/changes to make VESC firmware servo output instead of input?

      • Thanks. In a nutshell, you need to recompile bldc firmware using SERVO_OUT_ENABLE 1 in conf_general.h .

        In addition, you need to replace the resistor in R5 to a lower value, say 100 Ohm.

        • In the cars that I have built, there haven’t been any issues using the servo with the stock resistor value. MIT has not recommended any changes, they’ve built several cars. However, that doesn’t mean changing out the resistor is a bad idea.

  6. Hello,

    I don’t see the ttyACM0 port through BLDC tool for some reason and cannot connect to VESC. It does work on ubuntu 16.04 and Windows on my laptop but not on my TX2 (I work through ssh with X forwarding if that is of any relevance, and I added my user to the dialout group). Maybe you have an idea, or at least could post the output of “lsmod” command run on your TX2 here?


    • The stock NVIDIA Jetson TX2 on version L4T 27.1 does not have ACM support enabled by default. You will need to modify the stock kernel to add that module, or build it into the kernel itself. The next version of L4T is scheduled to be released soon, I do not know whether ACM support was added.
      As I recall, the configuration is:
      USB Modem (CDC ACM) support
      Abstract Control Model (CDC ACM)
      If it’s any consolation, it took me a while to figure out what the screw was going on. Good luck!

      • Thanks a lot! That explains. I saw your video on updating the kernel but somehow missed what was the reason for updating it. I’ll try to update the kernel.

        • Hi Alex,
          The kernel rebuild was just for instructions on how to do rebuild onboard the Jetson TX2. I was using the VESC for the first time on the TX2 last week, and discovered the issue. Simple enough to fix, but a little frustrating that something that standard was missing out of the kernel build.

          • Thanks for your answer. I have successfully built a new kernel with cdc-acm support enable with the script you provided and was able to connect the VESC. However, I encountered another problem — TX2 does not detect the game pad (the same as in your video). I suspect it’s a driver issue again, maybe you have a solution for this one as well? There is very little information about these things out there, and your website is pretty much the only source. Thanks for running it!

          • Hi Alex,
            You’re welcome. I’m glad you got the VESC to work!
            The Jetson TX2 needs to have the JOYSTICK modules built into the kernel image for the Logitech Gamepad to work.
            I think it’s JOYDEV and CONFIG_INPUT_JOYSTICK
            Make sure to build them as part of the image, you may encounter issues if they are added as modules. If you’re using make xconfig, you can do a Find on JOYSTICK and both should come up, though they will have a more descriptive name. Next, click on the option. The first option is to build it as a module, the second is to build it into the image. Make sure to save it after editing, build the new kernel, then install it. Good luck!

  7. Hi,

    I am trying to run a Traxxas Velineon 3500 Motor and VESC-X combo. Could you please confirm that by “updated bldc configurations” you meant the “6.141_bldc_VESC_X_hw_30k_erpm.xml” file? I loaded this config file and the BLDC-Tool failed to detect the motor.

    Below is a quote from above.

    “You should use the updated bldc configurations, the configurations lower the min and max erpm values to avoid damaging the VESC when connected to the TRAXXAS motor.”


  8. Hi Kangalow,

    Thanks for all your work!

    I have set everything up and everything works perfectly except for one thing.
    There is no steering control. With jstest I can execute and observe the servo command values from the F170 and when I plug the Servo in the wheels line up straight, but it seems nothing is being communicated from Focbox to the servo itself.

    Any ideas?


  9. My car currently does not have the IMU and LIDAR. Can I run the tele-operation?

    When I ran “roslaunch racecar teleop.launch”, it complained could not find IMU and LIDAR. When I tried the gamepad, the car did not give any response.

    • Does the joystick actually connect to the car? Did you run the joystick test mentioned in the article?
      The IMU and LIDAR probably don’t make a difference, though you may have to check the UDEV rules to make sure the VESC is seen.

  10. I went through this before I got my IMU and LIDAR.

    You can simply comment out the LIDAR and IMU in the teleop launch file, it should suffice.

    Also be sure to echo the /joy topic, just to make sure its communicating.

    Have fun!

    • When I type

      rostopic echo /joy

      I got the following print-out:

      seq: 13267
      secs: 1525586625
      nsecs: 853562656
      frame_id: ”
      axes: [-0.0, -0.0, -0.0, -0.0, -0.0, -0.0]
      buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

      When I ran the joystick, I can see “nsecs”, “axes”, and “buttons” changes.
      However, the car did not give any response

    • I tried running teleop without the IMU and Lidar. I commented out the argumennts in the launch file, but now Im getting: ERROR: cannot launch node of type [vesc_ackermann/ackermann_to_vesc_node]: can’t locate node [ackermann_to_vesc_node] in package [vesc_ackermann]
      Am I commenting the right things in the right places or is there more that I need to do?

  11. whilst everything is (or at least should be running from your perspective), that is once you’ve run teleop.launch, you can open a new terminal and type:
    $ rostopic list

    This will show a list of active topics. I believe it is the /joy topic (it may be somehting else, it’s been a while and I’m not 100%. You can perform some deductive reasoning to figure out which one.

    You then can enter:

    $ rostopic echo /joy

    or replace joy with whatever topic should be communicating the data from the joypad to the ackermann nodes.

    If you see a string of values as you meddle with the joypad, then you know its connected and communicating.
    You can do the same thing for nodes:

    $ rosnode list


    $ rosnode info /X

    X being the node you wish to investigate.

    Have fun!

  12. I just read your prior comment.

    You did it correctly. Now press buttons on the joypad whilst echoing and see if it gives any data variables.

    • hi N:

      Thanks a lot for your comments.

      I think the joystick is communicting with the Jetson TX2 since I could see “nsecs”, “axes”, and “buttons” changes.
      However, the car still did not response. Do you know what I should check?

      Is there a way we send directly movement signal to VESC? for Example, can we use BLDC tool to force the car to move?

  13. Good to know you got it working!

    On a side note, does anyone know of any autonomous algorithms I can run on this?

    I’ve tried tweaking nav2d, navigation_stack and also, most recently, the Formula1Epoch that is found on the nvidia github.
    I’m not having much luck and would really like to see it functioning autonomously.

    The Formula1Epoch seems like the most promising, with almost everything in alignment with the JetsonHacks iteration, but algorithmic output just doesn’t seem to be happening.

    Any input or guidance would be hugely appreciated!


    • I am not there yet so I do not know how to answer you questions. However, I have one question which should be easy to answer… (I do not know ROS yet)

      I would like to build a ros node that

      1. Read some numbers from a file
      2. Use the numbers as steering and acceleration, broadcasting them
      3. VESC node received these numbers and drive the car

      Could you please give me some directions that I can start to learn and work on?

  14. Hi
    The hardware of my vesc is 4.12 and the firmware of my vesc is 2.18.Now I follow the tutorial in this article,using “6.141_bldc_VESC_X_hw_30k_erpm.xml” file.But the moto does not run.My car and moto are the same as jetson’s racecar.I don’t know why.Should I detect my moto through bldc_tool in the first?
    Thanks very much!

      • My voltage of my racecar battery which connect my vesc is 40C 11.1v and 5000mah.And I have another battery which connect nvidia tx2,the voltage of this battery is 12v.
        Should I change the parameter in “6.141_bldc_VESC_X_hw_30k_erpm.xml” file?

        Thanks for your reply :)

  15. Hi,

    I’m building a Racecar and I have to buy a VESC for it. I’m quite confused because there are several manufacturers and different versions of the hardware. Do you have an advice on which VESC to buy, considering that shipping time to Europe is a concern for our project? VESC from Maytech seems widely available, are they appropriate for the racecar? I’ve seen also VESC from Focbox, but with less availability and slightly higher price.

    Thanks for your help!

  16. I have the exact same Logitech F710 Gamepad, but I’m getting different results from this video.

    The video shows the X-AXIS of the right joystick controlling the Steering, but on my system the Y-AXIS of the right joystick controls the steering. It’s a little hard to steer when the up/down motion controls the steering.

    Any thoughts as to where I went wrong?

    Here is how I have things setup
    Mode is set so the green light is off
    The switch on the gamepad is set to D

    Here is the results of JSTEST

    Axis 0 -> Left Joystick X-AXIS
    Axis 1 -> Left Joystick Y-AXIS
    Axis 2 -> Right Joystick X-AXIS
    Axis 3 -> Right Joystick Y-AXIS
    Axis 4 -> GamePad X (binary on/off as expected)
    Axis 5 -> GamePad Y (binary on/off as expected)

  17. Hi all. I try to make the VESC work with the Velineon 3500 motor of the Traxxas Slash. I can’t get it detected by VESC Tool. It spins three times, and then it says “Detection failed”. I first loaded the configuration file 6.141_bldc_old_hw_30k_erpm.xml, and then launched the motor detection in BLDC mode. Amongst all the attempts, it managed to detect the motor once, but then when I tried to control the motor, it was shaking instead of spinning.

    Any idea?


    • I also tried with bldc_tool instead of the new Vesc Tool. Same result: bad detection.

      One more info: my VESC is a 4.12 hardware.

    • I have not seen the Velineon motor work with the bldc tool. I just use it to flash the firmware and set the configuration. After that, it works fine with the Jetson. Thanks for reading!

  18. The BLDC tool detection works better if the motor is not driving the wheels: you can release one screw and rotate the motor so it runs freely, then do the detection and move the motor back and fix the screw.

  19. That is odd, I could run the detection just fine, both in BLDC and FOC mode, with and without sensors. I added an option for the AS5407 magnetic encoder, with magnet glued onto the axis at the back of the motor for better startup and position control to drive at ultra low speed. See this low-speed video:

    • Thanks for your reply. Do you remember which parameters you used for sensorless detection? Maybe I need to change something (intensity, duty cycle, rpm, or other)?

  20. After some more attempts, I’ve managed to get the motor detected by the VESC! I had first to upload the XML configuration from MIT project to the motor, upload this configuration to the VESC and then run detection. It doesn’t work every time, but sometimes it does.

    But after that, when I use the arrow keys, the motor shakes instead of spinning. Did I miss something?

    I’ve made two videos: first one is successful detection (still shakes at the end, I don’t know if it is the expected behaviour), second one is an attempt to spin the motor with the arrow keys from VESC Tools.

    Thanks again for your help.

Leave a Reply

Your email address will not be published.