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

4.OpenClaw Waste Sorting

OpenClaw Waste Sorting

OpenClaw Waste Sorting1. Course ContentLearning Objectives2. Preparation3. Robotic Arm Waste Sorting Case4. yolov26-OBB Waste Recognition Node5. Source Code Analysis5.1 GetWasteRecognitionResults — Obtain waste recognition results5.2 GraspWaste — Grasp the target waste5.3 PlaceWaste — Place the waste5.4 waste_classify Detection Node — YOLO Inference Thread6. Parameter Debugging6.1 Waste Sorting Grasping Parameters6.2 YOLO Model Detection Parameters7. Function Q&A

1. Course Content

Important

This lesson can only be used with the depth camera configuration. USB monocular camera users can skip this lesson.

Learning Objectives

  • Understand the application and configuration method of the yolov26-OBB model in waste detection.

  • Learn to use the GetWasteRecognitionResults, GraspWaste, and PlaceWaste tools to complete the waste sorting task.

  • Master the adjustment methods of key parameters such as waste_grasp_offset and waste_grasp_distance to optimize grasping precision.

2. Preparation

  • Demonstration props

    • 3 * 3 * 3 cm waste label blocks

image-20260915110229870

 

  • Start the MCP service. If you need voice replies, you must add the use_tts parameter: use_tts:=true, otherwise it can be omitted.

ros2 launch yahboomcar_bringup mcp_service.launch.py use_camera:=true use_waste_classify:=true

image-20260910094302276

 

3. Robotic Arm Waste Sorting Case

Tip

  • You can write the command yourself according to your needs. The following is a case demonstration. Just choose any one of the interaction methods. The demonstration here uses the web-based WebChat as an example.

ToolParameterFunction
GetWasteRecognitionResultsNoneObtain the waste recognition results of the YOLO model
GraspWaste--waste-nameGrasp a waste object
PlaceWasteNonePlace a waste object
  • Grasp the recyclable waste in front of you (you can also directly specify a certain piece of waste to grasp)

image-20260506141013556

 

  • Here, waste recognition is performed using the yolov26-OBB model for recognition and detection. There will be a cold start delay on the first launch, as the YOLO model needs to be loaded first.

    • The model is automatically unloaded 240 seconds after it is loaded and running, to save memory and CPU resources (the startup duration can be configured).

image-20260506120955551

  • After the model is loaded, the waste detection window automatically starts, displaying the waste recognition results.

image-20260506140734586

 

  • OpenClaw first obtains the YOLO waste recognition results through GetWasteRecognitionResults. When obtaining the results, the image of the recognition frame is automatically saved to the path:

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

image-20260506144333432

  • We can also directly obtain and view the waste detection results through the robot-control CLI (suitable for debugging).

xxxxxxxxxx
robot_control call-tool GetWasteRecognitionResults

image-20260910193810748

 

  • OpenClaw then calls the GraspWaste tool to grasp the target waste block.

xxxxxxxxxx
                                                        ┌──────────────────────┐
                                                        │Get waste recognition │
                                                        │       results        │
                                                        └──────────┬───────────┘
                                                                   │
                                                                   ▼
                                                        ┌──────────────────────┐
                                                        │Get target coordinates│
                                                        └──────────┬───────────┘
                                                                   │
                                                                   ▼
                                                        ┌──────────────────────┐
                                                        │  Grasp target waste  │
                                                        └──────────────────────┘

 

  • Target grasping skills

    • OpenClaw controls the robot to grasp the target object. It will first read the robotic arm grasping and waste sorting skills and carry out the operation by referring to the SOP process.

    • For the skill, refer to: [OpenClaw Skills Development]

  • For waste placement, in order to adapt to different waste bins, the waste placement tool completes the placement action through action groups (the placement pose can be customized through configuration parameters to adapt to different waste bins).

image-20260506142615638

image-20260911092817485

4. yolov26-OBB Waste Recognition Node

  • Waste detection is an independent program node. When starting the MCP service, the waste detection node is automatically started through the following code. To reduce CPU and memory usage, the detection enable is turned off by default at startup.

xxxxxxxxxx
    def start_waste_classify(context, *args, **kwargs):
        #find waste classify model according to different machine
        success, waste_model_path = GetWasteModelPath("waste_detect")
        if not success:
            raise Exception(f'[WARN] GetWasteModelPath failed: {waste_model_path}')
        success, device = GetYoloInferDevice()
        if not success:
            raise Exception(f'[WARN] GetWasteInferDevice failed: {device}')
        rgb_topic = GetCameraRgbTopic()
        if rgb_topic is None:
            raise Exception(f'[WARN] GetCameraRgbTopic failed: {rgb_topic}')
        return [Node(
            package="waste_classify",
            executable="waste_detect",
            name="waste_detect",
            parameters=[commom_param_file,
                        {'image_save_path': file_manager.GetFilePath("yolo_detect_image")},
                        {'model_path': waste_model_path},
                        {'show_image': True},
                        {'detect_enable': False},
                        {'device': device}
                        ],
            remappings=[('/camera/color/image_raw', rgb_topic)],
            emulate_tty=True,
            additional_env={'PYTHONPATH': venv_pythonpath + os.pathsep + original_pythonpath
            },
            output='screen')]

 

  • After the MCP service node starts, we can manually control the start and stop of the detection function through the ros service (suitable for debugging). The waste_classify node provides the following three services.

  • Query the current status (operation=0)

xxxxxxxxxx
ros2 service call /waste_enable_srv waste_classify_msg/srv/WasteEnable "{operation: 0}" 

image-20260506145500838

  • Enable waste detection (operation=1)

xxxxxxxxxx
ros2 service call /waste_enable_srv waste_classify_msg/srv/WasteEnable "{operation: 1}" 

image-20260506145556153

 

  • When detecting, the waste_classify node publishes the detection results to the /waste_detections topic. You can view the topic data with the following command.

xxxxxxxxxx
ros2 topic echo /waste_detections --once
  • Sample topic data is as follows

xxxxxxxxxx
header:
  stamp:
    sec: 1778052123
    nanosec: 473421724
  frame_id: ''
waste_detections:
- class_name: peach-pit
  classification: OtherWaste
  confidence: 0.8850700259208679
  center_x: 390.0876770019531
  center_y: 314.08135986328125
  width: 32.05992126464844
  height: 25.9763240814209
  angle: -0.02274312824010849
  points:
  - x: 406.40887451171875
    y: 326.7016296386719
  - x: 405.818115234375
    y: 300.7320251464844
  - x: 373.7664794921875
    y: 301.4610900878906
  - x: 374.35723876953125
    y: 327.4306945800781

Topic Data Meaning Description:

FieldTypeMeaning
header.stamptimeTimestamp of the detection result (sec: seconds, nanosec: nanoseconds)
waste_detectionsWasteItem[]List of detected waste objects (may contain multiple targets)
class_namestringSpecific category name of the waste (e.g., peach-pit, banana-peel, etc.)
classificationstringWaste classification type (Recyclable, KitchenWaste, OtherWaste, HazardousWaste)
confidencefloatDetection confidence (0.0~1.0); the higher the value, the more certain the model is about the detection result
center_xfloatX coordinate of the center point of the detection box (in pixels, relative to the top-left corner of the image)
center_yfloatY coordinate of the center point of the detection box (in pixels, relative to the top-left corner of the image)
widthfloatWidth of the detection box (in pixels)
heightfloatHeight of the detection box (in pixels)
anglefloatRotation angle of the detection box (in radians), a parameter unique to the OBB model, representing the orientation of the object
pointsPoint2D[]Coordinates of the 4 vertices of the rotated box (in clockwise or counter-clockwise order), used to precisely describe the object boundary

Key Concept Description:

  1. OBB (Oriented Bounding Box) rotated box: Unlike a traditional rectangular box, an OBB can rotate to better fit the actual shape of an object, making it especially suitable for irregular objects.

  2. angle: Represents the rotation angle of the object relative to the horizontal direction. When grasping, the robotic arm adjusts the gripper direction according to this angle, ensuring the grasp is made from the optimal angle.

  3. points vertex coordinates: The 4 vertices precisely describe the boundary of the rotated box and can be used to calculate the actual size and position of the object.

 

  • Disable detection (operation=2)

xxxxxxxxxx
ros2 service call /waste_enable_srv waste_classify_msg/srv/WasteEnable "{operation: 2}"

image-20260506145632824

 

5. Source Code Analysis

  • Source code path

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

5.1 GetWasteRecognitionResults — Obtain waste recognition results

Function Description: Call the YOLO model to perform waste detection and obtain the recognition results of all waste in the current field of view, including category, confidence, position, and other information.

Code Explanation:

  • GetWasteRecognitionResults: Obtain the YOLO recognition results of all waste in the current field of view.

  • waste_enable_client.wait_for_service / get_waste_client.wait_for_service: Wait for the two services, detection control and result acquisition, to come online and be available, with an 8-second timeout.

  • _pubSix_Arm([90,90,50,-30,90,0]): Move the robotic arm to the predefined detection pose to avoid the depth camera's blind spot, and wait 3 seconds to stabilize.

  • WasteEnable.Request(operation=0): Query the current detection status. detect_enable returns whether it is currently enabled.

  • WasteEnable.Request(operation=1): Enable waste detection. After enabling, wait 10 seconds to ensure the first inference is complete.

  • get_waste_client.call(GetWaste.Request()): Call the detection service to obtain the recognition results of all waste in the current field of view.

  • response.waste_detections: The list of detection results, each element containing fields such as class_name (category name), classification (waste classification), and confidence (confidence).

  • waste_recognition_result(...): Encapsulates a structured return result, containing the detection list, the total count, and the recognition frame image path.

​x
def GetWasteRecognitionResults(self) -> list:
    '''Get YOLO waste recognition results'''
    from multi_brains_pre.message.mcp_message import waste_recognition_result
    if not self.waste_enable_client.wait_for_service(timeout_sec=8.0) or not self.get_waste_client.wait_for_service(timeout_sec=8.0):
        msg = "GetWaste service not available"
        self.get_logger().error(Fore.YELLOW + msg + Fore.RESET)
        return [False, msg]

    self._pubSix_Arm([90,90,50,-30,90,0])
    time.sleep(3.0)
    
    #TODO: waste detection causes high CPU usage; enable detection only when needed, and disable after getting results
    response:WasteEnable.Response = self.waste_enable_client.call(WasteEnable.Request(operation=0))
    if not response.detect_enable:
        response:WasteEnable.Response = self.waste_enable_client.call(WasteEnable.Request(operation=1)) #enable waste detection
        if not response.success:
            msg = "Failed to enable waste detection"
            self.get_logger().error(Fore.RED + msg + Fore.RESET)
            return [False, msg]
        time.sleep(10.0)#wait for first waste detect 
    
    response:GetWaste.Response=self.get_waste_client.call(GetWaste.Request())
    if not response.success:
        msg = response.message
        self.get_logger().error(Fore.RED + msg + Fore.RESET)
        return [False, msg]

    if len(response.waste_detections) == 0:
        msg = "No waste detected"
        self.get_logger().warn(Fore.YELLOW + msg + Fore.RESET)
        return [False, msg]
    
    result_lines = []
    for i, item in enumerate(response.waste_detections, 1):
        result_lines.append(
            f"{i}. {item.class_name} ({item.classification}), "
            f"confidence: {item.confidence:.2f}")
    
    result = waste_recognition_result(
        detections=result_lines,
        total_count=len(response.waste_detections),
        yolo_detect_image=response.image_path)
    return [True, result]

Process Description:

  1. Service check: Wait for the waste_enable_srv and get_waste_srv services to be available (8-second timeout).

  2. Adjust the detection pose: Call _pubSix_Arm([90,90,50,-30,90,0]) to move the robotic arm to the predefined detection pose, and wait 3 seconds to stabilize.

  3. Start/stop detection:

    • Query the current detection status (operation=0).

    • If not started, enable detection (operation=1) and wait 10 seconds to ensure the first detection is complete.

  4. Obtain results: Call the get_waste_srv service to obtain the detection results.

  5. Result processing: Iterate over all detected waste and format the output (category, classification, confidence).

  6. Return result: Return a structured result containing the detection list, total count, and recognition image path.

Notes:

⚠️ Running the YOLO waste detection model increases CPU and memory usage, so an "on-demand start/stop" strategy is used; YOLO detection is automatically turned off a period of time after being enabled. ⚠️ After enabling detection, you need to wait a sufficient amount of time (10 seconds) to ensure the model completes the first inference. ⚠️ The robotic arm must first move to the detection pose (avoiding the depth camera's depth blind spot) before accurate recognition results can be obtained.


5.2 GraspWaste — Grasp the target waste

Code Explanation:

  • GraspWaste: Grasp the waste object with the specified name, executing the process of detection → localization → chassis adjustment → grasping → retreat.

  • _pubSix_Arm(self.waste_detect_pose): Move the robotic arm to the predefined waste detection pose.

  • _get_target_pose(waste_name, max_attempts=5): Obtain the 3D pose of the target waste, retrying up to 5 times, and returning a Pose and a WasteItem.

  • target_pose.position.x > self.waste_grasp_distance[0]: Determine whether the target X coordinate exceeds the grasping distance; if so, move the chassis forward through move_by_odom.

  • abs(target_pose.position.y) > self.waste_grasp_distance[1]: Determine whether the target Y coordinate exceeds the lateral grasping distance; if so, move the chassis left or right.

  • move_by_odom(distance, direction): Control the chassis through odometry to move the specified distance, and wait 4 seconds after moving to ensure the camera is stable.

  • adjusted_flag: The chassis adjustment flag. If the chassis has moved, call _get_target_pose again to obtain the updated 3D coordinates.

  • math.degrees(target_item.angle): Convert the rotation angle (radians) of the OBB detection box into a degree value.

  • arm_joint5_angle = 90 + math.degrees(target_item.angle): Calculate the wrist joint J5 angle according to the object orientation (90° is the neutral position); when the absolute value of the angle is ≤ 5°, keep it neutral.

  • _waste_grasp(...): Execute the actual grasping action, passing in the target 3D coordinates, the J5 angle, and the grasping pitch angle.

  • self.auto_back_dist: The automatic retreat distance after grasping is complete, to avoid collisions.

xxxxxxxxxx
def GraspWaste(self, waste_name: str) -> list[bool, str]:
    '''Grasp waste object by name'''
    self._pubSix_Arm(self.waste_detect_pose)
    time.sleep(3.0)
    result = self._get_target_pose(waste_name, max_attempts=5)
    if not result[0]:
        return [False, result[1]]

    target_pose: Pose = result[1]
    target_item: WasteItem = result[2]

    # Adjust robot position if needed
    adjusted_flag = False
    if target_pose.position.x > self.waste_grasp_distance[0]:
        adjusted_flag = True
        delta_x = target_pose.position.x - self.waste_grasp_distance[0]
        self.move_by_odom(distance=abs(delta_x), direction='forward')
        self.get_logger().info("adjust x position finish")
        time.sleep(4.0) #wait for camera to stabilize after movement

    if abs(target_pose.position.y) > self.waste_grasp_distance[1]:
        adjusted_flag = True
        delta_y = target_pose.position.y
        direction = 'left' if delta_y > 0 else 'right'
        self.move_by_odom(distance=abs(delta_y), direction=direction)
        self.get_logger().info("adjust y position finish")
        time.sleep(4.0) #wait for camera to stabilize after movement

    #  Re-acquire target pose after adjustment
    if adjusted_flag:
        result = self._get_target_pose(waste_name, max_attempts=5)
        if not result[0]:
            return [False, result[1]]

        target_pose = result[1]
        target_item: WasteItem = result[2]

    item_rotation_angle=math.degrees(target_item.angle)
    self.get_logger().debug(f"target_item_angle: {item_rotation_angle}")
    if abs(item_rotation_angle) > 5:
        #TODO: 90 degrees is the neutral position of the end effector.
        arm_joint5_angle = 90+math.degrees(target_item.angle)
    else:
        arm_joint5_angle=90

    self._waste_grasp(grasp_x=target_pose.position.x,
                      grasp_y=target_pose.position.y,
                      grasp_z=target_pose.position.z,
                      joint_5_angle=arm_joint5_angle,
                      grasp_pitch=self.waste_grasp_offset[3])

    self.move_by_odom(direction='backward', distance=self.auto_back_dist)
    return [True, "Grasp waste successfully"]

Process Description:

  1. Move to the detection pose: Call _pubSix_Arm(self.waste_detect_pose) to move the robotic arm to the predefined detection pose and wait 3 seconds.

  2. Obtain the target 3D pose: Call _get_target_pose() to obtain the 3D coordinates of the target waste, retrying up to 5 times.

  3. Chassis position adjustment:

    • If the target X coordinate exceeds waste_grasp_distance[0], move the chassis forward/backward.

    • If the target Y coordinate exceeds waste_grasp_distance[1], move the chassis left/right.

    • After each movement, wait 4 seconds to ensure the camera is stable.

  4. Re-obtain the pose: If the chassis has moved, call _get_target_pose() again to obtain the updated 3D coordinates.

  5. Calculate the gripper rotation angle:

    • Calculate the adjustment angle of joint5 (wrist yaw) according to the angle of the detection box.

    • If the absolute value of the angle is > 5°, then arm_joint5_angle = 90 + angle (90° is the neutral position).

    • Otherwise keep the neutral position (90°).

  6. Execute grasping: Call _waste_grasp() to execute the actual grasping action, passing in the 3D coordinates and joint angles.

  7. Automatic retreat: After grasping is complete, retreat by the auto_back_dist distance.

Key Technical Points:

  • Angle compensation: Adjust the gripper direction according to the rotation angle of the OBB detection box, ensuring the grasp of irregular objects is made from the optimal angle.

  • Chassis coordination: Automatically adjust the chassis position when the target exceeds the working range, ensuring the robotic arm can reach it.

  • Multiple retries: Retry up to 5 times when obtaining the pose, improving the success rate.


5.3 PlaceWaste — Place the waste

Code Explanation:

  • PlaceWaste: Place the grasped waste into the waste bin, completing the placement through a step-by-step action group.

  • SingleJoint_pub.publish(ArmJoint(id=2, joint=135, time=1200)): First move the J2 shoulder joint to 135° to raise the robotic arm.

  • SingleJoint_pub.publish(ArmJoint(id=4, joint=50, time=1200)): Move the J4 elbow joint to 50°, forming the placement pose together.

  • _pubSix_Arm(self.waste_place_pose): Move to the complete 6-joint placement pose and wait 3 seconds to ensure the motion is complete.

  • SingleJoint_pub.publish(ArmJoint(id=6, joint=0, time=1500)): Open the J6 gripper to 0° to release the waste object.

  • _pubSix_Arm(self.init_arm_pose): After placement is complete, restore the robotic arm to its initial safe pose.

  • move_by_odom(direction='backward', distance=self.auto_back_dist): The chassis automatically retreats, to avoid collisions and entering the costmap restricted area.

xxxxxxxxxx
def PlaceWaste(self):
    '''Place the grasped waste into the bin'''
    self.SingleJoint_pub.publish(ArmJoint(id=2, joint=135 , time=1200))
    self.SingleJoint_pub.publish(ArmJoint(id=4, joint=50 , time=1200))
    time.sleep(2.0)
    self._pubSix_Arm(self.waste_place_pose)
    time.sleep(3.0)
    self.SingleJoint_pub.publish(ArmJoint(id=6, joint=0 , time=1500))
    time.sleep(2.0)
    self._pubSix_Arm(self.init_arm_pose)

    self.move_by_odom(direction='backward', distance=self.auto_back_dist)
    return True

Process Description:

  1. Adjust the shoulder joint: Move joint2 to 135° to raise the robotic arm, and wait 1.2 seconds.

  2. Adjust the elbow joint: Move joint4 to 50° to prepare the placement pose, and wait 1.2 seconds.

  3. Move to the placement pose: Call _pubSix_Arm(self.waste_place_pose) to move to the complete placement pose and wait 3 seconds.

  4. Release the object: Open joint6 (the gripper) to 0° to release the waste, and wait 1.5 seconds.

  5. Restore the initial pose: Call _pubSix_Arm(self.init_arm_pose) to restore the robotic arm to the safe position.

  6. Automatic retreat: After placement is complete, retreat by the auto_back_dist distance.

Action Group Design:

  • The placement process uses a step-by-step action group, to prevent the object from dropping or collision caused by rapid movement of the robotic arm.

  • A waiting time is set after each joint movement to ensure the motion completes smoothly.


5.4 waste_classify Detection Node — YOLO Inference Thread

Source code path:

xxxxxxxxxx
~/yahboomcar_ros2_ws/yahboomcar_ws/src/waste_classify/waste_classify/waste_classify.py
  • Waste recognition detection thread inference_worker

xxxxxxxxxx
def inference_worker(model_config:Model_Configure,
                     frame_shm_name,
                     control_queue,
                     result_queue,
                     frame_shape,
                     ready_event,
                     show_image=False):
    """Inference subprocess"""
    from ultralytics import YOLO
    from ultralytics.engine.results import Results
    try:
        yolo_model = YOLO(model_config.model_path,task="obb")
    except Exception as e:
        print(Fore.RED+f"YOLO Model initialization error :{e} "+Fore.RESET)
        return False

    frame_shm = shared_memory.SharedMemory(name=frame_shm_name)
    frame_array = np.ndarray(frame_shape, dtype=np.uint8, buffer=frame_shm.buf)
    print(Fore.GREEN+'Subprocess: model loaded, waiting for inference commands...'+Fore.RESET)
    ready_event.set()

    while True:
        try:
            cmd = control_queue.get(timeout=0.1)
            if cmd == 'exit':
                print(Fore.YELLOW+'Subprocess: exit command received'+Fore.RESET)
                break
            elif cmd == 'infer':
                frame = frame_array.copy()
                results:list[Results] = yolo_model(frame,
                                     conf=model_config.conf,
                                     rect=model_config.rect,
                                     vid_stride=model_config.vid_stride,
                                     max_det=model_config.max_det,
                                     half=model_config.half,
                                     augment=model_config.augment,
                                     verbose=model_config.verbose,
                                     classes=model_config.classes,
                                     device=model_config.device
                                     )
                waste_items = []
                annotated_frame = frame
                for result in results:
                    if result.obb is None or len(result.obb) == 0:
                        continue
                    annotated_frame = result.plot()

                    xywhr = result.obb.xywhr
                    xyxyxyxy = result.obb.xyxyxyxy
                    names = [result.names[cls.item()] for cls in result.obb.cls.int()]
                    confs = result.obb.conf

                    for i in range(len(names)):
                        item = {
                            'class_name': names[i],
                            'confidence': float(confs[i]),
                            'center_x': float(xywhr[i][0]),
                            'center_y': float(xywhr[i][1]),
                            'width': float(xywhr[i][2]),
                            'height': float(xywhr[i][3]),
                            'angle': float(xywhr[i][4]),
                            'points': xyxyxyxy[i].tolist()
                        }
                        waste_items.append(item)

                if show_image:
                    cv2.imshow('Inference Result', annotated_frame)
                    cv2.waitKey(1)

                # Always put result to queue, even if empty
                result_queue.put((waste_items, annotated_frame))
        except:
            pass
    cv2.destroyAllWindows()
    frame_shm.close()

Code Explanation:

  1. Model loading: Use the ultralytics library to load the YOLO OBB model (task="obb").

  2. Shared memory: Share the camera image with the main process through shared_memory, avoiding data copying.

  3. Inference loop:

    • Receive control commands from control_queue ('exit' to exit, 'infer' to infer).

    • After receiving the 'infer' command, perform inference on the current frame.

  4. Result parsing:

    • Extract the xywhr of the OBB detection box (center point, width, height, angle).

    • Extract the 4 vertex coordinates xyxyxyxy.

    • Extract the category name and confidence.

  5. Result return: Put the detection results and the annotated frame into result_queue.

YOLO Inference Parameters:

ParameterDescriptionDefault value
confConfidence threshold; detection results below this value are filtered out0.1
rectWhether to use rectangular input (improves speed)True
vid_strideVideo frame skip stride (1 means detect every frame)1
max_detMaximum number of detection targets20
halfWhether to use half-precision FP16 inference (improves speed)True
augmentWhether to use test-time augmentation (improves accuracy)True
classesList of detection classes (0-15 correspond to 16 waste categories)[0,1,2,...,15]
deviceInference device (cuda:0 indicates GPU)"cuda:0"

 

6. Parameter Debugging

  • Parameter file path:

xxxxxxxxxx
~/yahboomcar_ros2_ws/yahboomcar_ws/src/yahboomcar_bringup/param/common.yaml

6.1 Waste Sorting Grasping Parameters

xxxxxxxxxx
mcp_service:
  ros__parameters:
    waste_grasp_offset: [0.03,-0.01,0.015,80.0]    # waste sorting grasping offset
    waste_grasp_distance: [0.10, 0.0]              # chassis alignment distance to the target x, y before waste sorting grasping
    waste_place_pose: [90, 50, 90, 50, 90, 140]    # waste sorting placement pose
    waste_detect_pose: [90, 90, 50, -30, 90, 0]    # waste sorting detection pose

Detailed Parameter Description:

ParameterTypeMeaning
waste_grasp_offset[x, y, z, angle]Grasp position offset, used to fine-tune the grasp coordinates and gripper angle
waste_grasp_distance[0]floatAlignment distance in the X direction before grasping
waste_grasp_distance[1]floatAlignment distance in the Y direction before grasping
waste_place_pose[j1, j2, j3, j4, j5, j6]The 6-joint target angles (degrees) when placing waste
waste_detect_pose[j1, j2, j3, j4, j5, j6]The 6-joint target angles (degrees) during waste detection

waste_grasp_offset Adjustment Principles:

Unlike ordinary grasping logic, waste sorting grasping needs to take the rotation angle of the object into account:

  1. X-axis offset (front-back direction): Usually 0.0; the distance is ensured by the chassis adjustment.

  2. Y-axis offset (left-right direction): Default 0.015m, to compensate for the lateral offset between the camera and the gripper.

  3. Z-axis offset (up-down direction): Default -0.02m, slightly lowering the grasp height to ensure the object is gripped.

  4. Grasp angle (the 4th parameter): Default 1.57 radians (90°), meaning the gripper is perpendicular to the table.

6.2 YOLO Model Detection Parameters

xxxxxxxxxx
waste_detect:
  ros__parameters:
    detect_enable: False              # detection is off by default at startup
    model_path: ''                    # YOLO model path
    conf: 0.1                         # confidence threshold
    vid_stride: 1                     # frame skip stride
    max_det: 20                       # maximum number of detections
    rect: True                        # rectangular input
    half: True                        # half-precision inference
    augment: True                     # test-time augmentation
    verbose: False                    # verbose log
    classes: [0,1,2,...,15]          # detection classes (16 waste categories)
    show_image: True                  # show the detection window
    image_save_path: ''               # recognition image save path
    auto_shutdown_time: 240.0         # automatic shutdown time (seconds)
    always_on: False                  # whether to always stay started

Detailed Parameter Description:

ParameterTypeMeaningDefault valueAdjustment suggestion
detect_enableboolWhether to enable detection at startupFalseFalse is recommended; start on demand to save resources
conffloatConfidence threshold (0.0~1.0)0.1Increasing it can reduce false detections, but may cause missed detections
max_detintMaximum number of targets per detection20Adjust according to the actual scenario
halfboolWhether to use FP16 half precisionTrueRecommended to enable for GPU inference, improves speed
augmentboolTest-time data augmentationTrueImproves accuracy but reduces speed; can be turned off for speed
classeslistList of detection class IDs[0-15]Can be narrowed to speed up
devicestringInference device"cuda:0"Change to "cpu" when there is no GPU
auto_shutdown_timefloatAutomatic shutdown time after no operation (seconds)240.0Adjust according to usage frequency
show_imageboolWhether to show the detection windowTrueCan be turned off during remote debugging

Performance Optimization Suggestions:

  • If there are too many false detections, you can raise conf to 0.2~0.3.

  • If there are too many missed detections, you can lower conf to 0.05~0.08, or enable augment.

 

7. Function Q&A

  • When there is a grasping error, how to correct the systematic error caused by camera measurement, servo backlash, etc.

    • Modify the grasping offset of the corresponding waste sorting field in common.yaml.

      xxxxxxxxxx
      robot_manage gui

image-20260911093407578

  • After clicking to save the parameters, they take effect immediately without restarting the program. You can then quickly verify and test again through the robot_control command.

xxxxxxxxxx
robot_control call-tool GetWasteRecognitionResults

robot_control call-tool GraspWaste --waste_name <waste_name>

 

 

 

 

OpenClaw Arm Fixed-point Placement
OpenClaw SLAM Mapping And Navigation

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/中文