Complete Guide to Deploying MIT Mini Cheetah on Sweet Potato Robot RDK S100

1. Introduction to mbedOS

1.1 SPI Interface Initialization Example

void init_spi(void){
    SPISlave *spi = new SPISlave(PA_7, PA_6, PA_5, PA_4);
    spi->format(16, 0);         // 16bit
    spi->frequency(12000000);   // 12M
    spi->reply(0x0);
    cs.fall(&spi_isr);
    printf("donenr");
}

1.2 CAN Bus Communication Example

#include "mbed.h"

DigitalOut myled(D8);
CAN can1(PD_0, PD_1, 500000);

int main() {
    CANMessage msg;
    while(1) {
        if(can1.read(msg)) {
            printf("Message received:id=%d,type=%d,%dn", msg.id, msg.type, msg.data[0]);
            myled = !myled;
        }
    }
}

2. MIT Cheetah Open Source Resources

2.1 Hardware Related

2.2 Software Related

3. MIT Mini Cheetah Robot System

3.1 Simulation Environment Configuration and Usage

./sim/sim
./mit_ctrl m s

3.2 Combined Use of Real Robot and Simulation

# Terminal 1: Start simulation interface
./sim/sim

# Terminal 2: Start controller (real robot mode)
./mit_ctrl m r f

4. RDK S100 Development Board Selection and System Deployment

4.1 Development Board Selection Introduction

image.png

image.png

No.FunctionNo.Function
J1Main board power supply interfaceJ22MCU domain 16-Pin interface
J2Main board function connectorJ23MCU expansion board 100-Pin interface
J3RTC battery interfaceJ2440-Pin interface
J8Fan control interfaceJ25Camera expansion board 100-Pin interface
J15Main domain and MCU domain JTAG interfaceK1Reset button
J16Type-C interface, for flashing, Main domain and MCU domain debuggingK2Sleep button
J17M.2 Key E interfaceSW1Power switch
J18M.2 Key M interfaceSW2Flashing mode switch
J19&J204x USB3.0 Type-A interfaceSW3&SW6Pin function switching DIP switches
J21HDMI interfaceU43&U452x Gigabit RJ45 network ports

5. RDK S100 System Flashing

5.1 USB Driver Installation

5.2 Complete System Flashing

5.2.1 Download Flashing Tools and System Image

image.png

5.2.2 U-Boot Flashing Steps

6. RDK S100 System Startup and Network Configuration

6.1 System Startup

image.png

6.2 Network Configuration

image-Uart-Login.gif

root@ubuntu:~# ifconfig -a
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.93  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 240e:39d:4d4:e2f0:283c:b3ff:fe97:bb72  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::283c:b3ff:fe97:bb72  prefixlen 64  scopeid 0x20<link>
        ether 2a:3c:b3:97:bb:72  txqueuelen 1000  (Ethernet)
        RX packets 38261  bytes 55422230 (55.4 MB)
        RX errors 0  dropped 98  overruns 0  frame 0
        TX packets 21241  bytes 1485148 (1.4 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 95

eth1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 92:b0:69:58:4e:df  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 96

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 145  bytes 13618 (13.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 145  bytes 13618 (13.6 KB)
        RX errors 0  dropped 0 overruns 0  frame 0
        TX errors 0  dropped 0 overruns 0  frame 0

6.3 System Version Confirmation

sunrise@ubuntu:~$ cat /etc/version
4.0.4-Beta

7. RDK S100 Software Environment Configuration

7.1 Computer Board Selection Description

7.2 Download MIT Mini Cheetah Source Code

git clone https://github.com/fuwei007/NavBot-EG02.git

7.3 Install Third-Party Dependency Libraries

sudo apt-get update
sudo apt -y install cmake gcc build-essential
sudo apt-get -y install openjdk-11-jdk
sudo apt -y install liblcm-dev
sudo apt-get -y install libeigen3-dev
sudo apt-get -y install mesa-common-dev
sudo apt -y install libgl1-mesa-dev
sudo apt -y install libglu1-mesa-dev
sudo apt-get -y install freeglut3-dev
sudo apt-get -y install libblas-dev liblapack-dev
sudo apt-get -y install libopenblas-dev

sudo apt install -y coinor-libipopt-dev gfortran libglib2.0-dev
sudo apt install -y openjdk-8-jdk

7.4 Install Qt

Method 1: Source Code Compilation Installation (Suitable for cases requiring a complete Qt development environment)

./qt-opensource-linux-x64-5.14.2.run

Method 2: Install Using apt (Recommended, Simpler)

sudo apt install -y libqt5 libqt5gamepad5
sudo apt install -y libqt5gamepad5-dev

7.5 Install LCM

sudo update-alternatives --config javac
# Select option 2: /usr/lib/jvm/java-8-openjdk-arm64/jre/bin/java

sudo update-alternatives --config java
# Select option 2: /usr/lib/jvm/java-8-openjdk-arm64/bin/javac
mkdir build 
cd build 
cmake .. 
make
sudo make install 
sudo ldconfig

7.6 Install Eigen 3.3.6

mkdir build 
cd build 
cmake .. 
sudo make install 
sudo ldconfig

7.7 Modify MIT Mini Cheetah Program Source Code

image.png

7.7.1 Modify Git Branch and Repository Address in CMakeLists.txt

image.png

7.7.2 Modify Eigen3 and LCM Header File Paths

include_directories("/usr/local/include/lcm/")
include_directories("/usr/local/include/eigen3")
include_directories("/usr/include/lcm/")
include_directories("/usr/include/eigen3")
Cheetah-Software-master/common/CMakeLists.txt
Cheetah-Software-master/rc_test/CMakeLists.txt
Cheetah-Software-master/robot/CMakeLists.txt
Cheetah-Software-master/sim/CMakeLists.txt
Cheetah-Software-master/user/MIT_Controller/CMakeLists.txt

7.7.3 Modify Qt Path

#printf "${HOME}/Qt/${QT_VER}/gcc_64/"
printf "$(qmake -query QT_INSTALL_PREFIX)/"
image.png

7.7.4 Fix Serial Port Header File Missing Issue

sudo nano /usr/include/asm-generic/termios.h
#ifndef _SYS_IOCTL_H
struct winsize {
        unsigned short ws_row;
        unsigned short ws_col;
        unsigned short ws_xpixel;
        unsigned short ws_ypixel;
};

#define NCC 8
struct termio {
        unsigned short c_iflag;         /* input mode flags */
        unsigned short c_oflag;         /* output mode flags */
        unsigned short c_cflag;         /* control mode flags */
        unsigned short c_lflag;         /* local mode flags */
        unsigned char c_line;           /* line discipline */
        unsigned char c_cc[NCC];        /* control characters */
};
#endif

7.7.5 Adapt spdlog Logging Library

add_subdirectory(Goldfarb_Optimizer)
add_subdirectory(ParamHandler)
add_subdirectory(inih)
add_subdirectory(osqp)
add_subdirectory(JCQP)
add_subdirectory(qpOASES)
add_subdirectory(lord_imu)
add_subdirectory(wheeltec_imu)
add_subdirectory(SOEM)

if(CMAKE_SYSTEM_NAME MATCHES Linux)
  add_subdirectory(vectornav)
endif()

# Build all 3rd-party libs with PIC (useful for shared libs)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# ------------------------------------------------------------
# spdlog: use system package (libspdlog-dev) instead of source
# ------------------------------------------------------------
find_package(spdlog CONFIG REQUIRED)

# Provide a target named "spdlog" for compatibility with existing link lines.
add_library(spdlog INTERFACE)

if(TARGET spdlog::spdlog)
  target_link_libraries(spdlog INTERFACE spdlog::spdlog)
elseif(TARGET spdlog::spdlog_header_only)
  target_link_libraries(spdlog INTERFACE spdlog::spdlog_header_only)
else()
  message(FATAL_ERROR "spdlog CMake target not found (spdlog::spdlog / spdlog::spdlog_header_only). Install libspdlog-dev or set spdlog_DIR.")
endif()
cmake_minimum_required(VERSION 3.5)

# Add project() to avoid CMake warning and make PROJECT_SOURCE_DIR valid
project(MiniCheetah LANGUAGES C CXX)

set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
set(CMAKE_DISABLE_SOURCE_CHANGES  ON)

if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
  message(SEND_ERROR "In-source builds are not allowed.")
endif ()

set(CMAKE_COLOR_MAKEFILE ON)
#execute_process(COMMAND ../scripts/make_types.sh)

set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

#set(CMAKE_VERBOSE_MAKEFILE ON)

option(MINI_CHEETAH_BUILD "use compiler flags for mini cheetah computer" OFF)
set(BUILD_TYPE_RELEASE TRUE)

option(NO_SIM "Do not build simulator" OFF)

# -------------------------------
# spdlog: use system libspdlog-dev
# Must be before any add_subdirectory() that links spdlog::spdlog
# -------------------------------
find_package(spdlog CONFIG REQUIRED)

# Some distros provide only header-only target; alias it to spdlog::spdlog
if(NOT TARGET spdlog::spdlog AND TARGET spdlog::spdlog_header_only)
  add_library(spdlog::spdlog ALIAS spdlog::spdlog_header_only)
endif()

if(MINI_CHEETAH_BUILD)
  SET (THIS_COM "../" )
  CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
    ${CMAKE_BINARY_DIR}/Configuration.h)
  set(CMAKE_CXX_FLAGS "-O3 -no-pie -ggdb -Wall 
  -Wextra -Wcast-align -Wdisabled-optimization -Wformat=2 
  -Winit-self -Wmissing-include-dirs -Woverloaded-virtual 
  -Wshadow -Wsign-promo -Werror")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=overloaded-virtual -Wno-error=unused-parameter")
  set(CMAKE_C_FLAGS "-O3  -ggdb -std=gnu99 -I.")
  message("**** Mini-Cheetah build enabled ****")
else(MINI_CHEETAH_BUILD)
  SET (THIS_COM "${PROJECT_SOURCE_DIR}/" )
  CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
    ${CMAKE_BINARY_DIR}/Configuration.h)

  if(CMAKE_SYSTEM_NAME MATCHES Linux)
    set(CMAKE_CXX_FLAGS "-O3 -no-pie -march=native -ggdb -Wall 
    -Wextra -Wcast-align -Wdisabled-optimization -Wformat=2 
    -Winit-self -Wmissing-include-dirs -Woverloaded-virtual 
    -Wshadow -Wsign-promo -Werror")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=overloaded-virtual -Wno-error=unused-parameter")
  elseif(APPLE)
    set(CMAKE_CXX_FLAGS "-O3 -march=native -ggdb -Wall 
    -Wextra -Wcast-align -Wdisabled-optimization -Wformat=2 
    -Winit-self -Wmissing-include-dirs -Woverloaded-virtual 
    -Wshadow -Wsign-promo")
    include_directories("/usr/local/include/")   # lcm includes
  endif()

  set(CMAKE_C_FLAGS "-O3  -ggdb  -march=native -std=gnu99 -I.")
  message("**** Mini-Cheetah build disabled ****")
endif(MINI_CHEETAH_BUILD)

set(CMAKE_CXX_STANDARD 14)

#find_package(lcm)

add_subdirectory(robot)
add_subdirectory(third-party)
add_subdirectory(common)

if(NO_SIM)

else(NO_SIM)
  add_subdirectory(sim)
endif()

add_subdirectory(user)
add_subdirectory(rc_test)

7.8 Compile MIT Mini Cheetah Program

cd Cheetah-Software
cd scripts
chmod +x make_types.sh
./make_types.sh  # You may see error messages like `rm: cannot remove...`, this is normal and can be ignored

cd .. && mkdir mc-build && cd mc-build
rm CMakeCache.txt  # Clean old configuration (if necessary)

# Configure project
# -DMINI_CHEETAH_BUILD=TRUE: Build Mini Cheetah version
# -DJCQP_USE_AVX2=OFF: Turn off x86 AVX2 optimization, adapt to ARM architecture (RDK S100)
cmake -DMINI_CHEETAH_BUILD=TRUE -DJCQP_USE_AVX2=OFF ..

# Compile (adjust -j parameter according to CPU core count, $(nproc) will automatically detect core count)
make -j$(nproc)

8. RDK S100 Program Execution

8.1 Simulation Mode Execution

cd mc-build
sudo ./user/MIT_Controller/mit_ctrl m s

8.2 Real Robot Mode Execution

cd mc-build
sudo ./user/MIT_Controller/mit_ctrl m r f

9. Advanced: Solving RDK S100 Rear Leg (SPI 0.1) Drive Issue

9.1 Problem Diagnosis

ls /dev/spi*
* `/dev/spidev0.0` (controls front legs)

* `/dev/spidev0.1` (controls rear legs)

9.2 Solution (Ultimate Hardware Modification Version)

9.2.1 Step 1: Install Required Tools

sudo apt-get update

sudo apt-get install -y device-tree-compiler

9.2.2 Step 2: Create Fix Script

nano force_spi_patch.py

9.2.3 Step 3: Copy Script Code

import os

import glob

import subprocess

import sys

# Path to RDK S100 Device Tree files

DTB_DIR = "/boot/hobot"

# The CS1 node to insert (using spidev@1)

# reg = <0x1> corresponds to Chip Select 1

NEW_NODE = """

        spidev@1 {

            compatible = "rohm,dh2228fv";

            reg = <0x1>;

            spi-max-frequency = <0x2faf080>;

        };

"""

def patch_dts_content(content):

    # Check if spidev@1 already exists

    if "spidev@1" in content:

        return None, "Already patched"

    # Find the position of spidev@0

    # We insert spidev@1 immediately before spidev@0 for safety

    target_str = "spidev@0 {"

    if target_str not in content:

        return None, "spidev@0 not found"

    # Replace target string with NEW_NODE + target string

    new_content = content.replace(target_str, NEW_NODE + "\n\t" + target_str)

    return new_content, "Patched"

def main():

    print("=== Starting: Kernel Device Tree Patch ===")

    # 1. Check for dtc tool

    if subprocess.call(["which", "dtc"], stdout=subprocess.DEVNULL) != 0:

        print("Error: dtc tool not found. Please run: sudo apt-get install device-tree-compiler")

        sys.exit(1)

    # 2. Find all dtb files

    dtb_files = glob.glob(os.path.join(DTB_DIR, "rdk-s100*.dtb"))

    if not dtb_files:

        print(f"Error: No .dtb files found in {DTB_DIR}")

        sys.exit(1)

    count = 0

    for dtb_path in dtb_files:

        # Skip files we might have created manually before

        if "-cs1.dtb" in dtb_path:

            continue

        print(f"Processing: {os.path.basename(dtb_path)}")

        # Backup original file

        if not os.path.exists(dtb_path + ".original"):

            os.system(f"sudo cp {dtb_path} {dtb_path}.original")

        # Decompile DTB -> DTS

        dts_path = dtb_path + ".temp.dts"

        cmd_decompile = f"dtc -I dtb -O dts -o {dts_path} {dtb_path}"

        # Run decompile (suppress warnings)

        os.system(f"{cmd_decompile} > /dev/null 2>&1")

        if not os.path.exists(dts_path):

            print("  -> Decompilation failed, skipping")

            continue

        # Read and modify DTS content

        with open(dts_path, 'r') as f:

            content = f.read()

        new_content, status = patch_dts_content(content)

        if new_content:

            with open(dts_path, 'w') as f:

                f.write(new_content)

            # Recompile DTS -> DTB

            cmd_compile = f"dtc -I dts -O dtb -o {dtb_path} {dts_path}"

            if os.system(f"{cmd_compile} > /dev/null 2>&1") == 0:

                print(f"  -> Patch applied successfully!")

                count += 1

            else:

                print(f"  -> Compilation error, file not modified")

        else:

            print(f"  -> {status} (No changes needed)")

        # Clean up temporary file

        if os.path.exists(dts_path):

            os.remove(dts_path)

    print("-" * 30)

    if count > 0:

        print(f"Patch Complete! Modified {count} kernel files.")

        print("Please reboot immediately: sudo reboot")

    else:

        print("No files were modified. Please check if spidev@1 already exists.")

if __name__ == "__main__":

    main()

9.2.4 Step 4: Execute Fix

sudo python3 force_spi_patch.py

9.2.5 Step 5: Reboot and Verify

sudo reboot

ls /dev/spi*

10. Summary


Leave a Reply

Your email address will not be published. Required fields are marked *

Latest Posts