File size: 4,487 Bytes
433d630
 
24d755d
 
 
 
 
 
 
433d630
24d755d
 
 
 
 
 
 
 
 
 
 
3c328d4
24d755d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3c328d4
 
 
24d755d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8f7d403
 
 
 
0f8d4cb
 
8f7d403
 
 
 
 
 
 
 
0f8d4cb
 
 
 
 
 
8f7d403
 
 
 
 
24d755d
 
3c328d4
 
 
 
 
24d755d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
---
license: cc-by-4.0
tags:
  - robotics
  - mlp
  - numpy
  - obstacle-avoidance
  - simulation
pretty_name: Sim Driving MLP (NumPy)
---

# Sim Driving MLP โ€” 279-parameter obstacle-avoidance policy (NumPy)

A deliberately tiny neural network: **4 ultrasonic distances in, one driving command
out.** 279 parameters, float32, trained and verified entirely inside our robot
simulation studio. Small enough to read, small enough to run on an MCU-class device.

**Trained on simulation data from a virtual map โ€” no real-world or customer data.**

## Architecture

![Architecture: 4 โ†’ 16 โ†’ 8 โ†’ 6](assets/01_architecture.png)

| part | meaning |
|------|---------|
| input (4) | ultrasonic distances: **F**ront, **L**eft, **R**ight, **B**ack (normalized with the included `norm_mean` / `norm_std`) |
| output (5 + 1) | 5 command logits โ€” `FWD / LEFT / RIGHT / STOP / BACK` โ€” plus 1 turning-angle regression head |

## Metrics (validation, virtual map)

| metric | value |
|--------|-------|
| command accuracy | **97.2 %** (best epoch 529 / 572) |
| turning-angle MAE | ~6.9ยฐ |

The `.npz` also embeds `meta_json`: the full 572-epoch training history
(per-class accuracy, loss, angle MAE per epoch), so the training curve is inspectable.
The plot below is drawn directly from that embedded history:

![Training history](assets/02_training_curve.png)

## Load and run (NumPy only, no framework)

```python
import numpy as np

d = np.load("sim_driving_mlp.npz")
x = np.array([[120.0, 45.0, 200.0, 300.0]])  # F, L, R, B distances (mm)
x = (x - d["norm_mean"]) / d["norm_std"]

h = np.maximum(x @ d["W0"] + d["b0"], 0)
h = np.maximum(h @ d["W1"] + d["b1"], 0)
y = h @ d["W2"] + d["b2"]

cmd = ["FWD", "LEFT", "RIGHT", "STOP", "BACK"][int(np.argmax(y[0, :5]))]
angle = float(y[0, 5])
print(cmd, angle)
```

## The simulator and the target robot

The studio stage where the model's four inputs are defined: ultrasonic sensors
F/L/R/B with datasheet-based noise models, checked by the built-in self QA/QC
checklist. On the right, the local LLM explains a warning from that checklist,
citing the stage report as its basis.

![Sensor definition stage in the simulation studio](assets/05_sim_studio_sensors.png)

A driving run on the 8 m ร— 8 m virtual map used for data collection
(green: ultrasonic rays from the robot):

![Driving run on the virtual map](assets/06_virtual_map_run.png)

And this exact model running in the studio's 3D evaluation stage. The left panel
shows the live inference at the current step: the four sensor inputs (F/L/R/B, mm),
the softmax over the five commands with FORWARD selected, and the angle head:

![The model driving in the 3D evaluation stage, with live inference panel](assets/07_nn_eval_3d.png)

The target hardware: a tracked test robot with the ultrasonic sensors mounted on
the hand, the same F-channel placement the simulator reproduces.

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

## Where this fits: our 4-layer stack

![NCDTech 4-layer stack](assets/03_four_layer_stack.png)

*(Diagram is in Korean; it is the same figure used on our website, demo video, and
companion dataset.)*

This model is a **layer-2 artifact** of our stack โ€” an edge neural network verified
through the 8-stage physics simulation workflow of our robot simulation studio.
Every stage of that workflow runs self QA/QC (layer 3) and reports through an
on-premise conversational LLM (layer 4); the record formats those layers produce
are shown in our companion dataset:
[NCDTech/human-gated-qaqc-knowledge-example](https://huggingface.co/datasets/NCDTech/human-gated-qaqc-knowledge-example)

## ํ•œ๊ตญ์–ด

**์ดˆ์ŒํŒŒ 4๋ฐฉํ–ฅ ๊ฑฐ๋ฆฌ(์ „ยท์ขŒยท์šฐยทํ›„)๋ฅผ ๋„ฃ์œผ๋ฉด ์ฃผํ–‰ ๋ช…๋ น์ด ๋‚˜์˜ค๋Š” 279 ํŒŒ๋ผ๋ฏธํ„ฐ์งœ๋ฆฌ ์ž‘์€
์‹ ๊ฒฝ๋ง**์ž…๋‹ˆ๋‹ค. ์ €ํฌ ๋กœ๋ด‡ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ์ŠคํŠœ๋””์˜ค์˜ 8๋‹จ๊ณ„ ์›Œํฌํ”Œ๋กœ(๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ โ†’ ํ•™์Šต โ†’
ํ‰๊ฐ€ โ†’ ๋ฌผ๋ฆฌ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ๊ฒ€์ฆ)๋ฅผ ํ†ต๊ณผํ•œ ๊ณ„์ธต 2(์—ฃ์ง€ ์‹ ๊ฒฝ๋ง) ์‚ฐ์ถœ๋ฌผ์ด๋ฉฐ, **๊ฐ€์ƒ ๋งต
์‹œ๋ฎฌ๋ ˆ์ด์…˜ ๋ฐ์ดํ„ฐ๋กœ๋งŒ ํ•™์Šต**ํ–ˆ์Šต๋‹ˆ๋‹ค โ€” ์‹ค๋ฐ์ดํ„ฐยท๊ณ ๊ฐ ๋ฐ์ดํ„ฐ ์—†์Œ.

์ถœ๋ ฅ์€ ์ฃผํ–‰ ๋ช…๋ น 5ํด๋ž˜์Šค(์ „์ง„/์ขŒํšŒ์ „/์šฐํšŒ์ „/์ •์ง€/ํ›„์ง„) + ํšŒ์ „๊ฐ ํšŒ๊ท€ 1๊ฐœ.
๊ฒ€์ฆ ์ •ํ™•๋„ 97.2 %, ๊ฐ๋„ ์˜ค์ฐจ ์•ฝ 6.9ยฐ. ํŒŒ์ผ ์•ˆ์— ์ •๊ทœํ™” ํ†ต๊ณ„์™€ 572 ์—ํฌํฌ ํ•™์Šต
์ด๋ ฅ ์ „์ฒด๊ฐ€ ํ•จ๊ป˜ ๋“ค์–ด ์žˆ์–ด ํ•™์Šต ๊ณก์„ ์„ ๊ทธ๋Œ€๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Learn more: https://huggingface.co/NCDTech ยท https://www.ncdtech.org