Project Info
Inspiration
Today's robots are brilliant at perceiving a scene and amnesiac about it a second later. A vision model can tell you "that's a mug," but it can't be taught "this is my mug" without retraining, and it has no memory of where it saw things. We wanted to build the missing piece for physical AI: a memory layer, instant, teachable, and spatial, that sits between a robot's eyes and its actions. The north-star question we kept asking: "Would a real robotics team actually use this?"
What it does
Engram gives a Booster K1 humanoid a cloud brain and instant memory: Perceives with a 72-billion-parameter vision model (Qwen2.5-VL) running on Nebius GPUs. It captions whatever the robot's camera sees. Remembers every object as a vector in Redis, with sub-2 ms nearest-neighbor recall over its whole memory bank. Learns in one shot. Show it a brand-new object it's never seen, teach it once (one vector written to Redis), and it recognizes it instantly. No retraining. Recognizes and attends. It turns its head to look at the object it recalls, tracking the object's position continuously. Has spatial memory. Walk it through a scene and it captures every object and the heading where it saw it. Fetches on command. Say "go to the red soda can" and it first checks whether it even remembers one, recalls where it was, walks toward it (closed-loop on odometry), stops at a safe distance using the robot's depth camera so it doesn't crash into the table, faces it, and waves. You can watch the robot's-eye view and its live decision (recalled object, confidence, Redis search latency, the Nebius model) on a real-time dashboard.
How we built it
Architecture, a thin robot plus a cloud brain: Perception (Nebius Token Factory): OpenAI-compatible API. Qwen/Qwen2.5-VL-72B-Instruct turns a camera frame into a short caption; Qwen/Qwen3-Embedding-8B turns the caption into a 4096-d vector. One VLM call also returns the object's horizontal center for tracking. Memory (Redis Stack): a FLAT cosine vector index over the embeddings, plus numeric fields storing the robot's pose (x, y, θ) where each object was seen. KNN recall runs in ~2 ms over a 124-object bank. A text query ("is the green bottle here?") embeds and searches the same index. Robot (Booster K1): ROS2 Humble + booster_robotics_sdk_python. RGB from /booster_video_stream, metric depth from /StereoNetNode/stereonet_depth (mono16, millimeters), odometry, and high-level motion (RotateHead, Move, WaveHand). Closed-loop locomotion: turns and walks are odometry-feedback controlled (we calibrated a slip factor because the K1's odometry over-reports rotation ~1.4× from foot slip), so "turn 180°" actually turns 180°. Depth-gated safe approach: during the final walk, we sample the nearest obstacle in the depth image and stop the robot a safe distance from the object before it can hit the table. Robust recognition: an object captured from several angles gets several captions, so we match the live view to the target by semantic similarity, not exact strings. Live demo dashboard: the brain serves an HTML/JS page showing the robot's view, the recalled label + confidence, a gaze marker, the Redis search latency, and the Nebius model, the "decision on screen." Laptop ↔ robot connected over Tailscale so the robot can be untethered.
Challenges we ran into
Laptop ↔ robot connected over Tailscale so the robot can be untethered. Challenges we ran into Firmware reality: the robot's SDK build didn't implement the Cartesian arm-control API (returned 501 Not Implemented), so our planned "point at it" pivoted to a head-look + walk-up + wave that the firmware does support. Firmware reality: the robot's SDK build didn't implement the Cartesian arm-control API (returned 501 Not Implemented), so our planned "point at it" pivoted to a head-look + walk-up + wave that the firmware does support. Odometry slip: open-loop turns were wildly inaccurate; we switched to closed-loop odometry feedback and calibrated the rotation scale so turns land on target. Odometry slip: open-loop turns were wildly inaccurate; we switched to closed-loop odometry feedback and calibrated the rotation scale so turns land on target. Depth that reads the wrong thing: a naive center-of-frame depth sample looked over the table at the far wall, so the robot didn't stop. We moved to a nearest-obstacle sample over a wider, lower band. Depth that reads the wrong thing: a naive center-of-frame depth sample looked over the table at the far wall, so the robot didn't stop. We moved to a nearest-obstacle sample over a wider, lower band. One object, many captions: the same object captioned differently from different angles broke exact-label matching during approach, fixed with semantic matching. One object, many captions: the same object captioned differently from different angles broke exact-label matching during approach, fixed with semantic matching. Networking gauntlet: captive portals, a flaky Ethernet link, and hotspot/Tailscale relays. We ended up on Tailscale so the robot could roam. Networking gauntlet: captive portals, a flaky Ethernet link, and hotspot/Tailscale relays. We ended up on Tailscale so the robot could roam. Staging perception: the VLM captions the dominant object, so objects have to fill enough of the frame, a real lesson in demo design.
Accomplishments we're proud of
Staging perception: the VLM captions the dominant object, so objects have to fill enough of the frame, a real lesson in demo design. Accomplishments that we're proud of One-shot live learning that actually works. Teach a brand-new object once and it's known instantly. A vision model alone can't do this. One-shot live learning that actually works. Teach a brand-new object once and it's known instantly. A vision model alone can't do this. A genuinely large model, 72B parameters, running in the live robot loop on Nebius, not a toy API call. A genuinely large model, 72B parameters, running in the live robot loop on Nebius, not a toy API call. Sub-2 ms memory recall in Redis over the whole object bank. Sub-2 ms memory recall in Redis over the whole object bank. A full spatial fetch: check memory, recall heading, walk, depth-safe stop, wave, built and tuned on real hardware in a single hack. A full spatial fetch: check memory, recall heading, walk, depth-safe stop, wave, built and tuned on real hardware in a single hack. Closed-loop humanoid navigation calibrated from scratch in hours.
What we learned
Closed-loop humanoid navigation calibrated from scratch in hours. What we learned Caption → embed → vector store is a remarkably robust, nearly-free perception path; it matches on caption consistency more than accuracy. Caption → embed → vector store is a remarkably robust, nearly-free perception path; it matches on caption consistency more than accuracy. Closed-loop beats open-loop for everything on a real robot. Trust the sensor, not the command. Closed-loop beats open-loop for everything on a real robot. Trust the sensor, not the command. Depth needs careful region sampling. "What's directly ahead of me" is not "the median of the center of the image." Depth needs careful region sampling. "What's directly ahead of me" is not "the median of the center of the image." The memory layer is the differentiator: perception is a commodity; a teachable, instant, spatial memory is what makes a robot feel like it understands its space.
What's next
The memory layer is the differentiator: perception is a commodity; a teachable, instant, spatial memory is what makes a robot feel like it understands its space. What's next for Engram Image embeddings (Path B): CLIP-style image vectors on a Nebius GPU to tell lookalikes apart (two similar cans). Image embeddings (Path B): CLIP-style image vectors on a Nebius GPU to tell lookalikes apart (two similar cans). Brain on the robot: run the whole pipeline on the K1's onboard Jetson for full autonomy, untethered. Brain on the robot: run the whole pipeline on the K1's onboard Jetson for full autonomy, untethered. True spatial navigation / SLAM: persistent maps so it can be walked through a building and sent anywhere. True spatial navigation / SLAM: persistent maps so it can be walked through a building and sent anywhere. Depth for 3D grasping: use the RGBD stream to reach and pick, not just point. Depth for 3D grasping: use the RGBD stream to reach and pick, not just point. Scale the memory: thousands of objects, still sub-ms. Scale the memory: thousands of objects, still sub-ms.
Engram — the memory layer for physical AI
A Booster K1 humanoid with a cloud brain and instant memory. It perceives with a 72B vision model on Nebius, remembers objects as vectors in Redis, can be taught a new object in one shot, and walks to recall it — checking memory, navigating to where it saw the object, stopping a safe distance away using its depth camera, then waving.
Built at the AI Berkeley Hackathon 2026 (Ultimate Bots — Physical AI Hack). Targets the Nebius (best use of compute) and Redis (best use) prize tracks.
How it works
robot camera → laptop brain (Nebius VLM caption → Qwen embedding → Redis vector KNN) → robot acts (head-look / walk / wave)
- Perception:
Qwen/Qwen2.5-VL-72B-Instruct+Qwen/Qwen3-Embedding-8Bon Nebius Token Factory (OpenAI-compatible API). - Memory: Redis Stack vector index (cosine KNN, ~2 ms), storing each object's caption embedding + the robot pose where it was seen.
- One-shot learning: teach a new object live; one vector written; recognized instantly.
- Spatial fetch: scan a scene → "go to the X" → check memory → walk (closed-loop odometry) → depth-safe stop → wave.
- Robot: Booster K1, ROS2 Humble, RGB + stereo depth, odometry, RotateHead/Move/WaveHand.
Key files
| file | what |
|---|---|
engram_pipeline.py | perception + Redis vector memory (brain core) |
engram_server.py | HTTP brain + live dashboard (localhost:8000/) |
k1_fetch.py | robot-side spatial fetch (--scan / --goto) |
k1_locomotion.py | odometry-feedback walking + turning |
k1_engram.py, k1_indicate.py | recognition + head-tracking loop |
preload_bank.py | pre-load a memory bank (Redis scale demo) |
DEMO_RUNBOOK.md, DEVPOST_SUBMISSION.md | how to run / writeup |
Run (short)
Brain (laptop): export NEBIUS_API_KEY=... && python engram_server.py (needs Redis Stack; dashboard at :8000).
Robot: python3 k1_fetch.py --reset && python3 k1_fetch.py --scan && python3 k1_fetch.py --goto "red soda can"
Work in progress — full code + demo video coming.
Analysis
View
Metric
No commits on this project resolved to a GitHub account.
Technology
- PythonIn code
- JavaScriptClaimed
- RedisClaimed
1 of 3 appear in the indexed code. 2 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
- Claude CodeCommits
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
101 KB
Source files
18
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
A-Mundanilkunathil/engram
19 files · 102 KB · @ f815a37
Structure
Application logic
15 files · 79%Domain rules, services and shared utilities.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- Python86%
- Markdown14%
Share of indexed source by file size. Binary and vendored files are excluded.
Feature verification
72B Nebius VLM captioning (Qwen2.5-VL-72B)Verified
Perceives with a 72-billion-parameter vision model (Qwen2.5-VL) running on Nebius GPUs to caption camera frames
Claimed on Devposthigh confidenceengram_pipeline.py:43— VLM_MODEL set to Qwen/Qwen2.5-VL-72B-Instructengram_pipeline.py:76— caption_image() calls Nebius chat.completions with the VLM model and an image payloadengram_pipeline.py:42— NEBIUS_BASE_URL points at Nebius Token Factory endpoint
Booster K1 SDK integration (ROS2 Humble + booster_robotics_sdk_python)Verified
Robot: Booster K1, ROS2 Humble + booster_robotics_sdk_python, RGB + stereo depth, odometry, high-level motion (RotateHead, Move, WaveHand)
Claimed on readmehigh confidencek1_locomotion.py:21— imports ChannelFactory, B1LocoClient, B1OdometerStateSubscriber, RobotMode from booster_robotics_sdk_python and uses Move/ChangeModek1_indicate.py:55— uses client.RotateHead and client.WaveHand from the SDK
Closed-loop odometry-feedback locomotion with slip calibration (~1.4x)Verified
Closed-loop locomotion: turns and walks are odometry-feedback controlled; calibrated a slip factor because K1's odometry over-reports rotation ~1.4x
Claimed on Devposthigh confidencek1_locomotion.py:28— TURN_SCALE = 1.4 slip-correction constantk1_locomotion.py:64— turn_by() loops commanding motion until measured odometry (self.theta) reaches target, i.e. closed-loopk1_locomotion.py:86— walk_forward() loops until measured (x,y) odometry displacement reaches target distance
Depth camera source: /StereoNetNode/stereonet_depth mono16 mmVerified
Metric depth from /StereoNetNode/stereonet_depth (mono16, millimeters)
Claimed on readmehigh confidencek1_fetch.py:47— DEPTH_TOPIC constant matches the claimed topic, subscribed as Image with mono16 encoding check in _d()
Depth-gated safe approach using nearest-obstacle samplingVerified
During the final walk, samples the nearest obstacle in the depth image and stops a safe distance before hitting the table
Claimed on Devposthigh confidencek1_fetch.py:96— front_distance_mm() takes a low percentile (nearest, not median) over a wide central depth region, explicitly to avoid the far-background problemk1_fetch.py:183— goto() stops the approach loop once dist < stop_mm
Fetch on command: check memory, walk closed-loop, depth-safe stop, face, waveVerified
Say "go to the red soda can": checks memory, recalls where it was, walks toward it closed-loop on odometry, stops at safe distance via depth camera, faces it, waves
Claimed on Devposthigh confidencek1_fetch.py:146— goto() queries /query for memory, turns to remembered heading, then loops walking forward while checking depth-based front_distance_mm() for a safe stopk1_fetch.py:183— stops when nearest obstacle distance is below stop_mm thresholdk1_fetch.py:208— calls wave(loco) after facing the target
Head-look tracking toward recalled objectVerified
It turns its head to look at the object it recalls, tracking the object's position continuously
Claimed on Devposthigh confidencek1_indicate.py:47— indicate() maps center_x to a continuous head yaw and calls RotateHeadk1_engram.py:121— --loop mode calls pointer.indicate(center_x=cx) continuously for head tracking
Laptop <-> robot connected over Tailscale, untetheredVerified
Laptop and robot connected over Tailscale so the robot can be untethered
Claimed on Devposthigh confidencek1_engram.py:5— BRAIN default URL is documented as the laptop's Tailscale IPDEMO_RUNBOOK.md:19— robot reachable over Tailscale via ssh, with tailscale status troubleshooting
Live real-time dashboard showing view, recalled object, confidence, search latency, modelVerified
Watch the robot's-eye view and its live decision (recalled object, confidence, Redis search latency, the Nebius model) on a real-time dashboard
Claimed on Devposthigh confidenceengram_server.py:71— DASH HTML/JS page polls /state every 400ms and renders label, confidence, search_ms, vlm model, and frame imageengram_server.py:203— /state endpoint returns result, memory_count, vlm and embed model names
One-shot learning (teach new object live, no retraining)Verified
Show it a brand-new object, teach it once (one vector written to Redis), and it recognizes it instantly
Claimed on Devposthigh confidenceengram_pipeline.py:199— store_memory() writes a single caption embedding vector to Redis under a labelengram_server.py:294— POST /learn_image endpoint embeds one frame and stores it as a new memory
Qwen3-Embedding-8B text embeddings, 4096-dVerified
Qwen/Qwen3-Embedding-8B turns the caption into a 4096-d vector
Claimed on readmehigh confidenceengram_pipeline.py:44— EMBED_MODEL = Qwen/Qwen3-Embedding-8Bengram_pipeline.py:45— EMBED_DIM = 4096 matches VectorField DIM used at index creation
Redis vector memory of objects (KNN cosine)Verified
Remembers every object as a vector in Redis, with sub-2ms nearest-neighbor recall over its whole memory bank
Claimed on Devposthigh confidenceengram_pipeline.py:170— creates a FLAT cosine VectorField index in Redisengram_pipeline.py:205— identify() runs a KNN query and times it with perf_counter
Robot arm Cartesian API unsupported (501), pivoted to head-look + waveVerified
The robot's SDK build didn't implement the Cartesian arm-control API (returned 501 Not Implemented), so 'point at it' pivoted to head-look + walk-up + wave
Claimed on Devposthigh confidencek1_indicate.py:4— comment states Cartesian arm API (MoveHandEndEffector) returns 501, so head RotateHead is used insteadk1_arm_lowlevel.py:6— confirms MoveHandEndEffector returns 501 and describes the low-level kCustom fallback triedDEMO_RUNBOOK.md:97— runbook documents the same 501/head-turn pivot
Robust recognition via semantic caption matching (not exact string match)Verified
An object captured from several angles gets several captions, so match is by semantic similarity, not exact strings
Claimed on Devposthigh confidenceengram_server.py:261— POST /see computes cosine similarity between embeddings of the live caption and the target phrase (semantic match) rather than string equalityengram_server.py:46— _cos() helper implements the cosine similarity used for this semantic matching
Single VLM call also returns object's horizontal center for trackingVerified
One VLM call also returns the object's horizontal center for tracking
Claimed on Devposthigh confidenceengram_pipeline.py:124— perceive() asks for JSON with caption and center_x in a single chat completion call
Spatial memory: capture object + heading while walked through sceneVerified
Walk it through a scene and it captures every object and the heading where it saw it
Claimed on Devposthigh confidencek1_fetch.py:132— scan() spins 360 degrees capturing frames with current theta/x/y at each stepengram_server.py:277— POST /capture stores caption embedding along with robot pose (x,y,theta)
Text query against memory ('is the green bottle here?')Verified
A text query embeds and searches the same index
Claimed on Devposthigh confidenceengram_pipeline.py:221— query_memory(text) embeds the text and runs the same KNN search against the indexengram_server.py:219— GET /query route exposes query_memory over HTTP
Redis-scale demo: preload large object bank (124 objects, sub-ms recall)Code-supported
KNN recall runs in ~2 ms over a 124-object bank
Claimed on Devpostmedium confidencepreload_bank.py:17— BANK list of curated object captions to preload into Redis for the scale demopreload_bank.py:156— loop embeds and stores each bank entry via store_memory
Sub-2ms KNN search latency claimCode-supported
Sub-2 ms memory recall in Redis over the whole object bank
Claimed on Devpostlow confidenceengram_pipeline.py:210— identify()/query_memory() measure and report search_ms via perf_counter, so latency is instrumented, but no benchmark/log file in the repo confirms the actual sub-2ms figure
Image embeddings (CLIP-style, Path B) for telling lookalikes apartClaimed only
What's next: Image embeddings (Path B): CLIP-style image vectors on a Nebius GPU to tell lookalikes apart
Claimed on Devposthigh confidenceOnboard Jetson brain for full untethered autonomyClaimed only
What's next: run the whole pipeline on the K1's onboard Jetson for full autonomy, untethered
Claimed on Devposthigh confidence
An AI agent derived these features from the project’s Devpost page and readme, then searched the code for each one. Verified features are backed by cited code; claimed-only features had no supporting code, which is not by itself proof a feature is missing.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.