IQ9 × OpenArm MoveIt Complete Guide
This guide explains how to build a ROS 2 environment on IQ9, an edge AI board based on Qualcomm QCS6490, and control an OpenArm bimanual robot with MoveIt.
> Target audience: developers who are new to IQ9, ROS 2, MoveIt, or OpenArm.
Table of Contents
1. Project Overview and Terminology 2. Install Drivers on the Host PC 3. Download and Flash the OS Image 4. First Boot and Network Setup 5. Install ROS 2 Jazzy 6. Install MoveIt and Required Packages 7. Clone and Build openarm_moveit 8. Configure the CAN Interface 9. Run Simulation with Fake Hardware 10. Connect and Run the Physical Robot 11. Control MoveIt in RViz 12. System Architecture 13. Troubleshooting 14. References
0. Project Overview and Terminology
Goal of this guide
The final goal is to run ROS 2 MoveIt on a IQ9 board and move each joint of the OpenArm bimanual robot through mouse-based interaction in RViz.
You can also follow the guide without a physical robot by using fake hardware mode.
IQ9 → ROS 2 Jazzy → MoveIt → OpenArm
Edge AI controller → Robotics framework → Motion planning → 7-DOF bimanual robot
Key terminology
| Term | Description |
|---|---|
| IQ9 | A single-board computer from Thundercomm. It uses Qualcomm QCS6490 and provides 12 TOPS AI performance. It includes USB, HDMI, Ethernet, a 40-pin connector, Wi-Fi 5, Bluetooth 5.2, and other interfaces. |
| TOPS | Trillion Operations Per Second. This is an AI performance unit. IQ9 provides 12 TOPS through its NPU. |
| OpenArm | An open-source 7-DOF humanoid robot arm developed by Enactic, Inc. The bimanual set is designed for safe human-robot interaction and has high backdrivability. |
| ROS 2 | An open-source robotics middleware framework. “Jazzy” is a ROS 2 distribution aligned with Ubuntu 24.04. |
| MoveIt | A motion planning framework for robot arms that runs on ROS. It calculates collision-free joint trajectories. |
| RViz | A 3D visualization tool for ROS. It can visualize robot models and expose the MoveIt MotionPlanning panel. |
| URDF / xacro | XML-based robot description formats. URDF defines links, joints, visuals, and limits. xacro adds macro support. |
| CAN | Controller Area Network. OpenArm uses CAN FD to communicate with Damiao motors. |
ros2_control | A ROS 2 hardware abstraction framework that exposes real and fake hardware through the same interface. |
colcon | The standard build tool for ROS 2 workspaces. |
IQ9 specifications
| Item | Specification |
|---|---|
| SoC | QCS6490 |
| CPU | Kryo 670 |
| AI / NPU | 12 TOPS |
| GPU | Adreno 643 |
| RAM | 8 GB LPDDR4x |
| Storage | 128 GB UFS 2.2 |
| USB | USB-C ×1, USB-A 3.0 ×2, USB-A 2.0 ×1 |
| Display | HDMI + DisplayPort over USB-C |
| Network | 1000M Ethernet + Wi-Fi 5 |
| GPIO | 28 pins through a 40-pin low-speed connector |
| Bluetooth | Bluetooth 5.2 |
| Size | 100 × 75 mm |
The CPU uses a big.LITTLE configuration: 1 × Cortex-A78 at 2.7 GHz, 3 × Cortex-A78 at 2.4 GHz, and 4 × Cortex-A55 at 1.9 GHz. The board also includes an M.2 Key M 2280 slot with PCIe 3.0 2-lane support for NVMe SSDs.
Required environment
| Item | Requirement |
|---|---|
| OS | Ubuntu 24.04 |
| ROS | ROS 2 Jazzy |
| Board | IQ9 |
| Robot | OpenArm v10 bimanual set, optional for fake hardware simulation |
| Power | 12V 3A USB Type-C power adapter |
1. Install Drivers on the Host PC
> Execution context: Host PC
This step is performed on your desktop or laptop computer. You need the host PC to flash an OS image to IQ9.
Why start from the host PC?
IQ9 stores its OS on internal UFS storage. To flash the OS, connect IQ9 to the host PC by USB and run the flashing tool from the host PC. Install the USB driver (QUD) and flashing tool (Tflash) first.
Required items
1. Host PC: Windows 10 or later, or Ubuntu 18–22 2. USB Type-A to Type-C cable 3. USB Type-A to Micro USB cable for debug UART, optional 4. 12V 3A USB Type-C power adapter
1-1. Install QUD on Windows
1. Download the QUD installer from the official IQ9 documentation: qud.win.1.1_installer_10061.1.zip. 2. Extract the archive and run setup.exe. 3. Select I accept the terms → Next → Install → Finish.
1-2. Install Tflash
Windows
Download TflashSetup_v1.2.0.4.exe and complete the installation wizard.
Ubuntu
sudo dpkg -i Thundercomm-tflash-v1.0.0.deb
tflash # Verify installation
2. Download and Flash the OS Image
> Execution context: Host PC → IQ9 connection
2-1. Select an OS image
| OS | Base | Notes |
|---|---|---|
| Qualcomm Linux | Weston | Lightweight desktop, suitable for low-level development |
| Debian 13 | GNOME 48 | Rich package support and high usability |
| Android 13 | Google AOSP | For Android application development |
> Important: openarm_moveit requires Ubuntu 24.04 + ROS 2 Jazzy. If a native Ubuntu image is unavailable for the target setup, use Debian 13 and install ROS 2 Jazzy on top of it.
2-2. Flash the image
1. Power off IQ9 and connect it to the host PC through USB-C. 2. Enter EDL mode using the board's boot-button sequence described in the official documentation. 3. In Tflash, select the image path and click Flash. 4. Wait for the process to finish. The board should reboot automatically.
Using QDL on Ubuntu or macOS
cd <FlatBuild\_package>/ufs/
./qdl --storage ufs prog\_firehose\_ddr.elf rawprogram\*.xml patch\*.xml
3. First Boot and Network Setup
> Execution context: IQ9 device
3-1. Connect hardware
1. Connect a 12V 3A USB-C power supply. 2. Connect an HDMI monitor. IQ9 supports up to 4K@30Hz. 3. Connect a USB keyboard and mouse. 4. Connect Ethernet to the RJ45 port, or configure Wi-Fi.
3-2. Connect through SSH
The default device name is IQ9.
On IQ9, check the IP address:
ifconfig # Check the IP address
On the host PC, connect through SSH:
ssh root@10.9.5.59 # Replace with the actual IP address
4. Install ROS 2 Jazzy
> Execution context: IQ9 device
> IQ9 Qualcomm Linux images may include ROS 2 Humble by default. However, openarm_moveit requires ROS 2 Jazzy, so install Jazzy separately.
4-1. Configure locale
sudo apt update \&\& sudo apt install -y locales
sudo locale-gen en\_US en\_US.UTF-8
sudo update-locale LC\_ALL=en\_US.UTF-8 LANG=en\_US.UTF-8
export LANG=en\_US.UTF-8
4-2. Add the ROS 2 APT source
sudo apt install -y software-properties-common curl
curl -L -o ros2-apt-source.deb \\
https://github.com/ros-infrastructure/ros-apt-source/releases/download/1.1.0/ros2-apt-source\_1.1.0.noble\_all.deb
sudo dpkg -i ros2-apt-source.deb
4-3. Install ROS 2 Jazzy Desktop
sudo apt update \&\& sudo apt upgrade -y
sudo apt install -y ros-jazzy-desktop
Installation can take 20 minutes to more than an hour depending on network speed.
4-4. Register environment variables
echo "source /opt/ros/jazzy/setup.bash" >> \~/.bashrc
source \~/.bashrc
4-5. Verify installation
ros2 -h # Check that help output appears
ros2 topic list # Check that topic listing works
5. Install MoveIt and Required Packages
> Execution context: IQ9 device
Install MoveIt, planners, controller packages, RViz, xacro, and TF packages.
sudo apt update \&\& sudo apt install -y \\
ros-jazzy-moveit \\
ros-jazzy-moveit-configs-utils \\
ros-jazzy-moveit-kinematics \\
ros-jazzy-moveit-planners \\
ros-jazzy-moveit-planners-ompl \\
ros-jazzy-moveit-planners-chomp \\
ros-jazzy-moveit-planners-stomp \\
ros-jazzy-moveit-ros-move-group \\
ros-jazzy-moveit-ros-visualization \\
ros-jazzy-moveit-ros-planning-interface \\
ros-jazzy-moveit-simple-controller-manager \\
ros-jazzy-trac-ik-kinematics-plugin \\
ros-jazzy-ros2-control \\
ros-jazzy-ros2-controllers \\
ros-jazzy-controller-manager \\
ros-jazzy-joint-state-broadcaster \\
ros-jazzy-joint-trajectory-controller \\
ros-jazzy-forward-command-controller \\
ros-jazzy-gripper-controllers \\
ros-jazzy-robot-state-publisher \\
ros-jazzy-joint-state-publisher \\
ros-jazzy-rviz2 \\
ros-jazzy-xacro \\
ros-jazzy-tf2-ros
Package role summary
| Package | Purpose |
|---|---|
moveit* | Core libraries for automatic robot-arm path planning |
trac-ik | Inverse kinematics solver with a higher success rate than KDL in many cases |
ros2-control* | Common control interface for real and fake motors |
xacro | Macro processor for robot model files |
rviz2 | 3D visualization and MoveIt UI |
6. Clone and Build openarm_moveit
> Execution context: IQ9 device
6-1. Create the workspace and clone the repository
mkdir -p \~/openarm\_moveit/src
cd \~/openarm\_moveit/src
# Important: keep the trailing dot.
# Without it, the repository will be cloned into src/openarm\_moveit/,
# which can cause build-path issues.
git clone https://github.com/XHAKA3456/openarm\_moveit.git .
6-2. Build
cd \~/openarm\_moveit
colcon build
source install/setup.bash
6-3. Register the workspace in .bashrc
echo "source \~/openarm\_moveit/install/setup.bash" >> \~/.bashrc
source \~/.bashrc
If the build fails
sudo rosdep init # Run only once
rosdep update
rosdep install --from-paths src -y --ignore-src -r
colcon build
7. Configure the CAN Interface
> Execution context: IQ9 device > Required only when using a physical robot.
If you only plan to run simulation with use_fake_hardware:=true, skip this section.
| Interface | Connected target | Configuration |
|---|---|---|
can0 | Seven motors on the right arm | CAN FD, 1 Mbps / 5 Mbps |
can1 | Seven motors on the left arm | CAN FD, 1 Mbps / 5 Mbps |
# Use the provided script
cd \~/openarm\_moveit/src
./setup\_can.sh up # Enable CAN interfaces
./setup\_can.sh down # Disable CAN interfaces when finished
# Manual setup
sudo ip link set can0 up type can bitrate 1000000 dbitrate 5000000 fd on
sudo ip link set can1 up type can bitrate 1000000 dbitrate 5000000 fd on
ip link show can0 # Confirm that the interface is UP
candump can0 # Confirm packet reception
8. Run Simulation with Fake Hardware
> Execution context: IQ9 device
echo $ROS\_DISTRO # Confirm that it prints "jazzy"
# Simulation mode
ros2 launch openarm\_bimanual\_moveit\_config demo.launch.py \\
use\_fake\_hardware:=true
RViz should open and display the OpenArm bimanual robot in 3D. The setup is successful if the MotionPlanning panel appears on the left side.
9. Connect and Run the Physical Robot
> Execution context: IQ9 device
Safety checklist
Before running the physical robot:
- Complete every step in the hardware setup guide.
- Set the motor zero positions first.
- Keep the emergency stop button within reach.
- Remove people and obstacles from the robot operating radius.
- Know how to cut power immediately.
# Enable CAN first. See Section 7.
# Physical robot mode
ros2 launch openarm\_bimanual\_moveit\_config demo.launch.py \\
use\_fake\_hardware:=false
Launch parameters
| Parameter | Default | Description |
|---|---|---|
use_fake_hardware | false | true for simulation, false for real hardware |
right_can_interface | can0 | CAN interface for the right arm |
left_can_interface | can1 | CAN interface for the left arm |
arm_type | v10 | Robot arm version |
Control joints from the CLI
Run this command in a separate terminal:
ros2 action send\_goal \\
/joint\_trajectory\_controller/follow\_joint\_trajectory \\
control\_msgs/action/FollowJointTrajectory \\
'{trajectory: {
joint\_names: \["openarm\_joint1","openarm\_joint2","openarm\_joint3",
"openarm\_joint4","openarm\_joint5","openarm\_joint6","openarm\_joint7"],
points: \[{positions: \[0.15,0.15,0.15,0.15,0.15,0.15,0.15],
time\_from\_start: {sec: 3, nanosec: 0}}]}}'
10. Control MoveIt in RViz
1. Confirm that the MotionPlanning panel is visible on the left side of RViz. 2. Select a planning group:
both_arms: both arms, default left_arm: left arm only * right_arm: right arm only 3. Set a target pose:
Drag the interactive marker at the robot end effector. Use the sliders in the Joints tab. * Select a preset in Goal State. 4. Click Plan to preview a collision-free path. 5. Click Execute, or use Plan \& Execute to run planning and execution together.
Planner selection
You can change the planner in the Context tab. OMPL is the default. CHOMP and STOMP may also be available. For general use, RRTConnectkConfigDefault is a practical default choice.
11. System Architecture
┌───────────────────────────────────────────────┐
│ RViz MotionPlanning UI │
│ Drag an Interactive Marker by mouse │
└──────────────────────┬────────────────────────┘
│ Target pose
┌──────────────────────▼────────────────────────┐
│ MoveIt Move Group Node │
│ ┌────────┐ ┌────────┐ ┌──────────────┐ │
│ │ OMPL │ │trac\_ik │ │ Collision │ │
│ │Planner │ │IK │ │ Checking │ │
│ └────────┘ └────────┘ └──────────────┘ │
└──────────────────────┬────────────────────────┘
│ Joint trajectory
┌──────────────────────▼────────────────────────┐
│ ros2\_control Controller Manager │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │JointTrajectory│ │JointState │ │
│ │Controller │ │Broadcaster │ │
│ └──────┬────────┘ └────────┬─────────┘ │
└─────────┼───────────────────┼─────────────────┘
│ │
┌─────────▼───────────────────▼─────────────────┐
│ OpenArm Hardware Interface, CAN-based │
│ ┌──────┐ ┌──────┐ │
│ │ can0 │ │ can1 │ │
│ │Right │ │ Left │ │
│ └──┬───┘ └──┬───┘ │
└─────┼─────────────────────┼────────────────────┘
┌────▼────┐ ┌────▼────┐
│Motors ×7│ │Motors ×7│
└─────────┘ └─────────┘
Key configuration files
| File | Purpose |
|---|---|
openarm_bimanual.srdf | Defines planning groups such as left_arm, right_arm, and both_arms, end effectors, and disabled self-collisions. |
kinematics.yaml | Specifies the inverse kinematics solver. This setup uses trac_ik. |
joint_limits.yaml | Defines maximum joint velocity and acceleration limits. Missing acceleration limits can cause trajectory planning failure. |
moveit_controllers.yaml | Connects MoveIt to ros2_control controllers. |
demo.launch.py | Loads all settings and starts Move Group, RViz, and controllers together. |
Notes on the XHAKA3456 fork
The fork modifies the following items:
urdf.xacro: changes the defaultbimanual=truebehavior.srdf: unifies robot naming and adds theboth_armsgroup.joint_limits.yaml: adds acceleration limits.moveit.rviz: changes the default group toboth_arms.
Gain tuning
Default gains are intentionally low for safety. Edit control_gains.yaml, rebuild with colcon build, and increase gains gradually from low values.
12. Troubleshooting
| Issue | Solution |
|---|---|
| RViz shows a black screen | Set export LIBGL_ALWAYS_SOFTWARE=1 and restart RViz. Alternatively, run RViz on another Ubuntu PC in the same network. |
colcon build cannot find packages | Confirm source /opt/ros/jazzy/setup.bash, then run rosdep install --from-paths src -y --ignore-src -r. |
| CAN interface does not come up | Check `dmesg |
| “No motion plan found” | The target may exceed joint limits or cause self-collision. Increase Planning Time to 5–10 seconds or adjust the target position. |
| Robot arm feels weak or droops | Default gains may be too low. Edit control_gains.yaml, rebuild, and increase gains gradually. |
| Topics are not visible in a multi-machine setup | Make sure ROS_DOMAIN_ID is identical on all machines. Allow DDS ports, usually 7400+, through the firewall. |
Build path issue after git clone | The trailing dot in git clone ... . may have been omitted. Delete the workspace directory and clone again correctly. |
13. References
| Resource | URL | Used for |
|---|---|---|
| IQ9 official documentation | https://www.thundercomm.com/IQ9-pi-3/en/docs/IQ9-pi-3-user-manual/1.1.1/get-started | Specifications, preparation, drivers, flashing, SSH |
| IQ9 GitHub documentation | https://github.com/IQ9-ai/documentation | Source-level documentation |
| IQ9 ROS Guide | https://www.thundercomm.com/IQ9-pi-3/en/docs/IQ9-pi-3-user-manual/1.1.1/ros-user-guide/ | Built-in ROS 2 Humble environment variables |
openarm_moveit | https://github.com/XHAKA3456/openarm_moveit | Environment, dependencies, build, execution, parameters |
| OpenArm GitHub | https://github.com/enactic/openarm | Hardware overview and pricing |
| OpenArm ROS 2 installation guide | https://docs.openarm.dev/software/ros2/install/ | ROS 2 installation and dependencies |
| OpenArm Control | https://docs.openarm.dev/software/ros2/control/ | Safety, bringup, MoveIt, gain tuning |
| ROS 2 Jazzy installation | https://docs.ros.org/en/jazzy/Installation.html | ROS 2 Jazzy installation |