--- title: "GRIIP SDK" slug: "griip-sdk-1" updated: 2026-09-03T19:07:53Z published: 2026-09-03T19:07:53Z canonical: "docs.vention.com/griip-sdk-1" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.vention.com/llms.txt > Use this file to discover all available pages before exploring further. # GRIIP SDK The GRIIP SDK is a Python library for building Physical AI powered automation applications that run on your Machine Motion AI. The steps are: 1. Populate the configuration file `config.yaml`. 2. Write a few lines of code using the GRIIP SDK. 3. Push this code to your Machine Motion. 4. Run your Physical AI powered robotics application. The GRIIP SDK handles the tedious parts of a complex vision-powered pick-and-place application for you. The only logic you write is logic specific to your setup; for example, a check the robot should do before placing. At Vention, the GRIIP SDK lets us program and deploy vision-powered robotics applications in a matter of days. --- ## 1. Configure your cell Everything about your physical setup lives in one file: the robot you're driving, the tool on the end of it, the camera watching the scene, and the parts you want to pick. There is no hardcoded geometry and there are no magic numbers buried in code. ``` # config.yaml robot: model: ur10e ip: 192.168.5.2 tool: type: gripper model: robotiq_2f140 tcp_offset: [0, 0, 0.245] camera: name: wrist_cam sensor: stereo environment: collision_geometry: ./environment/bin_and_walls.yaml positions: home: [0.0, -1.57, 1.57, -1.57, -1.57, 0.0] drop: [-1.5, -1.2, 1.0, -1.4, -1.5, 0.0] parts: - id: vp15 mesh: ./parts/vp15.stl grasps: ./parts/vp15_grasps.json placing: strategy: insert target: named_pose.receptacle ``` That's a full cell description. Swap the robot model, point at a different mesh, and the same application code picks a different part on a different arm. ## 2. Write a few lines of code A complete vision-powered bin picking application: ``` from griip_sdk import GRIIP griip = GRIIP("./config.yaml") griip.init(application="bin_picking", part_id="vp15") griip.start_pick_and_place() ``` Behind those three lines, GRIIP captures stereo images, estimates depth, detects parts, estimates 6DoF poses, generates and collision-checks grasps, plans trajectories, and runs the full pick-scoop-place cycle continuously until the bin is empty. ## 3. Push it to your Machine Motion Deploy from your laptop to the machine with one command using the Vention CLI: ``` vention push --host 192.168.5.10 --app ./my_picking_app ``` The CLI bundles your application and config, ships it to the Machine Motion AI, and installs it alongside the on-box GRIIP perception and planning services. ## 4. Run it ``` vention run --host 192.168.5.10 my_picking_app ``` Your application is now live on the cell. Telemetry and pick KPIs stream out of the box while the robot works. --- ## Make it yours The default loop is a good start, but real cells have quirks. The SDK exposes hooks at every decision point of the cycle, so your logic runs exactly where it needs to and you never rewrite the loop: ``` from griip_sdk import GRIIP, PlaceCandidate, Sensor FIXTURE_SENSOR_IP = "192.168.5.21" fixture_clear_sensor = Sensor(FIXTURE_SENSOR_IP) griip = GRIIP("./config.yaml") griip.init(application="bin_picking", part_id="vp15") def check_before_place(candidate: PlaceCandidate) -> bool: # Don't place until the fixture's presence sensor reports the slot is clear return fixture_clear_sensor.read() griip.start_pick_and_place( check_before_place=check_before_place, ) ``` There are hooks for every phase (`check_before_pick`, `check_before_place`, `on_pick_success`, `on_pick_failure`, `on_bin_empty`), so customizing a cell takes a dozen lines instead of a thousand. --- # API reference ## The `GRIIP` object One object represents the entire SDK. Construct it with your config, initialize it for your application type, and every call in this reference is a method on it. ``` from griip_sdk import GRIIP griip = GRIIP("./config.yaml") griip.init( application="bin_picking", # "bin_picking" | "pick_and_place" | "kitting" | "custom" part_id="vp15", mock=False, # run against simulated hardware for development ) ``` `init()` connects to the cell, validates your configuration against the physical setup, and wires up the right orchestration for your application type. Use it as a context manager and it handles teardown for you: ``` with GRIIP("./config.yaml") as griip: griip.init(application="bin_picking", part_id="vp15") ... ``` ## Three levels of control The SDK is layered. Every level is built from the one below it, and you choose how deep to go: 1. The managed loop. Call `start_pick_and_place()` and let GRIIP run the entire application. You customize behavior through the config file and callbacks, and write nothing else. 2. Your own loop. Skip the managed loop and compose your application from full-cycle building blocks: `pick()`, `place()`, `move_to()`, `release()`, `stop()`. GRIIP still handles perception, planning, and execution inside each call; you decide the sequence. 3. The primitives. Go all the way down to the individual engine capabilities (`capture()`, `estimate_depth()`, `detect_objects()`, `estimate_pose()`, streaming pick generation, path planning) and build something that isn't pick-and-place at all. ### Level 1: the managed loop One call runs a full, production-hardened cycle: perception, grasp generation, motion, placement, and failure recovery, continuously, until stopped or the bin is empty. ``` griip.start_pick_and_place() ``` All customization flows in through two channels, so the loop itself never needs to be rewritten. The config covers placing strategy, grasp ordering, retry thresholds, motion speeds, and region of interest, so most tuning never touches your code. Callbacks carry your logic, injected at every decision point of the cycle: ``` griip.start_pick_and_place( check_before_pick=..., # veto a pick candidate before the robot commits check_before_place=..., # veto or gate the placement on_pick_success=..., on_pick_failure=..., on_bin_empty=..., ) ``` If the managed loop with config and callbacks covers your cell, and for most pick-and-place cells it does, this is the whole SDK you'll ever touch. ### Level 2: build your own loop Sometimes the sequence itself is custom: parts routed to different stations, an inspection step between pick and place, a coordinating PLC calling the shots. In that case, write your own loop from the same building blocks the managed loop is made of: ``` pick = griip.pick(max_attempts=3) ``` Executes a single complete pick and returns a `PickResult`: whether it `succeeded`, the in-hand object pose, and structured `failure_reasons` when things go wrong. You decide what happens next. ``` griip.place() ``` Executes the placement leg for the part currently in hand, using the placing strategy from your config. ``` griip.move_to(griip.positions.drop) griip.release() ``` Collision-free motion to any configured position or pose, and gripper control, for the steps between picks and places that are unique to your cell. ``` griip.stop() ``` Gracefully winds down, finishes the current motion, and parks the robot. ### Level 3: the primitives Every capability of the GRIIP perception and planning engine is exposed directly, so you can compose your own pipeline when the application isn't pick-and-place at all. These are the same primitives `pick()` and `place()` are built from. #### `griip.perception` ``` image = griip.perception.capture() # grab from the cell camera depth = griip.perception.estimate_depth(image) # stereo -> dense depth detections = griip.perception.detect_objects(image, depth) # find parts in the scene pose = griip.perception.estimate_pose(image, depth, detections[0]) # 6DoF pose in_hand = griip.perception.estimate_in_hand_pose() # refine pose of the part in the gripper ``` #### `griip.picking` ``` for pick_candidate in griip.picking.generate_picks(image, depth): ... # candidates stream in as they're planned — take the first good one ``` #### `griip.placing` ``` placement = griip.placing.generate_placement() # refined pose + valid IK solutions for the place ``` #### `griip.planning` ``` griip.planning.configure(environment=...) # load collision world trajectory = griip.planning.plan_path(start=..., target=...) # collision-free path ``` --- # Example applications ## Level 1: bin picking in five lines ``` from griip_sdk import GRIIP with GRIIP("./config.yaml") as griip: griip.init(application="bin_picking", part_id="vp15") griip.start_pick_and_place() ``` ## Level 1: guarding picks with a custom check Still the managed loop; your logic rides along as a callback. ``` from griip_sdk import GRIIP, PickCandidate FRAGILE_ZONE_RADIUS = 0.08 def check_before_pick(candidate: PickCandidate) -> bool: return candidate.object_pose.distance_to(fixture_center) > FRAGILE_ZONE_RADIUS with GRIIP("./config.yaml") as griip: griip.init(application="bin_picking", part_id="vp15") griip.start_pick_and_place(check_before_pick=check_before_pick) ``` ## Level 2: a loop of your own The sequence is yours; GRIIP owns the hard parts inside each call. ``` from griip_sdk import GRIIP with GRIIP("./config.yaml") as griip: griip.init(application="pick_and_place", part_id="pcb") while True: pick = griip.pick(max_attempts=3) if not pick.succeeded: notify_operator(pick.failure_reasons) griip.stop() break if incoming_tray_is_full(): griip.move_to(griip.positions.overflow_drop) griip.release() else: griip.place() ``` ## Level 3: building your own pipeline from the primitives When your application doesn't look like pick-and-place at all (inspection, counting, custom manipulation), compose it from the same engine: ``` from griip_sdk import GRIIP with GRIIP("./config.yaml") as griip: griip.init(application="custom", part_id="vp15") image = griip.perception.capture() depth = griip.perception.estimate_depth(image) detections = griip.perception.detect_objects(image, depth) print(f"{len(detections)} parts on the table") for detection in detections: pose = griip.perception.estimate_pose(image, depth, detection) griip.move_to(compute_camera_vantage(pose)) run_quality_inspection(griip.perception.capture()) ``` Same config, same hardware, same SDK, running a completely different application.