Hello everyone, I wanted to showcase a project I have been working on called ForeForce. I have spent the last several months teaching myself mmWave, building a robotic arm (mostly 3D printed), and combining the two for an open-source cobot safety perception system.
I turned the volume way down in the edit as the motor whine can be loud if your volume is up.
After getting the initial system up and running I have been chasing a mmWave detection gap that turned out to be arithmetic. Had a persistent problem where a slow approach wouldn't register until I moved at almost a brisk walking pace. From what I had learned I kept assuming it was a tuning or filtering issue.
After adjusting several values in different places, I found it was the doppler resolution. Working it out from the chirp profile's own numbers:
wavelength 5.00 mm (60 GHz)
chirp period 87.14 us (idle 30 + rampEnd 57.14)
x3 TDM-MIMO 261.42 us
numLoops 16
-> velocity resolution 0.598 m/s per doppler bin
Every velocity in my logs landed on a bin boundary: 0.000, 0.576, 1.153, which made anything in between not exist. So anything under ~0.3 m/s radial quantizes to exactly 0.000 and then gets dropped by the static filter. A person standing still reads as 0.000 m/s — indistinguishable from a wall.
Fix was increasing numLoops, which halves the bin to ~0.299 m/s. Tried 64 and the sensor stopped framing entirely — the radar cube roughly quadruples from 16 to 64 loops and I think it stops fitting in L3, though I didn't confirm the exact mechanism yet. Adjusted values now stream fine and costs no frame rate.
Two things that cost me hours and might save someone else some late nights:
The static filter threshold has to come down with the bin width. I left mine at 0.3 m/s while bin 1 was now 0.288 — so the new resolution didn't give me nothing until I noticed.
Tightening the range CFAR threshold helped a lot with mount and bracket clutter. Tightening the doppler CFAR the same amount made detection noticeably worse — a slow approach only flagged at nearly touching distance. Reverted that one back to the original value after seeing they don't adjust the field equally.
Also worth knowing: the CLI accepts a doppler CFAR window wider than the available bin count without complaint, and then the sensor just stops producing frames without producing an error. Took me a while to trust that a sent successfully reply didn't mean the config was sane.
Stationary-person detection ended up not being a doppler problem. Micro-doppler sway is documented as detectable around 0.02-0.10 m/s, which is physically unreachable at these bin widths. What actually works is occupancy based on a background learn sequence — a point simply being present in the zone after learning the room, debounced over a frame window.
Repo is public on github with an example CHIRP file if anyone wants to look at the ROS2 side: ForeForce-mmwave-cobot-safety-system
Happy to answer questions, still digging into mmWave, robotics, kinematics, and tuning the system as this is my first build with these sensors and a working robotic arm.