投入口でのゴミ分別 — デプロイガイド

プリセット

Camera + reComputer J30 / J40 (Orin)

The Jetson Orin runs the classifier on TensorRT and serves the web page, the trigger endpoint and MQTT output. The first deployment builds the TensorRT engine on the device. Open-vocabulary classification (Step 4) is optional; switch to it after the baseline works.

  • Camera: a USB or IP camera looking down into the drop area, one item per shot.
  • Optional peripherals: a physical button as a trigger source; a flap, relay or indicator driven by the actuator callback. Wiring and the GPIO read are your own integration work.

Limitations:

  • The Chinese four-way mapping is maintained by this project and municipal definitions differ between cities. Do not use the output as the sole basis for a charging, penalty or compliance decision.
  • One item per frame. Two items in one frame produce one result.
  • textile has no training data and is not recognized; hazardous (有害垃圾) is never emitted.
  • The training data is photos of single clean items. Accuracy drops on wet, crushed, stacked or bagged waste; verify with data from your own site.
1

Deploy Waste Sorting

Fill in the device, camera and classifier options. The step downloads the model, builds the engine, and starts the classifier with a local MQTT broker. The first start waits for the engine build to finish.

前提条件
  • A Jetson Orin on JetPack 6.x with the NVIDIA container runtime configured.
  • At least 10 GB of free disk.
  • For a USB camera, uncomment the matching /dev/videoN line in assets/jetson/docker-compose.yml. Do not mount all of /dev.
  • The container image is built on the device from the upstream repository; retag it to the name in the compose file or set WASTE_IMAGE to your local tag.
  • Classifier option: baseline by default; for open_vocab see Step 4.
トラブルシューティング
SymptomAction
This target is not a NVIDIA JetsonThe target is not a Jetson. Use a Jetson Orin.
trtexec not foundRun sudo apt install tensorrt.
WARNING: nvidia runtime missingRun sudo nvidia-ctk runtime configure --runtime=docker && sudo systemctl restart docker, then redeploy.
Engine build fails with Static model does not take explicit shapesRemove the --minShapes/--optShapes/--maxShapes flags.
sha256 mismatch on the ONNXThe file is not the released one; do not proceed. Delete the ONNX on the device and redeploy to download it again.
docker compose not foundInstall docker-compose-plugin by hand.
Compose fails parsing ._docker-compose.ymlRun find … -name '._*' -delete on the device to remove the files copied from a Mac.
Container starts, no cameraUncomment the /dev/videoN line in the compose file.
edge-waste-mosquitto restart-loops with Address in useAnother broker holds 1883. Change config/mosquitto.conf and config/config.json's mqtt.port to a free port (e.g. 18831) and run docker compose up -d --force-recreate mosquitto.
デプロイ方法

Deploy over SSH from this machine to the Orin. Enter the device IP, SSH credentials, camera address and classifier option.

入力が必要な項目(SenseCraft Solution アプリで入力)
  • Jetson IP*
  • SSH Username*既定値 recomputer

    Common defaults: recomputer (Seeed reComputer J30 / J40 series), nvidia, or ubuntu.

  • SSH Password*
  • Device Name*既定値 orin-nx

    First segment of the MQTT topic — name this device after the bin or the drop-off point so several installations stay separable on one broker

  • Stream ID*既定値 bin1-cam1

    Appended to the MQTT topic so several cameras on one box stay separable. It is also in the payload — consumers must read it there, not parse the topic.

  • Camera Type*既定値 usb
    3 件の選択肢
    • · USB camera (/dev/videoN)
    • · IP camera (RTSP URL)
    • · Video file — for bench testing without a camera
  • Camera Address*

    For a USB camera also uncomment the matching /dev/videoN line in assets/jetson/docker-compose.yml — the container sees no video node otherwise. Never mount all of /dev.

  • Classifier Track*既定値 baseline
    2 件の選択肢
    • · Baseline EfficientNet-Lite0 (m1c) — higher top-1, 13.5 MB, the default
    • · Open-vocabulary SigLIP 2 — better calibrated, adds classes without retraining, 372 MB, no timing on any board

    baseline is the closed-set EfficientNet-Lite0 head (m1c): higher top-1 on this taxonomy than open_vocab (0.8877 vs 0.8501 on the same val split) and roughly 4-5x faster on CPU (no Jetson TensorRT figure exists for either track). The prior baseline, MobileNetV3-Small (m1b), was superseded because it collapsed under INT8 quantisation on every edge chain tested (Hailo, RK3576, RK3588) -- see the solution page. open_vocab is the SigLIP 2 vision tower scored against text prototypes: better calibrated, able to score open-set rejection and to answer in either language, and able to add a class without retraining — but 372 MB, never engine-built on any board, and no Jetson latency figure exists for it. Neither track has been measured on hardware.

  • Trigger Sources*既定値 http
    4 件の選択肢
    • · HTTP only — POST /trigger
    • · HTTP + physical button
    • · HTTP + motion in frame
    • · All three

    Which sources fire a capture. HTTP is POST /trigger on port 8080 and is the only one this deployment can exercise by itself; button and motion need wiring or a framed scene.

  • Trigger Debounce (ms)*既定値 800

    A trigger arriving within this window of the previous one is merged into the in-flight request, not queued. Below roughly 300 ms a bouncing button will fire twice per press.

  • Minimum Confidence*既定値 0.5

    Below this the event carries rules.fallback_category (residual) instead of the argmax. On the val set 4.5% of images fall below 0.5 for the baseline track; raising it sends more items to the residual bin rather than guessing.

2

Watch the Live Classification

Opens the device's own page with the live view, a trigger button and recent classifications. Use it to aim the camera before verification.

トラブルシューティング
SymptomAction
Page does not loadRun docker ps on the device to confirm the waste container is up; check docker logs edge-waste-app.
Preview is blackFor a USB camera check that /dev/videoN is mounted into the container; for RTSP test the URL in VLC first.
Preview works, /events stays emptyNothing has triggered yet. By default the runtime classifies only on a trigger.
Item is tiny in the frameRe-aim so the item fills most of the frame.
3

Wire the Trigger and Confirm One Classification

Put an item under the camera, fire one trigger, and confirm one classification result arrives on MQTT.

前提条件
  • Step 1 finished and the container running.
  • mosquitto_sub on a machine on the same network, or use the broker container: docker exec edge-waste-mosquitto mosquitto_sub ….
  • One item to classify that is not textile.
トラブルシューティング
SymptomAction
No message at allCheck the trigger counter in /healthz; if it does not move, check trigger.sources in config/config.json.
Two messages per button pressRaise trigger.debounce_ms to at least about 300 ms.
Category is always residualConfidence is below rules.min_confidence. Check the lighting, the framing, and whether the item belongs to one of the eight classes.
Glass and plastic confusedBoth map to 可回收物, so the four-way result is unaffected.
Most items come back organicImprove framing and lighting; a full fix needs a rebalanced retrain.
Textile item classified as something elseKnown limitation: textile has no training data.
Item is not household wasteThe baseline cannot reject out-of-vocabulary items; switch to Step 4 if you need that.
デプロイ後

The classifier is running and one classification has completed end to end.

Quick verification

  1. Open http://<device-ip>:8080/ and confirm the view covers the drop area with the item filling most of the frame.
  2. Subscribe: mosquitto_sub -h <device-ip> -t '<device-name>/waste/+/results' -v.
  3. Fire one trigger: curl -X POST http://<device-ip>:8080/trigger.
  4. Confirm one message arrives and category matches top3[0].
  5. Fire two triggers within 800 ms and confirm you still get one message.

The MQTT message

Each classification publishes one JSON record. Main fields below; read stream_id from the payload rather than parsing the topic:

{
  "type": "waste_sorting_result",
  "stream_id": "bin1-cam1",
  "timestamp": 1757030400123,
  "trigger": "button",
  "category": {
    "class_name": "plastic",
    "china_category": "recyclable",
    "china_category_zh": "可回收物"
  },
  "confidence": 0.913,
  "top3": [
    {"rank": 0, "class_name": "plastic", "confidence": 0.913, "china_category": "recyclable"},
    {"rank": 1, "class_name": "glass", "confidence": 0.052, "china_category": "recyclable"},
    {"rank": 2, "class_name": "residual", "confidence": 0.021, "china_category": "residual"}
  ],
  "image_ref": {
    "kind": "local",
    "uri": "/var/lib/edge-waste-sorting/captures/2026-09-05/bin1-cam1-4207.jpg"
  },
  "model": {"name": "efficientnet_lite0_waste8", "accelerator": "tensorrt"}
}

Next steps

  • For a flap or indicator, set "actuator": {"enabled": true, "min_confidence": 0.5} and write the integration code.
  • Before production use, point MQTT at a broker with credentials. The bundled broker allows anonymous connections and is for commissioning only.
  • To reject out-of-vocabulary items or add classes without retraining, see Step 4.
  • Collect data from your site to verify accuracy.
4

Switch to Open-Vocabulary Classification (Optional)

Switches to the SigLIP 2 open-vocabulary classifier: it can reject out-of-vocabulary items, answer in Chinese or English, and add classes without retraining, at the cost of lower top-1 accuracy and higher latency.

前提条件
  • Step 1 working with model_track: baseline.
  • About 372 MB extra for the vision model, plus space for its engine.
  • The prototype bank and its meta file copied onto the device by hand and verified with sha256sum -c against assets/models/SHA256SUMS.open_vocab.
  • Orin preset only.
トラブルシューティング
SymptomAction
Engine build takes far longer than the baseline'sExpected. Do not stop it early.
Engine build fails with Static model does not take explicit shapesRemove the --minShapes/--optShapes/--maxShapes flags.
Latency is much higherExpected. If it is not acceptable, switch back to baseline.
Confidences all look differentAfter changing temperature, retune min_confidence; the calibrated value is 0.0075.
Four-way accuracy dropped after switching to a Chinese four-way bankUse the hierarchical path: classify eight classes, then map to four.
Unknown objects still get a confident material labelRejection is weak on the residual class; known limitation.