Skip to content

Basic Programming Functions

Getting IMU Information

Running the Example

After powering on OriginMan, you can start the following command in MoboXterm or VSCode:

ros2 run originman_demo imu_print_node

You will quickly see the IMU content being published in the terminal:

image-20220923124715971

Code Implementation

The code implementing this functionality is in originman_demo/imu_print_node.py. Here's the detailed implementation:

#!/usr/bin/env python3
import sys
import os
# Add current script directory to sys.path
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

import rclpy
from rclpy.node import Node
import time
from ros_robot_controller_sdk import Board


class IMUDisplayNode(Node):
    def __init__(self):
        super().__init__('imu_print_node')
        self.board = Board(device="/dev/ttyS1", baudrate=1000000) 
        self.board.enable_reception()
        self.get_logger().info("Board initialized")
        time.sleep(1)  # Wait for 1 second
        self.timer = self.create_timer(0.1, self.display_imu_callback)  # Read every 0.1 seconds

    def display_imu_callback(self):
        imu_data = self.board.get_imu()
        if imu_data is not None:
            ax, ay, az, gx, gy, gz = imu_data
            self.get_logger().info(f"IMU - Accel: ({ax:.2f}, {ay:.2f}, {az:.2f}) g, Gyro: ({gx:.2f}, {gy:.2f}, {gz:.2f}) deg/s")


def main(args=None):
    rclpy.init(args=args)
    imu_print_node = IMUDisplayNode()
    rclpy.spin(imu_print_node)
    imu_print_node.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

Image Publishing

Running the Example

After powering on OriginMan, you can start the following command in MoboXterm or VSCode:

ros2 run originman_demo image_display_node

You will quickly see the robot's image publishing output information in the terminal:

image-20220923124819442

Code Implementation

The code implementing this functionality is in originman_demo/image_display_node.py. Here's the detailed implementation:

#!/usr/bin/env python3
# encoding:utf-8
import rclpy
from rclpy.node import Node
import cv2
from cv_bridge import CvBridge
from sensor_msgs.msg import Image


class ImagePublisherNode(Node):
    def __init__(self):
        super().__init__('image_publisher_node')
        self.bridge = CvBridge()
        # Create publisher for image_raw topic
        self.publisher_ = self.create_publisher(Image, 'image_raw', 10)
        # Open camera, 0 represents default camera
        self.cap = cv2.VideoCapture(0)
        if not self.cap.isOpened():
            self.get_logger().error("Cannot open camera")
        else:
            # Create timer to publish images periodically
            self.timer = self.create_timer(0.1, self.publish_image)

    def publish_image(self):
        ret, frame = self.cap.read()
        if ret:
            try:
                # Convert OpenCV image to ROS image message
                ros_image = self.bridge.cv2_to_imgmsg(frame, "bgr8")
                # Publish image message
                self.publisher_.publish(ros_image)
                self.get_logger().info('Publishing image')
            except Exception as e:
                self.get_logger().error(f"Error converting image: {str(e)}")
        else:
            self.get_logger().error("Cannot read image frame")

    def __del__(self):
        # Release camera resources
        if self.cap.isOpened():
            self.cap.release()


def main(args=None):
    rclpy.init(args=args)
    image_publisher_node = ImagePublisherNode()
    rclpy.spin(image_publisher_node)
    image_publisher_node.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

Controlling OLED

Running the Example

After powering on OriginMan, you can start the following command in MoboXterm or VSCode:

ros2 run originman_demo oled_display_node

After successful execution, you will see the Wlan0 IP address displayed on the OLED screen on the back of OriginMan.

image-20220923124819442

Code Implementation

The code implementing this functionality is in originman_demo/oled_display_node.py. Here's the detailed implementation:

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
import time
import numpy as np
import Adafruit_SSD1306
from PIL import Image, ImageDraw, ImageFont
import socket
import subprocess


class OledDisplayNode(Node):
    def __init__(self):
        super().__init__('oled_display_node')
        # Initialize OLED display
        self.screen = Adafruit_SSD1306.SSD1306_128_64(rst=None, i2c_bus=5, gpio=1, i2c_address=0x3C)
        self.screen.begin()  # Start screen
        self.screen.image(Image.fromarray(np.zeros((64, 128), dtype=np.uint8)).convert('1'))
        self.screen.display()

        # Load font
        self.font = ImageFont.load_default()

        # Create timer to update display content every second
        self.timer = self.create_timer(1.0, self.update_display)

    def get_wlan0_ip(self):
        """Get wlan0 IP address, return None if not connected"""
        try:
            # Use ifconfig to get wlan0 IP address
            result = subprocess.check_output(["ifconfig", "wlan0"], text=True)
            for line in result.split('\n'):
                if "inet " in line:
                    ip = line.split('inet ')[1].split(' ')[0]  # Extract IP address part
                    return ip
            return None  # If no inet line, means not connected
        except subprocess.CalledProcessError:
            # If ifconfig wlan0 fails (e.g., interface doesn't exist or not enabled)
            return None

    def update_display(self):
        """Update OLED display content"""
        # Create blank image
        img = Image.new('1', (self.screen.width, self.screen.height), color=0)
        draw = ImageDraw.Draw(img)

        # Get wlan0 IP address
        ip_address = self.get_wlan0_ip()

        if ip_address:
            # If IP address exists, display "IP: xxx.xxx.xxx.xxx"
            display_text = f"IP: {ip_address}"
            draw.text((3, 22), display_text, font=self.font, fill=255)
        else:
            # If not connected to network, display "Network not connected"
            draw.text((3, 22), "Network not connected", font=self.font, fill=255)

        # Update screen display
        self.screen.image(img)
        self.screen.display()


def main(args=None):
    rclpy.init(args=args)
    oled_display_node = OledDisplayNode()
    rclpy.spin(oled_display_node)
    oled_display_node.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

Image1