yahboom
HomeTutorialsProduct
Solution
Blog
Online Store
About Us
EN/中文
Store
ROSMASTER M1 PRO📖
0.Robot Configuration and Operation Guidelines
  • 0.Unboxing and Review
  • 1.Assembly Videos
  • 2.User Manual
  • 3.Enter Docker (For Raspberry Pi)
  • 4.FAQ
  • 5.RobotManager User Guide
1.Chassis Control Course
  • 1.Robot Information Publishing
  • 2.Robot Handle Control
  • 3.Robot Keyboard Control
  • 4.Linear Velocity Calibration
  • 5.Angular Velocity Calibration
  • 6.Robot URDF Model
  • 7.Robot EKF State Estimation
2.Lidar Course
  • 1.Lidar Introduction And Use
  • 2.Lidar Obstacle Avoidance
  • 3.Lidar Following
  • 4.Lidar Guard
  • 5.Lidar Patrol
  • 6.GMapping-SLAM Mapping
  • 7.Cartographer-SLAM Mapping
  • 8.Slam-Toolbox Mapping
  • 9.Lifelong Mode Mapping
  • 10.Navigation2 Single Point Navigation
  • 11.Navigation2 Multi Point Navigation
  • 12.Cartographer Relocalization Navigation
  • 13.Slam-Toolbox Localization Navigation
  • 14.Synchronous Mapping And Navigation
  • 15.Aruco Visual Relocalization Navigation
  • 16.Mobile App Mapping And Navigation
3.USB Camera-Depth Camera Course
  • 1.USB Camera Introduction
  • 2.USB Camera Intrinsic Calibration
  • 3.Nuwa-HP60C Camera Introduction (Depth Camera Only)
  • 4.Depth Pseudo Color Image (Depth Camera Only)
  • 5.Depth Camera Distance Measurement (Depth Camera Only)
  • 6.Block Volume Calculation (Depth Camera Only)
  • 7.Edge Detection (Depth Camera Only)
  • 8.RTAB-Map SLAM Mapping (Depth Camera Only)
  • 9.RTAB-Map Navigation (Depth Camera Only)
4.Robotic Arm and 3D Space Gripping Course
  • 1.Robotic Arm Basic Usage
  • 2.Robotic Arm Kinematics
  • 3.Robotic Arm Chassis Coordination Control
  • 4.AprilTag ID Sorting
  • 5.AprilTag Height Anomaly Sorting
  • 6.AprilTag Tracking and Grasping
  • 7.Color Block Sorting
  • 8.Color Block Height Anomaly Sorting
  • 9.Color Block Tracking and Grasping
  • 10.Wood Block Shape Sorting
  • 11.KCF Tracking and Grasping Objects
  • 12.Mediapipe Gesture ID Sorting AprilTag
  • 13.Mediapipe Gesture Height Sorting AprilTag
  • 14.Desktop Tracking and Grasping AprilTag
  • 15.3D Spatial Tracking AprilTag
  • 16.Transformer Model Tracking Algorithm
  • 17.Line Following Obstacle Clearing
5.Road network planning and navigation
  • 1.Introduction To Road Network Planning
  • 2.Road Network Annotation
  • 3.Planning And Navigation Between Waypoints
  • 4.Road Network Navigation In Any Pose
  • 5.Path Re-planning
6.OpenClaw Basic Course
  • 1.Introduction to OpenClaw
  • 2.OpenClaw Core Concepts
  • 3.OpenClaw API-KEY Configuration
  • 4.OpenClaw Switch Models
  • 5.OpenClaw System Prompt Words
  • 6.OpenClaw Common CLI Commands
7.OpenClaw Interaction Method
  • 1.OpenClaw Webchat Interaction
  • 2.OpenClaw Tui Interaction
  • 3.OpenClaw Voice Dialogue Interaction
  • 4.OpenClaw WhatsApp Interaction
8.OpenClaw Development
  • 1.OpenClaw Connecting to Robot MCP Service
  • 2.Robot CLI Command Tool
  • 3.robot-control Plugin Tool
  • 4.reply-bridge Plugin Tool
  • 5.OpenClaw Multimodal Vision
  • 6.OpenClaw Chassis Control
  • 7.OpenClaw Robotic Arm Control
  • 8.OpenClaw Skills Development
  • 9.OpenClaw Scheduled Tasks
  • 10.OpenClaw Multi-Agent Intelligent Agent
  • 11.OpenClaw Active Interaction
  • 12.OpenClaw Vector Memory
9.OpenClaw Embodied intelligent application
  • 1.OpenClaw Target Tracking
  • 2.OpenClaw Arm Tracking And Grasping
  • 3.OpenClaw Arm Fixed-point Placement
  • 4.OpenClaw Waste Sorting
  • 5.OpenClaw SLAM Mapping And Navigation
  • 6.OpenClaw Navigation Transport
  • 7.OpenClaw AprilTag Grasping
  • 8.OpenClaw Color Line Patrol
  • 9.OpenClaw Visual Distance Measurement
10.OpenClaw scenario sandbox
  • 1.Map Description and Props Placement
  • 2.Building the Sandbox Map
  • 3.Visual Relocalization Marker
  • 4.Map Mapping Marker
  • 5.Sandbox Scenario Comprehensive Case
11.AI Large Model Basics
  • 1.AI Large Model Types and Principles
  • 2.RAG Retrieval Enhancement and Model Training Samples
  • 3.Embodied Intelligent Robot System Architecture
  • 4.Embodied Intelligent Functions Core Source Code
12.AI large Model Development
  • 1.Register a Model Service Provider Account
  • 2.Configuring API-KEY
  • 3.Introduction to Dify
  • 4.Basic Dify Features
  • 5.AI Large Model Development - Chatbot
  • 6.Deploy the RAG Knowledge Base
  • 7.RAG Knowledge Base + Chatbot
  • 8.AI Agent Workflow
  • 9.Custom Wake-up Response
13.AI Model - Voice Version
  • 1.Semantic Understanding and Command Following
  • 2.Multimodal Visual Understanding
  • 3.Multimodal Visual Understanding and Robotic Arm Gripping
  • 4.Multimodal Visual Understanding and SLAM Navigation
  • 5.Robotic arm gripping+Multimodal visual understand+SLAM navigation
  • 6.Intention Understanding
14.AI Model - Text Version
  • 1.Semantic Understanding and Command Following
  • 2.Multimodal Visual Understanding
  • 3.Multimodal Visual Understanding and Robotic Arm Gripping
  • 4.Multimodal Visual Understanding and SLAM Navigation
  • 5.Robotic arm gripping+Multimodal visual understand+SLAM navigation
  • 6.Intention estimation
15.Mediapipe Visual Course
  • 1.Hand detection
  • 2.Posture detection
  • 3.Overall detection
  • 4.Facial Landmark Detection
  • 5.Face detection
  • 6.Face special effects
  • 7.3D object recognition
  • 8.Brush
  • 9.Finger control
  • 10.Palm target positioning
  • 11.Fingertip trajectory recognition
  • 12.Fingertip gesture control robotic arm
  • 13.Gesture grabbing and releasing objects
  • 14.Finger control robotic arm
  • 15.Medipipe gesture control robotic arm action group
16.MoveIt2 Simulation Course
  • 1.MovelT2 configuration
  • 2.MovelT2 simulation-reality linkage
  • 3.Random movement
  • 4.Forward kinematics design
  • 5.Inverse kinematics design
  • 6.Cartesian path
  • 7.Trajectory Planning
  • 8.Collision Detection
  • 9.Scene Design
  • 10.3D perception obstacle‑avoidance
17.Multi-vehicle Course
  • 1.Multi-vehicle Control
  • 2.Multi-vehicle Navigation
  • 3.Multi-vehicle Formation
18.YOLO26 Development
  • 1.CLI Use
  • 2.Object Detection
  • 3.Instance Segmentation
  • 4.Pose Estimation
  • 5.Image Classification
  • 6.Oriented Object Detection
  • 7.YOLOv26 + DeepSORT Tracking
  • 8.Monocular Depth Estimation
19.Control Board STM32 Driver Course
  • 0.Notes (Must Read)
  • 1.About Expansion Board
  • 2.STM32 Development Environment
  • 3.Button Control
  • 4.FreeRTOS Application
  • 5.Serial Communication
  • 6.SBUS Model Aircraft Remote Control
  • 7.CAN Bus Communication
  • 8.RGB Colorful Light Bar
  • 9.Timer Interrupt to Control PWM Servo
  • 10.Control Serial Port Servos
  • 11.Nine-axis Attitude Sensor to Obtain Data
  • 12.Control Motor
  • 13.Timer Captures the Encoder Data
  • 14.1 Kinematic Analysis of Mecanum Wheel
  • 14.2 Kinematic Analysis of Ackerman
  • 14.3 Kinematic Analysis of 4WD
  • 15.PID Control Robot Movement
20.Docker Course
  • 1.Docker Introduction and Installation
  • 2.Docker Basic Commands
  • 3.Docker Submission and Multi-Terminal Access
  • 4. Docker Startup Script
  • 5.Docker-Vscode Environment Construction
21.Image Processing Basics Course
  • 1. Introduction to Open Source CV
  • 2. Image reading and display
  • 3. Image writing
  • 4. Image quality
  • 5. Pixel Operation
  • 6. Image zoom
  • 7. Image cutting
  • 8. Image translation
  • 9. Image Mirroring
  • 10. Affine Transformation
  • 11. Image Rotation
  • 12. Perspective Transformation
  • 13. Grayscale processing
  • 14. Image Binarization
  • 15. Edge Detection
  • 16. Line drawing
  • 17. Rectangle and circle drawing
  • 18. Drawing text and pictures
22.Linux System Course
  • 1.Introduction to Linux system
  • 2.Ubuntu file system
  • 3.Ubuntu common commands
  • 4.Ubuntu common editors
  • 5.Ubuntu software operation commands
  • 6.Virtual machine installation
  • 7.SSH remote control
  • 8.VNC remote control
  • 9.Transfer files remotely
  • 10.Driver library and communication
  • 11.Static IP and hotspot mode
  • 12.Bind device ID
  • 13.Capacity expansion and resource allocation
  • 14.Update system software sources
  • 15.Set root user password
  • 16.sudo free password
  • 17.Connect to WiFi network
  • 18.View system version
  • 19.Customized service management
  • 20.Back up system image
23.ROS2 Basic Course
  • 1.Introduction to ROS2
  • 2.ROS2 install Humble
  • 3.ROS2 development environment
  • 4.ROS2 workspace
  • 5.ROS2 function package
  • 6.ROS2 node
  • 7.ROS2 topic communication
  • 8.ROS2 service communication
  • 9.ROS2 action communication
  • 10.ROS2 custom interface message
  • 11.ROS2 parameter service case
  • 12.ROS2 meta-function package
  • 13.ROS2 distributed communication
  • 14.ROS2 DDS
  • 15.ROS2 time related API
  • 16.ROS2 common command tools
  • 17.ROS2 rviz2 use
  • 18.ROS2 rqt toolbox
  • 19.ROS2 Launch startup file configuration
  • 20.ROS2 recording and playback tool
  • 21.ROS2 URDF model
  • 22.ROS2 Gazebo simulation platform
  • 23.ROS2 TF2 coordinate transformation
24.Main Control Course
Jetson Orin Nano_NX
  • 1.Jetson Orin board introduction
  • 2.Restore the factory image system
  • 3.Backup SSD system
  • 4.SSD expansion
  • 5.Network configuration
  • 6.SSH remote login
  • 7.VNC remote control
  • 8.Remote file transfer
  • 9.Jtop tool
  • 10.Exchange space expansion
Raspberry Pi
  • 1. Introduction to Raspberry PI 5
  • 2. Raspberry PI system installation and backup
  • 3. Powering the Raspberry PI 5
  • 4. Startup of Raspberry PI 5
  • 5. Update and upgrade operating system
  • 6. Introduction to raspi-config tool
  • 7. config.txt file description
  • 8. Network Configuration
  • 9. remote access
  • 10. Transfer files remotely
  • 11. Set display resolution and rotation
  • 12. Set screen to sleep
  • 13. Play audio and video
  • 14. Using USB camera
  • 15. Using MIPI camera
  • 16. Get real-time temperature of Raspberry Pi
RDKX5
  • 1.Introduction to RDK X5 board
  • 2.Write system file
  • 3.Hardware interface description
  • 4.Install case and other accessories
  • 5.Network configuration
  • 6.Remote login
  • 7.Update system
  • 8.srpi-config user guide
  • 9.config. txt configuration file
  • 10.Self-startup setting
  • 11.RDK exclusive command usage
  • 12.Linux command usage
  • 13.GPIO readwrite operation
  • 14.Image classification algorithm
  • 15.Use USB camera
  • 16.Use MIPI camera
  • 17.Binocular camera depth algorithm
  • 18. Controlling RGB Cooling Fans
Download
  • System File
  • Code
  • 3D Model File
  • Software Tools
  • Hardware_Info
  • Deb function package
  • Dify AI Agent
Download ZIP

Welcome to ROSMASTER M1 PRO repository

5.OpenClaw Multimodal Vision

OpenClaw Multimodal Vision

OpenClaw Multimodal Vision1. Course ContentCourse OverviewLearning Objectives2. Preparation3. Vision-Related Control Interfaces4. Case Demonstration4.1 Start OpenClaw Interaction4.2 Visual Observation and Understanding4.3 Configuring SeeWhat Auto-Send Channels4.3.1 Configure WhatsApp Channel4.4 Get Target Bounding Box Coordinates4.5 Get Placement Point Coordinates (Depth Camera Only)5. Source Code Analysis5.1 SeeWhat() — Capture Camera Image5.2 GetBbox() — Get Target Bounding Box Coordinates5.3 GetPlacePoint() — Get Placement Point Coordinates5.4 visual_bounding and visual_positioning6. Function Q&A6.1 What should I do if the vision model does not accurately draw bounding boxes around target objects?

1. Course Content

Course Overview

  • OpenClaw's multimodal vision capability provides visual perception through MCP interfaces, enabling robots to "understand" their surroundings

  • Covers 3 core vision tools: SeeWhat (capture image), GetBbox (object detection bounding box), GetPlacePoint (get placement point coordinates)

  • Supports configuring SeeWhat auto-send channels to automatically push robot observation images to communication channels like WhatsApp

Learning Objectives

  1. Understand the functionality and use cases of the 3 vision control interfaces provided by OpenClaw

  2. Master the configuration method for SeeWhat auto-send channels

  3. Master how to invoke vision tools directly via CLI

2. Preparation

  • Start the MCP service

ros2 launch yahboomcar_bringup mcp_service.launch.py use_camera:=true
  • If you need voice broadcast replies, you need to add the use_tts parameter: ros2 launch yahboomcar_bringup mcp_service.launch.py use_camera:=true use_tts:=true, otherwise it can be omitted

 

3. Vision-Related Control Interfaces

Note

  • For the detailed functionality, parameters, and usage of the interfaces, please refer to the tutorials 【OpenClaw Connecting to Robot MCP Service】 and 【Robot CLI Command Tool】

Tool NameFunction Description
SeeWhatCapture camera image and return save path
GetBboxDetect bounding box coordinates of target object
GetPlacePointGet placement point coordinates and check reachability

 

4. Case Demonstration

4.1 Start OpenClaw Interaction

  • Use any interaction method to converse with OpenClaw, here demonstrating with Web Chat

image-20260429195455794

 

Tip

  • You can write conversation statements according to your own needs, following is the case demonstration

4.2 Visual Observation and Understanding

  • Take a look at what is in the environment in front of you

image-20260429200708658

  • When the SeeWhat tool on the MCP server side is called, the image is automatically saved for checking the observed content, image path: $HOME/yahboomcar_ros2_ws/yahboomcar_ws/cache/image.png

4.3 Configuring SeeWhat Auto-Send Channels

  • This feature is used for the robot to automatically send observation-perspective images to mobile communication channels when calling SeeWhat to observe the environment

  • Configuration parameter path: $HOME/.openclaw/openclaw.json. You can directly modify the configuration file or configure it through CLI commands; the following uses CLI command configuration as an example

Important

  • SeeWhat_channels are the channels that need to be auto-sent; images will only be sent to the channels in the list

xxxxxxxxxx
...  
"robot-control": {
    "enabled": true,
    "config": {
      "SeeWhat_channels": [
        "whatsapp",
        "weixin"  
      ],
      "whatsapp_number": "+8615338xxxxxxx"
    }
  }
...

Configuration Parameter Description:

  • SeeWhat_channels: Auto-send channel list, supports whatsapp and weixin. When SeeWhat is called, observation images are automatically sent to the channels in the list

  • whatsapp_number: WhatsApp recipient phone number, which must include the country code (e.g., +86)

 

4.3.1 Configure WhatsApp Channel

xxxxxxxxxx
openclaw config set plugins.entries.robot-control.config.SeeWhat_channels '["whatsapp"]'
  • Set the SeeWhat_channels phone number

xxxxxxxxxx
openclaw config set plugins.entries.robot-control.config.whatsapp_number "+861533xxxxx"
  • Restart the gateway to apply

xxxxxxxxxx
openclaw gateway restart
  • During restart, the openclaw log will indicate the auto-send channel

image-20260430151740758

Note

  • Now you can converse with OpenClaw; when a vision function is called, the image will be automatically sent to the configured communication channels

4.4 Get Target Bounding Box Coordinates

  • Get the outer bounding box of the target object. This tool is used for subsequent robotic arm grasping of objects and target tracking. The GetBbox tool provides the function of obtaining target Box bounding box coordinates based on a natural language description

  • You can directly call GetBbox via the robot_control CLI

xxxxxxxxxx
robot_control call-tool GetBbox --query yellow block on the table
  • If the target object exists within the camera's field of view, it returns the Box bounding box coordinates and the path to the annotated verification image. The Box bounding box coordinates are used by OpenClaw to decide the next operation.

image-20260907195004448

  • The auto-saved verification image path is:

xxxxxxxxxx
~/yahboomcar_ros2_ws/yahboomcar_ws/cache/verify_image.png
  • You can check through the image whether the vision model accurately draws a bounding box around the target

image-20260907194943701

 

Important

  • The accuracy of visual positioning and bounding box selection depends on the capability of the vision model, which will directly affect robotic arm grasping and visual tracking functions. If the vision model frequently produces inaccurate bounding boxes, refer to 6. Function Q&A to change the vision model or switch the detection method

 

4.5 Get Placement Point Coordinates (Depth Camera Only)

  • This tool is used for subsequent robotic arm placing objects to specified points. It obtains the spatial 3D coordinates of the target point based on a natural language description, and determines whether the point is within the robotic arm's working range

  • You can directly call GetPlacePoint via the robot_control CLI

xxxxxxxxxx
robot_control call-tool GetPlacePoint --query place to the right of the yellow block on the table
  • If a point matching the description exists within the camera's field of view, the tool returns the spatial coordinates of the target point in the vehicle's base_link coordinate system, the verification image path, and a prompt about whether the point is within the robotic arm's working range

image-20260907195325975

  • Verification image save path:

xxxxxxxxxx
~/yahboomcar_ros2_ws/yahboomcar_ws/cache/image_point_selected.png

image-20260907195232655

5. Source Code Analysis

  • Source code path

xxxxxxxxxx
~/yahboomcar_ros2_ws/yahboomcar_ws/src/multi_brains_pre/multi_brains_pre/action_controller.py

The following is the source code explanation of the three core vision functions in the ActionController class.


5.1 SeeWhat() — Capture Camera Image

xxxxxxxxxx
def SeeWhat(self)->list[bool,str]:
    '''To capture the scene before your eyes'''
    response:Trigger.Response=self.image_cllient.call(Trigger.Request())
    if response.success:
        result=[True,response.message]
        self.image_path=response.message
    else:
        self.image_path=None
        result=[False,response.message]
        self.get_logger().error(response.message)
    return result

Code Description:

  • SeeWhat: Captures the current camera frame and saves the image, returning the image path for upper-level functions to use

  • Trigger.Request(): Constructs a ROS2 Trigger service request with no parameters, triggering the camera to capture and save an image

  • self.image_cllient.call(...): Calls the /save_image service, returning a Trigger.Response containing success (whether it succeeded) and message (the image path or error information)

  • self.image_path: Saves the image path for use by subsequent functions such as GetBbox and GetPlacePoint

  1. Call the image service: Through image_cllient (a ROS2 Trigger client), calls the /save_image service to trigger camera capture

  2. Result handling: On success, saves the image path to self.image_path; on failure, logs an error

  3. Return value: Returns [True, image_path] or [False, error_message] for upper-level functions to judge


5.2 GetBbox() — Get Target Bounding Box Coordinates

Code Description:

  • GetBbox: Gets the bounding box coordinates of the target object based on a natural language description, returning a bbox dictionary string

  • self.SeeWhat(): First refreshes the image to ensure detection is based on the current scene

  • self._get_bbox_tool(): Lazily loads the visual bounding box detection tool; on the first call, reads the vision LLM configuration (api_key, base_url, model) from robot_info.json and initializes RobotVisualPBoundingBox

  • tool.BoundingBoxDetection(image_path, target_description): Calls the vision LLM for target detection, returning a Visual_Result containing found and the x1/y1/x2/y2 coordinates

  • result.error / result.found: Checks whether detection errored or the target does not exist, returning the corresponding error information respectively

  • _get_bbox_tool: A lazy loading method that reads vision_LLM's api_key, base_url, and model from the configuration file, initializes a RobotVisualPBoundingBox instance, and supports the detect_mode and yolo_model_path parameters

  1. Automatic image refresh: First calls SeeWhat() to get the latest frame, ensuring detection is based on the current scene

  2. Draw grid overlay: Via draw_grid_overlay(grid_size=30), overlays a grid on the image to assist the Dify vision model in pixel localization

  3. Result parsing: Extracts the bbox list from the JSON returned by the Agent, obtaining the four corner coordinates x1/y1/x2/y2

  4. Verification image: Draws a green rectangular box on the original image and saves it to verify_image.png, facilitating manual confirmation of whether the bounding box is accurate

​x
    def GetBbox(self,query:str)->list[bool,str]:
        """Get the bounding box of an object in the scene"""
        res=self.SeeWhat() #Automatic image refresh
        if not res[0]: return [False,res[1],""]
        try:
            tool = self._get_bbox_tool()
        except Exception as e:
            self.get_logger().error(f"GetBbox init failed: {e}")
            return [False, f"GetBbox failed: {e}", ""]
        result = tool.BoundingBoxDetection(image_path=self.image_path, target_description=str(query))
        if result.error:
            self.get_logger().error(result.error_message)
            return [False, f"GetBbox failed: {result.error_message}", ""]
        if not result.found:
            return [False, f"GetBbox: target '{query}' not found in the image", ""]
        self.get_logger().info(f"GetBbox: target bbox=({result.x1},{result.y1},{result.x2},{result.y2})")
        return [True, str({"x1": result.x1, "y1": result.y1, "x2": result.x2, "y2": result.y2})]

    def _get_bbox_tool(self):
        """Lazy load the bounding box tool"""
        if self._bbox_tool is None:
            from robot_util.visual_positioning.visual_bounding import RobotVisualPBoundingBox
            from robot_util.robot_tool import GetRobotInfo
            vision_llm = GetRobotInfo().get("vision_LLM") or {}
            api_key = vision_llm.get("api_key")
            base_url = vision_llm.get("base_url")
            model = vision_llm.get("model")
            if not api_key or not base_url or not model:
                raise RuntimeError("vision_LLM api_key/base_url/model are not configured in robot_info.json")
            self._bbox_tool = RobotVisualPBoundingBox(api_key=api_key, base_url=base_url, model=model,
                                                      detect_mode=self.bbox_detect_mode,
                                                      yolo_model_path=self.yolo_model_path)
        return self._bbox_tool

5.3 GetPlacePoint() — Get Placement Point Coordinates

Code Description:

  • GetPlacePoint: Gets the 3D spatial coordinates of the placement point based on a natural language description, and checks whether it is within the robotic arm's working range

  • self.SeeWhat(): Refreshes the image to ensure positioning is based on the current scene

  • self._get_place_point_tool(): Lazily loads the visual positioning tool; on the first call, reads the vision LLM configuration from robot_info.json and initializes RobotVisualPositioning

  • tool.FindTargetPoint(image_path, target_description): Calls the vision LLM to get the pixel coordinates (x, y) of the target point, returning a PositioningResult

  • result.found: Checks whether the target point exists; if not, returns an error

  • GetTargetPose.Request(x, y, radius=self.target_circle): Constructs the pose resolution service request, where radius is the radius of the circular sampling area (pixels)

  • self.get_pose_client.call(request): Calls the /get_target_pose service to convert the pixel coordinates into 3D spatial coordinates in the base_link coordinate system

  • round(result.pose.position.x/y/z, 2): Rounds the 3D coordinates to 2 decimal places and converts them to a string format for return

  • self.place_distance[2]/[3]: The upper limits of the robotic arm's working range, used to determine whether the target point is reachable

  • _get_place_point_tool: A lazy loading method that reads the vision_LLM configuration from the configuration file and initializes a RobotVisualPositioning instance

  1. Refresh image: Likewise first calls SeeWhat() to get the latest scene

  2. Grid overlay: Uses a grid_size=20 grid (finer than the 30 used by GetBbox), because the placement point requires higher-precision pixel localization

  3. Target non-existence determination: When (-1, -1) is returned, it indicates that the target point is not in the frame

  4. Verification image drawing: A black circle marks the target_circle sampling range, and a red solid dot marks the detection center, saved to place_verify_image.png

  5. 3D coordinate conversion: Through get_pose_client (the /get_target_pose service), converts the pixel coordinates (x, y) into 3D spatial coordinates (x, y, z) in the base_link coordinate system

  6. Working range detection: Determines whether the converted 3D coordinates are within the place_distance[2]/[3] range, returning a readable prompt message

xxxxxxxxxx
    def GetPlacePoint(self,query:str)->list[bool,str]:
        save_result=self.SeeWhat()
        if  not save_result[0]:
            return [False, f"SeeWhat error:{save_result[1]}",""]
        try:
            tool = self._get_place_point_tool()
        except Exception as e:
            self.get_logger().error(f"GetPlacePoint init failed: {e}")
            return [False, f"GetPlacePoint failed: {e}", ""]
        # Grid overlay and target-point annotation are handled inside FindTargetPoint
        result = tool.FindTargetPoint(image_path=self.image_path, target_description=str(query))
        if result.error:
            self.get_logger().error(result.error_message)
            return [False, f"GetPlacePoint failed: {result.error_message}", ""]
        if not result.found:
            return [False, "point is empty; the target point may not exist in the frame.", ""]
        x, y = result.x, result.y
        
        request = GetTargetPose.Request(x=float(x), y=float(y), radius=self.target_circle)
        result:GetTargetPose.Response = self.get_pose_client.call(request)
        
        if not result.success:
            self.get_logger().error(f"GetTargetPose failed: {result.message}")
            return [False, str(result.message),""]
        
        point = str({"x": round(result.pose.position.x, 2), 
                     "y": round(result.pose.position.y, 2),
                     "z": round(result.pose.position.z, 2)
                     })
        self.get_logger().info(
                f'Target Point:x:{result.pose.position.x:.2f}, '
                f'y:{result.pose.position.y:.2f}, '
                f'z:{result.pose.position.z:.2f}')
        if result.pose.position.x<=self.place_distance[2] and result.pose.position.y <= self.place_distance[3]:
            msg="✅ The target point is within the working range of the robotic arm"
        else:
            msg="❌ The target point is outside the working range of the robotic arm"
        return [True,msg,point]

    def _get_place_point_tool(self):
        """Lazy load the placement-point positioning tool"""
        if self._place_point_tool is None:
            from robot_util.visual_positioning.visual_positioning import RobotVisualPositioning
            from robot_util.robot_tool import GetRobotInfo
            vision_llm = GetRobotInfo().get("vision_LLM") or {}
            api_key = vision_llm.get("api_key")
            base_url = vision_llm.get("base_url")
            model = vision_llm.get("model")
            if not api_key or not base_url or not model:
                raise RuntimeError("vision_LLM api_key/base_url/model are not configured in robot_info.json")
            self._place_point_tool = RobotVisualPositioning(api_key=api_key, base_url=base_url, model=model)
        return self._place_point_tool

5.4 visual_bounding and visual_positioning

  • Source code path

xxxxxxxxxx
~/yahboomcar_ros2_ws/yahboomcar_ws/src/robot_util/robot_util/visual_positioning/visual_bounding.py
xxxxxxxxxx
~/yahboomcar_ros2_ws/yahboomcar_ws/src/robot_util/robot_util/visual_positioning/visual_positioning.py

 

  • _online_detection (visual_bounding.py): Online visual detection function

    • Encodes the image as base64, calls the vision LLM through litellm.completion(), sending the system prompt + target description + image

    • Handles exceptions such as authentication errors, rate limits, and general API exceptions

    • Parses the JSON returned by the model, extracting found and the x1/y1/x2/y2 bounding box coordinates

    • When the target exists, creates a Visual_Result and draws the verification image; when it does not exist, returns found=False

  • FindTargetPoint (visual_positioning.py): Target point pixel localization function

    • Reads the image and computes the number of grid rows and columns (based on grid_size)

    • Overlays a grid with indices and orientation labels, saving it as _grid.png for the vision model to recognize

    • Builds the system prompt, including the image dimensions, grid size, maximum index, and orientation labels

    • Calls the vision LLM; the model returns the grid index (col, row) where the target is located

    • Clamps the grid index to the legal range and computes the grid center pixel coordinates (x, y)

    • Marks the detection point on the original image and returns a PositioningResult containing the pixel coordinates

xxxxxxxxxx
    def _online_detection(self, image_path: str, target_description: str) -> Visual_Result:
        image_base64, err = self._encode_image(image_path)
        if err:
            return Visual_Result(error=True, error_message=f"Image encoding error: {err}")

        try:
            response = completion(
                model=self.model,
                messages=[
                    {"role": "system", "content": PROMPT},
                    {
                        "role": "user",
                        "content": [
                            {"type": "text", "text": f"Target: {target_description}"},
                            {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_base64}"}},
                        ],
                    },
                ],
                api_base=self.base_url,
                api_key=self.api_key,
            )
        except litellm.AuthenticationError as e:
            return Visual_Result(error=True, error_message=f"Bad API key: {e}")
        except litellm.RateLimitError as e:
            return Visual_Result(error=True, error_message=f"Rate limited: {e}")
        except Exception as e:
            return Visual_Result(error=True, error_message=f"API error: {e}")

        data, parse_err = self._parse_model_json(response)
        if parse_err:
            return parse_err
        if data.get("found"):
            result = Visual_Result(found=True, x1=data["x1"], y1=data["y1"], x2=data["x2"], y2=data["y2"])
            if self._annotate_selected(image_path, result) is None:
                logger.warning("OnlyOnline: selected-target annotation failed")
            return result
        return Visual_Result(found=False, error_message="Target not found in image")
    
     def FindTargetPoint(self, image_path: str, target_description: str) -> PositioningResult:
        '''Find the pixel coordinates (x, y) of the target point described in natural language.
        The visual model returns the grid cell containing the target, and the grid center
        pixel coordinates are computed locally'''
        img = cv2.imread(image_path)
        if img is None:
            return PositioningResult(error=True, error_message=f"Image not found: {image_path}")
        img_h, img_w = img.shape[:2]
        cols = math.ceil(img_w / self.grid_size)
        rows = math.ceil(img_h / self.grid_size)

        # Overlay the indexed grid (with orientation labels) and save it next to the original for the online model
        grid_img = draw_grid_overlay(img, grid_size=self.grid_size, orientation_labels=self.orientation_labels)
        base, _ = os.path.splitext(image_path)
        grid_path = f"{base}_grid.png"
        if not cv2.imwrite(grid_path, grid_img):
            return PositioningResult(error=True, error_message=f"Failed to save grid image: {grid_path}")

        image_base64, err = self._encode_image(grid_path)
        if err:
            return err

        system_prompt = Template(PROMPT_TEMPLATE).substitute(
            width=img_w, height=img_h, grid_size=self.grid_size,
            max_col=cols - 1, max_row=rows - 1,
            top_label=self.orientation_labels["top"], bottom_label=self.orientation_labels["bottom"],
            left_label=self.orientation_labels["left"], right_label=self.orientation_labels["right"]
        )

        try:
            response = completion(
                model=self.model,
                messages=[
                    {"role": "system", "content": system_prompt},
                    {
                        "role": "user",
                        "content": [
                            {"type": "text", "text": f"Target: {target_description}"},
                            {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image_base64}"}},
                        ],
                    },
                ],
                api_base=self.base_url,
                api_key=self.api_key,
            )
        except litellm.AuthenticationError as e:
            return PositioningResult(error=True, error_message=f"Bad API key: {e}")
        except litellm.RateLimitError as e:
            return PositioningResult(error=True, error_message=f"Rate limited: {e}")
        except Exception as e:
            return PositioningResult(error=True, error_message=f"API error: {e}")

        data, parse_err = self._parse_model_json(response)
        if parse_err:
            return parse_err
        if not data.get("found"):
            return PositioningResult(found=False, error_message="Target point not found in image")

        col = self._to_int(data.get("col"))
        row = self._to_int(data.get("row"))
        if col is None or row is None:
            return PositioningResult(error=True,
                                     error_message=f"The visual model returned an invalid grid index: {data}")

        # Clamp the indices into the legal range, then compute the grid center point
        col = max(0, min(col, cols - 1))
        row = max(0, min(row, rows - 1))
        x = min(col * self.grid_size + self.grid_size // 2, img_w - 1)
        y = min(row * self.grid_size + self.grid_size // 2, img_h - 1)
        logger.info(f"Positioning: target cell (col={col}, row={row}), center point (x={x}, y={y})")

        if self._annotate_selected(image_path, x, y) is None:
            logger.warning("Positioning: selected-point annotation failed")
        return PositioningResult(found=True, x=x, y=y, grid_col=col, grid_row=row)

 

6. Function Q&A

6.1 What should I do if the vision model does not accurately draw bounding boxes around target objects?

  • Start RobotManager through the icon or CLI

xxxxxxxxxx
robot_manage gui
  • Option 1: Directly replace the vision model

  • In Configuration — Vision Model, you can switch to vision models from different providers for the visual bounding box localization feature

Tip

  • Recommended models for visual positioning: qwen-vl-max, qwen3.8-max, kimi2.5

image-20260907145415797

 

  • Option 2: Switch the visual localization mode to Hybrid (mixed detection) mode

image-20260908095118746

Note

  • This is a pre-research feature that can significantly improve the bounding box localization capability of vision models that lack pixel-level localization. The core logic is: the vision model provides several words describing target features, then the yolo-world open-vocabulary model detects all candidate words for pixel localization, and finally vision performs semantic decision-making to determine the final target object. For the detailed program implementation, refer to the aforementioned visual_bounding.py

  • The factory detection mode is OnlyOnline (online detection only)

image-20260908094259603

 

 

reply-bridge Plugin Tool
OpenClaw Chassis Control

COMPANY

  • About us
  • Team Style
  • Blog

LEARNING & EXPLORATION

  • Tutorials
  • Edge AI hardware
  • Educational robots
  • Embedded intelligent hardware

WHERE TO BUY

  • Yahboom Online Store
  • Amazon
  • Alibaba
  • AliExpress
  • Mercado

TECHNOLOGY SUPPORT

  • Email: support@yahboom.com

BE A DISTRIBUTOR

  • Email: sales@yahboom.com
QR Code

Copyright © 2017-2026 Yahboom. All Rights Reserved.

EN/中文