File size: 6,606 Bytes
99f6a88
 
58f3fec
 
 
 
 
 
3dd2d0e
 
 
 
58f3fec
99f6a88
58f3fec
3dd2d0e
 
 
 
 
 
 
 
 
58f3fec
fbfb09a
 
 
 
58f3fec
8417503
58f3fec
3dd2d0e
58f3fec
8417503
2d753b1
8417503
 
 
 
 
 
 
 
 
58f3fec
 
 
 
 
 
 
8417503
58f3fec
 
 
 
 
8417503
58f3fec
 
 
 
 
 
 
 
 
8417503
 
 
 
 
 
 
 
 
58f3fec
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8417503
 
 
58f3fec
 
 
8417503
 
 
6c17371
8417503
58f3fec
6c17371
 
 
58f3fec
 
 
 
 
 
 
3dd2d0e
58f3fec
 
 
8417503
58f3fec
fbfb09a
 
58f3fec
 
8417503
 
 
 
3dd2d0e
 
 
 
 
8417503
 
 
 
 
 
 
 
 
 
 
 
 
 
58f3fec
fbfb09a
 
51370a3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
---
license: cc-by-4.0
tags:
  - robotics
  - mlp
  - numpy
  - obstacle-avoidance
  - real-robot
  - edge
  - embedded
  - industrial
  - sensor-data
pretty_name: Real-Robot Driving MLP (NumPy)
---

# Real-Robot Driving MLP: the 101-parameter policy driving our robot's tracks on video

**101 learnable parameters · 2.4 KB file · 0.0073 ms per inference · 1.84 KB peak inference memory · numpy only, no framework.**

Inference numbers measured on a 12th-gen i7 laptop CPU, average over 100,000 runs.

At a 20 Hz control loop that is 0.015 % of the cycle budget: small is the point, not a limitation.

(An earlier revision of this card said 116 parameters. That count included the file's metadata arrays. The learnable weight and bias count is 101.)

Why does a company focused on predictive maintenance publish a robot driving model?

Because this robot is our test bed: the same recipe of tiny numpy networks, measured numbers, and self QA/QC on every stage is what we now focus on the predictive maintenance (PdM) of aging mechanical equipment.

This is the smaller, older sibling of
[NCDTech/sim-driving-mlp-numpy](https://huggingface.co/NCDTech/sim-driving-mlp-numpy).

A 101-parameter MLP trained not in simulation but on real driving sessions of our tracked test robot, collected through our desktop studio.

**This exact file is the one loaded and running in the video below.**

We traced it frame by frame: the load dialog in the recording shows this very filename.

▶ **[Watch it run (3:18, Korean)](https://youtu.be/6DJX0T6qrtM)**: synthetic data check, analysis, training, weight transfer to the robot, and the network driving the tracks, end to end.

One honest detail you will notice: **the robot is propped up in the air.**

The LEGO-built chassis was too fragile for repeated floor runs, so for this NN test the tracks spin freely while the network drives them from live ultrasonic input.

The video's own thumbnail jokes about it ("hehe... right now it's floating!").

## Architecture

![Architecture: 6 → 8 → 5](assets/01_architecture.png)

| part | meaning |
|------|---------|
| input (6) | ultrasonic distances **F**ront / **L**eft / **R**ight, plus their frame-to-frame deltas (ΔF, ΔL, ΔR). Distance tells "how far", delta tells "getting closer or not" |
| hidden (8) | one dense layer, leaky ReLU (α = 0.01) |
| output (5) | command logits: `FWD / LEFT / RIGHT / STOP / BACK` |

Normalization statistics (`norm_center`, `norm_scale`) are included in the file.

## Metrics: an honest early scorecard

| command | accuracy |
|---------|----------|
| FORWARD | 76 % |
| LEFT | 85 % |
| RIGHT | 83 % |
| STOP / BACK | **0 %** |
| overall | 49 % |

We publish these numbers as they are.

The driving commands (F/L/R) worked well enough to drive the tracks in the video.

STOP and BACK scored zero because the training sessions barely contained those actions: class imbalance in a few minutes of real driving data.

Fixing exactly this kind of gap is why our current systems run self QA/QC on every stage.

The class-distribution check that would have flagged this dataset is now built in.

## Load and run (NumPy only)

```python
import numpy as np

d = np.load("real_robot_mlp.npz")
x = np.array([[300.0, 150.0, 400.0, -5.0, -20.0, 0.0]])  # F, L, R, dF, dL, dR
x = (x - d["norm_center"]) / d["norm_scale"]

h = x @ d["W0"] + d["b0"]
h = np.where(h > 0, h, 0.01 * h)          # leaky ReLU
y = h @ d["W1"] + d["b1"]

print(["FWD", "LEFT", "RIGHT", "STOP", "BACK"][int(np.argmax(y))])
```

The whole file is 2.4 KB.

It runs on anything that runs NumPy, and the original target was an MCU-class robot controller.

## The robot it drove

A frame from that video (2:37): the robot propped up on its support, tracks driven by **this network live at the same moment**.

The inference panel on the right shows the softmax over the five commands, and its judgment at this instant is STOP.

![The network driving live: robot on its support, live softmax panel deciding STOP](assets/03_nn_driving_live.png)

The hardware itself, with the ultrasonic sensors on the hand:

![Tracked test robot with hand-mounted ultrasonic sensors](assets/02_real_robot.jpg)

## Sim and real, side by side

| | this model | [sim-driving-mlp-numpy](https://huggingface.co/NCDTech/sim-driving-mlp-numpy) |
|---|---|---|
| trained on | real driving sessions (test floor) | virtual-map simulation |
| inputs | 3 distances + 3 deltas | 4 distances (F/L/R/B) |
| size | 6→8→5, 101 params | 4→16→8→6, 270 params |
| extra head | none | turning-angle regression |
| date | 2026-04 | 2026-05 |

Together they show the path we actually took: drive the real robot first, feel the data problems, then build the simulation studio with self QA/QC wired into every stage.

That same discipline is now focused on predictive maintenance for aging mechanical equipment.

## 한국어

**영상 속에서 실제로 로드되어 돌던 바로 그 가중치 파일**입니다 (영상의 파일 열기 장면에서 파일명을 추적해 확인).

시뮬 모델의 형뻘로, 가상 맵이 아니라 실제 주행 데이터로 학습했습니다.

초음파 3방 거리 + 변화량 3개를 넣으면 주행 명령 5종이 나오는 101 파라미터 신경망(2.4 KB)입니다.

추론 1회 0.0073 ms, 추론 메모리 1.84 KB, 의존성은 numpy 하나 (12세대 i7 노트북 CPU에서 10만 회 평균 실측).

(이전 판의 "116 파라미터"는 파일 속 메타 배열까지 센 수치였고, 학습 가중치 기준 정확한 수는 101입니다.)

정직하게 밝혀둘 것 두 가지.

첫째, 영상의 NN 테스트에서 **로봇은 공중에 떠 있습니다.**

레고 블록 몸체라 하체가 약해 바닥 주행을 반복하기 어려웠고, 그래서 받침 위에 올려 신경망이 궤도(바퀴)를 모는 모습만 보여줍니다.

영상 썸네일도 "후후.. 지금은 공중에 떠 있어요!"라고 먼저 밝히고 있습니다.

둘째, 성적표 그대로: 주행 명령(전진 76%·좌 85%·우 83%)은 잘 동작했지만 **정지/후진은 0%** 입니다.

몇 분짜리 실주행 데이터에 그 동작이 거의 없었기 때문입니다(클래스 불균형).

바로 이런 구멍을 잡으려고 지금의 저희 시스템은 모든 단계에 셀프 QA/QC(클래스 분포 검사 포함)를 심었습니다.

이 로봇은 저희의 테스트베드이고, 같은 기술을 지금은 노후 기계식 설비의 예지보전(PdM)에 집중하고 있습니다.

Learn more: https://huggingface.co/NCDTech · https://ncdtech.org · 주행 영상: https://youtu.be/6DJX0T6qrtM