Compressing Videos with ffmpeg

By Thomas Weng on August 4, 2020

Publication venues in robotics often allow supplementary video submissions. There are often strict size limits on video submissions. To meet these limits, it’s often necessary to compress the video.

I used to compress my videos using Compressor after making my videos with iMovie or Final Cut Pro. Now I just use ffmpeg to compress my videos. I share/export the video from Final Cut Pro and then use this command to compress it:

ffmpeg -i -vcodec libx264 -crf 20

The -crf flag specifies the compression factor and it ranges from 0 (lossless) to 51 (worst quality), with 23 as the default. If I’m trying to get under a size limit, I’ll run the command multiple times, playing with this value until I meet the requirement.

ffmpeg can also be used for converting between video formats, trimming, cropping, etc. Hope this helps!

Tags: how-to

Installing NVIDIA drivers and CUDA on Ubuntu 16.04 and 18.04

By Thomas Weng on July 23, 2020

There are several ways to install NVIDIA drivers. This method using a runfile is the one that works most reliably for me.

  1. Determine the driver version and CUDA version you need. The versions will depend on the GPU you have and the code you want to run. For example, specific pytorch and tensorflow versions are tied to specific CUDA versions.

  2. Download the driver and CUDA version as a runfile from the NVIDIA website: CUDA Downloads

  3. Disable the default nouveau drivers. Create a file at /etc/modprobe.d/blacklist-nouveau.conf and add the following:
     blacklist nouveau
     options nouveau modeset=0

    Then regenerate the kernel initramfs: sudo update-initramfs -u

  4. If you already have nvidia installed, uninstall it: sudo apt-get purge nvidia-* and reboot your machine.

  5. Upon restart, drop into the tty terminal with Ctrl+Alt+F1 and log in.

  6. Stop running the gui. On Ubuntu 16.04 run sudo service lightdm stop, on 18.04 run sudo systemctl stop gdm3.service.

  7. Find the runfile you downloaded from step 2 and run it: sudo sh ./

  8. Follow the prompts to install the driver and CUDA. If the installation fails, you will need to check /var/log/nvidia-installer.log or /var/log/cuda-installer.log to find out why. You can test if the installation was successful by running nvidia-smi.Check the reported driver and CUDA versions.

  9. Restart the gui. On Ubuntu 16.04 run sudo service lightdm start, on 18.04 run sudo systemctl start gdm3.service.

  10. Leave the tty terminal and return to the gui: Ctrl+Alt+F7.

For more detailed instructions, see the NVIDIA CUDA Installation Guide.

Tags: how-to

Replacing my command prompt with emoji

By Thomas Weng on November 26, 2019

The title says it all:

My new emojified command prompt

Why did I do this? Wanted to see if it was possible. And seeing emoji somehow brings me a lot of joy.

I did this on my Mac with zsh and Oh My Zsh. Here are the steps if you want to do the same in your own terminal.

1. In your .zshrc, add the emoji plugin to the list of plugins.

  git alias-tips autojump emoji

2. In your zsh theme, update the PROMPT variable.

You’ll find the name of your current theme in your .zshrc file. The file for that theme is under /.oh-my-zsh/themes/.

In my theme file, I replaced > with $(random_emoji animals), which loads a random animal emoji as my terminal prompt each time I open a new terminal. Other options are available in the emoji plugin documentation.

# Old prompt
${_current_dir}$(git_prompt_info) %{$fg[$CARETCOLOR]%}>%{$resetcolor%} '
# New prompt
${_current_dir}$(git_prompt_info) %{$fg[$CARETCOLOR]%}$(random_emoji animals)%{$resetcolor%} '

To see changes, reload zsh with source ~/.zshrc or open and close the terminal.

3. Change the command prompt emoji with the random_emoji command

Step 2 replaces your prompt with a random emoji for each new terminal. If you get tired of the current emoji, you can change it with the command random_emoji. It outputs a random emoji and also randomly changes the emoji of your prompt.

Change the command prompt emoji with `random_emoji`


How to install ROS drivers for Azure Kinect on Ubuntu 16.04

By Thomas Weng on August 31, 2019

Following up from my previous post on installing the Azure Kinect SDK on Ubuntu 16.04, this post provides instructions for setting up ROS drivers for the Azure Kinect. These instructions apply for ROS kinetic and Ubuntu 16.04.

The credit for figuring out these steps goes to Kevin Zhang!

Installation steps

  1. Install the Azure Kinect SDK executables on your path so they can be found by ROS.
    $ cd path/to/Azure-Kinect-Sensor-SDK/build
    $ sudo ninja install
  2. Clone the official ROS driver into a catkin workspace.1
    $ cd catkin_ws/src
    $ git clone
  3. Make minor edits to the codebase. If you were to build the workspace now, you would get errors relating to std::atomic syntax.

    To fix this, open <repo>/include/azure_kinect_ros_driver/k4a_ros_device.h and convert all instances of std::atomic_TYPE type declarations to std::atomic<TYPE>. Below is a diff of the edits I made.

    @@ -117,11 +117,11 @@ class K4AROSDevice
      volatile bool running_;
      // Last capture timestamp for synchronizing playback capture and imu thread
           -    std::atomic_int64_t last_capture_time_usec_;
           +    std::atomic<int64_t> last_capture_time_usec_;
      // Last imu timestamp for synchronizing playback capture and imu thread
           -    std::atomic_uint64_t last_imu_time_usec_;
           -    std::atomic_bool imu_stream_end_of_file_;
           +    std::atomic<uint64_t> last_imu_time_usec_;
           +    std::atomic<bool> imu_stream_end_of_file_;
      // Threads
      std::thread frame_publisher_thread_;
  4. Build the catkin workspace with either catkin_make or catkin build.

  5. Copy the libdepthengine and libstdc++ binaries that you placed in the Azure_Kinect_SDK/build/bin folder from my previous post in your catkin workspace.
    $ cp path/to/Azure_Kinect_SDK/build/bin/ path/to/catkin_ws/devel/lib/
    $ cp path/to/Azure_Kinect_SDK/build/bin/ path/to/catkin_ws/devel/lib/

    You will have to do this whenever you do a clean build of your workspace.

  6. Copy udev rules from the ROS driver repo to your machine.
    $ cp /path/to/Azure_Kinect_ROS_Driver/scripts/99-k4a.rules /etc/udev/rules.d/

    Unplug and replug your sensor into the machine after copying the file over.

  7. Source your built workspace and launch the driver.
    $ source path/to/catkin_ws/devel/setup.bash
    $ roslaunch azure_kinect_ros_driver driver.launch

    Note that there are parameters you can adjust in the driver launch file, e.g. FPS, resolution, etc.

  8. Run Rviz and you should be able to open Image and PointCloud2 widgets that read topics from the sensor!
Screenshot from RViz


  1. I used commit be9a528ddac3f9a494045b7acd76b7b32bd17105, but a later commit may work. 

Tags: robotics, how-to

Terminal tips

By Thomas Weng on August 27, 2019

The terminal is an essential tool,1 but also one whose tasks are most easily automated and optimized.

Most of the time spent on the command line is on non-value-adding tasks, like moving files around, executing programs, installing dependencies, and checking system status.2 These tasks are necessary, but do not end up in your final deliverable, i.e. a publication, code, or other project output.

Therefore, you should aim to spend as little time in the terminal as possible, focusing instead on value-adding tasks like writing programs, analyzing data, making visualizations, etc.

Here are some ways to automate or speed up terminal tasks. I’m assuming you use bash, but the items here are applicable to most terminals.

  1. Shorten commands using aliases and scripts
  2. Use reverse-i-search to find past commands
  3. Check system status using htop
  4. Split one terminal into several with tmux
  5. Download files faster using aria2
  6. Set up key-based authentication for ssh and Github
  7. Try out other terminals

1. Shorten commands using aliases and scripts

This one seems obvious, but if you run the same set of commands often, turn them into aliases. I use aliases for computers that I ssh into often, e.g.

alias hostname="ssh <username>@<hostname>"

Another use case is for aliases is to shorten series of commands, like navigating to a directory and running a script.

alias intera="cd ~/catkin_ws && source"

If a series of commands is longer or more complicated (e.g. building and running code), it may be better to turn it into a shell script, which will allow you to take advantage of for loops, command line arguments, etc.

2. Use reverse-i-search to find past commands

Related to the first point, avoid typing out commands, especially if you have typed a similar one already. Besides using tab-autocompleting aggressively, I also use reverse-i-search all the time to search my command history. Activate reverse-i-search using Ctrl+r and then type in a query to find matches. Hit Ctrl+r again to find the next match.

Demonstrating reverse-i-search.

3. Check system status using htop

htop is an improved version of the top command, with colors, better navigation, and other features.

Screenshot of htop.

Besides checking system usage, I also use this to find (F4) and kill (F9) processes as root (sudo htop).

4. Split one terminal into several with tmux

Use tmux to create and switch between multiple terminal panes within one window.

Demonstrating how to split panes with tmux. Note that my keybindings are different from the tmux defaults.

Another benefit to tmux is that these terminals will persist even if your ssh connection drops. Simply run tmux attach after ssh-ing back in to return to your panes.

5. Download files faster using aria2

aria2 is an alternative to wget or curl that parallelizes downloads:

$ aria2c -x8 <URL>

-xN specifies how many connections to open for parallelization.

6. Set up key-based authentication for ssh and Github

Instead of typing your password each time you ssh or push/pull from Github, use key-based authentication. It only takes a few minutes and has the dual benefit of being easier and more secure than password authentication.

To set up key-based authentication for ssh, see this DigitalOcean post: How To Set Up SSH Keys. You’ll need to do this once per computer you want to ssh into. For Github, follow the steps outlined here: Connecting to Github with SSH

7. Try out other terminals

You can also explore beyond bash and try terminals with more features. I use zsh as my default shell with plugins for jumping between directories, better autocomplete, etc. If you’re interested in zsh, check out these articles on how to get started: Articles from the Oh My Zsh wiki.

Many thanks to Cherie Ho for editing this post and introducing me to zsh, Leah Perlmutter for introducing me to reverse-i-search, Rosario Scalise for tmux, and Abhijat Biswas for aria2!


  1. If you’re a beginner with the terminal, this reference from Software Carpentry is a good starting point. 

  2. I consider working in a terminal-based editor like vim different from being on the command line itself.