The document discusses efforts to develop ROS drivers for a Xiaomi robotic vacuum cleaner by gaining access to the robot's hardware and software, installing ROS on the limited storage system, attempting to monitor the communication between sensors and processors, and eventually being able to read lidar data and visualize it in ROS/RVIZ. Future work proposed includes developing drivers for other peripherals by further analyzing the communication protocols and potentially modifying firmware.
1. Generating ROS drivers for
Hacked Gen 1 Xiaomi Mi
All Traces Complete
Group 7: Neil Dave
Spencer Pozder
John Tan
Paul Terrasi
GitLab Link: https://gitlab.com/EECE-5698-Group-7
2. Project Overview
• Root & create ROS drivers to control Xiaomi Vacuum
• 4GB total storage
• High processing power (3 dedicated ARM processors)
• Multitude of sensors to work with
• Runs onboard SLAM using player
3. Hardware Teardown - Motherboard
• Only 2 processors present:
• R16 Application Processor
• Quad Core, performs slam
• STM Peripheral Processor
• Sensor Handler, relays info
between R16 & sensors
• Connector Breakouts for:
• Lidar
• 2 Wheels + Encoders
• 4 cliff sensors
• Main & Side Brush Motors
• No connector breakouts for:
• R16 - STM comm/prog
• Flash storage
4. Accessing Hardware & Getting WiFi
1. Connect to robot Wi-Fi (wlan0)
2. Download & build encrypted firmware (with English language packages)
written by Dennis Giese and assign SSH key
3. SSHed into robot over wlan0
4. Wrote script to bring up 2nd wireless interface (wlan1), connect robot to
router/hotspot, and request an IP address with dhclient
5. Install packages & dependencies to robot over Wi-Fi
Adding key and re-encrypting firmware
We in!
5. Installing ROS
• Limited Space in root partition (246 Mb)
• Barebones ROS requires at least 400 Mb
• More space in /mnt/data partition (1.4 Gb)
• Attempted to Symlink root dirs /var/cache/apt and
/var/lib/apt to /mnt/data to increase space
• Frees up 150 Mb (enough room for ROS but not
dependencies required to complete installation)
• Attempted to Install ROS from source
• ros_comm more lightweight than ros_base, but
compiler dependencies took too much space
• Ideally we can resize partitions on firmware image
• Beyond scope of project
• Current solution is to copy most of root partition onto
the /mnt/data partition, then use chroot to install ROS
• Once complete, we edit PYTHONPATH to search for
modules on the /mnt/data partition, so that ROS
can be run without using chroot
6. Communicating with Sensors and Motor
• Application processor communicates with
sensors/motors over UART through STM32
• Uses proprietary protocol to send/receive data
• Initial plan: monitor uart_test program to
observe and reverse engineer protocol
structure
• Attempt 1: Using uart_test’s option to output raw
MCU data
• This seemed to be omitting some of the header
and setup data that it was sending
• We eventually found the byte that
corresponded to the wall sensor reading
• Attempt 2: Using socat to intercept the UART data
sent and received by uart_test
• Able to see some data written to UART, but for
some data packets, we couldn’t discern if they
were being read or written
uart_test raw output
socat output - first line shows output from uart_test,
couldn’t tell if rest is read or written
7. Attempt to Monitor uart_test - Software
• Attempt 3: Using strace to monitor uart_test’s syscalls
• We were able to see the packets that uart_test sent over UART, which matched what
we saw using socat
• Uart_test never read from the serial port, but it mmap’d the file /dev/uart_mcu, which
led us to believe that it might be getting the UART data from there
• Attempt 4: Reading from memory space at /dev/uart_mcu
• We noticed that a few bytes before the wall sensor data in the packet almost never
changed, so we searched for those bytes and obstructed the wall sensor to verify that
the data was correct
• Very slow due to search - packets varied in size, so we could not consistently jump from
one wall sensor reading to the next
strace output - packet written matches data
seen in socat
Wall sensor byte location from raw uart_test
output
8. Hardware Teardown - Lidar (3rd Processor)
• Couldn’t find Lidar handling processor on motherboard.
• Decided to look into lidar independently to create lidar drivers (data should come on separate
bus than STM data)
• Opened top of module & found lidar MCU actually present in rotating enclosure
• Lidar Module uses 6 pin connector to connect to Robot (4 Visible wires on Lidar)
• Initial assumption: Wires correspond to module V+, V-, TX, RX,
• Probe TX, RX to sniff lidar Data
Untouched lidar module
Opened module w/MCU exposed
9. Lidar: Initial Assumption == False!
• Module can be separated into 2 boards: Lidar PCB & Relay PCB
• Lidar PCB contains Piccolo MCU
• Relay PCB connects directly to robot, contains photodiode
• Relay PCB powers up coil to wirelessly induce lidar power through coil
attached to lidar PCB
• Lidar PCB wirelessly transmits data by pulsing output MCU UART over
LED to photodiode
• This means wireless communication 1 way!
• Assumption 2: Less likely that Xiaomi customized data packet
format out of lidar MCU. Nothing transmitted upstream to
standard Piccolo LiDar handling MCU. Should be easier to find
library to interpret packet structure!
Wait, what? No wires
through slip ring?
LED from lidar module (left)
Photodiode (right)
10. Lidar Assumption 2 == True: Reading Data over Arduino
• Found python visualization library for Piccolo enabled lidar using VPython
• Connected lidar to Arduino Mega to parse UART output from photodiode into Arduino
serial pin.
• Arduino COM port can be subscribed to over python (serves as Lidar UART to USB adapter)
• When still lidar only outputs heartbeat (lidar board @ .6V)
• When motor active, rotating coil generates full power and module outputs data
Lidar output when lidar motor inactive obtained with Saleae Logic Analyzer
Lidar output when lidar motor active obtained with Saleae Logic Analyzer
11. Lidar: Arduino + Viz in action
Lidar Demo through ArduinoLidar needs spin to generate data
12. Lidar - Working with ROS and rviz
• ROS Lidar Driver running on vacuum
• Existing driver almost worked correctly:
https://github.com/rohbotics/xv_11_laser_driver
• Changed to allow for inconsistent connection
• ROS Core running on external machine
• rviz running on external machine
• Allowed for real-time data visualization
• No speed reduction from arduino or file i/o
13. Lidar - Data Consistency
• Largest issue with Lidar was inconsistent data
• Mostly invalid readings (~12 good angles out of 360)
• Occasionally a good reading (~256 good angles out of 360)
• The fix: applying resistance to Lidar’s rotation!
• Consistent readings (360/360 angles)
• Real-time data
• Possibly increases current through inductive coil that powers lidar sensor
14. Future work - Hardware
• Currently soldered to test points on main PCB
• Correspond to 2 UARTS and potentially an I2C
breakout
• If possible solder to known buses on IC’s to quantify
behavior over BUS & send commands upstream to
determine UART (using logic analyzer)
• Potentially send new STM32 firmware upstream to
write our own UART protocol
15. Future Work - Drivers
• Create drivers for peripherals relayed
through STM32 (motors & sensors)
• Involves reverse engineering UART protocol
between STM32 and application processor
or flashing STM32 with altered firmware
with a a documented UART protocol
• SLAM?
Sensor/Control
Driver
Acc Topic
Gyro
Topic
...
Movement
Topic
STM
Serial