| --- |
| license: cc-by-4.0 |
| tags: |
| - robotics |
| - mlp |
| - numpy |
| - obstacle-avoidance |
| - simulation |
| - edge |
| - embedded |
| - industrial |
| - sensor-data |
| pretty_name: Sim Driving MLP (NumPy) |
| --- |
| |
| # Sim Driving MLP: a 270-parameter obstacle-avoidance policy (NumPy) |
|
|
| **270 learnable parameters ยท 1.05 KB of weights ยท 0.0103 ms per inference ยท 1.95 KB peak inference memory ยท numpy only, no framework.** |
|
|
| Inference numbers measured on a 12th-gen i7 laptop CPU, average over 100,000 runs. |
|
|
| (An earlier revision of this card said 279 parameters. That count included the file's normalization and metadata arrays. The learnable weight and bias count is 270.) |
|
|
| A deliberately tiny neural network: **4 ultrasonic distances in, one driving command out.** |
|
|
| 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 |
|
|
|  |
|
|
| | 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: |
|
|
|  |
|
|
| ## 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. |
|
|
| This screen is a frame from our [demo video (22 min, Korean)](https://youtu.be/ftsw_vbfw6E). |
|
|
|  |
|
|
| A driving run on the 8 m ร 8 m virtual map used for data collection (green: ultrasonic rays from the robot): |
|
|
|  |
|
|
| 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 target hardware: a tracked test robot with the ultrasonic sensors mounted on the hand, the same F-channel placement the simulator reproduces. |
|
|
|  |
|
|
| ## Where this fits: our 4-layer stack |
|
|
|  |
|
|
| *(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) |
|
|
| We now focus this stack on predictive maintenance (PdM) for aging mechanical equipment. |
|
|
| ## ํ๊ตญ์ด |
|
|
| **์ด์ํ 4๋ฐฉํฅ ๊ฑฐ๋ฆฌ(์ ยท์ขยท์ฐยทํ)๋ฅผ ๋ฃ์ผ๋ฉด ์ฃผํ ๋ช
๋ น์ด ๋์ค๋ 270 ํ๋ผ๋ฏธํฐ์ง๋ฆฌ ์์ ์ ๊ฒฝ๋ง**์
๋๋ค. |
|
|
| ์ถ๋ก 1ํ 0.0103 ms, ์ถ๋ก ๋ฉ๋ชจ๋ฆฌ 1.95 KB, ์์กด์ฑ์ numpy ํ๋ (12์ธ๋ i7 ๋
ธํธ๋ถ CPU์์ 10๋ง ํ ํ๊ท ์ค์ธก). |
|
|
| (์ด์ ํ์ "279 ํ๋ผ๋ฏธํฐ"๋ ์ ๊ทํยท๋ฉํ ๋ฐฐ์ด๊น์ง ์ผ ์์น์๊ณ , ํ์ต ๊ฐ์ค์น ๊ธฐ์ค ์ ํํ ์๋ 270์
๋๋ค.) |
|
|
| ์ ํฌ ๋ก๋ด ์๋ฎฌ๋ ์ด์
์คํ๋์ค์ 8๋จ๊ณ ์ํฌํ๋ก(๋ฐ์ดํฐ ์์ง โ ํ์ต โ ํ๊ฐ โ ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ด์
๊ฒ์ฆ)๋ฅผ ํต๊ณผํ ๊ณ์ธต 2(์ฃ์ง ์ ๊ฒฝ๋ง) ์ฐ์ถ๋ฌผ์ด๋ฉฐ, **๊ฐ์ ๋งต ์๋ฎฌ๋ ์ด์
๋ฐ์ดํฐ๋ก๋ง ํ์ต**ํ์ต๋๋ค (์ค๋ฐ์ดํฐยท๊ณ ๊ฐ ๋ฐ์ดํฐ ์์). |
|
|
| ์ถ๋ ฅ์ ์ฃผํ ๋ช
๋ น 5ํด๋์ค(์ ์ง/์ขํ์ /์ฐํ์ /์ ์ง/ํ์ง) + ํ์ ๊ฐ ํ๊ท 1๊ฐ. |
|
|
| ๊ฒ์ฆ ์ ํ๋ 97.2 %, ๊ฐ๋ ์ค์ฐจ ์ฝ 6.9ยฐ. |
|
|
| ํ์ผ ์์ ์ ๊ทํ ํต๊ณ์ 572 ์ํฌํฌ ํ์ต ์ด๋ ฅ ์ ์ฒด๊ฐ ํจ๊ป ๋ค์ด ์์ด ํ์ต ๊ณก์ ์ ๊ทธ๋๋ก ํ์ธํ ์ ์์ต๋๋ค. |
|
|
| ์ ํฌ๋ ์ด ์คํ์ ๋
ธํ ๊ธฐ๊ณ์ ์ค๋น์ ์์ง๋ณด์ (PdM)์ ์ง์คํ๊ณ ์์ต๋๋ค. |
|
|
| Learn more: https://huggingface.co/NCDTech ยท https://ncdtech.org ยท Demo video: https://youtu.be/ftsw_vbfw6E |
| |