基础功能编程
获取IMU信息
运行例程
开启OriginMan电源后,可以在MoboXterm或者Vscode中启动如下指令:
很快就可以在终端中看到IMU的内容发布:代码实现
实现该功能的代码文件是originman_demo/imu_print_node.py,详细的实现过程如下:
#!/usr/bin/env python3
import sys
import os
# 将当前脚本所在目录添加到 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) # 等待1秒
self.timer = self.create_timer(0.1, self.display_imu_callback) # 每0.1秒读取一次
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()
图像发布
运行例程
开启OriginMan电源后,可以在MoboXterm或者Vscode中启动如下指令:
很快就可以在终端中看到机器人发布图像的输出信息:
代码实现
实现该功能的代码文件是originman_demo/image_display_node.py,详细的实现过程如下:
#!/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()
# 创建发布者,发布 image_raw 话题
self.publisher_ = self.create_publisher(Image, 'image_raw', 10)
# 打开摄像头,0 表示默认摄像头
self.cap = cv2.VideoCapture(0)
if not self.cap.isOpened():
self.get_logger().error("无法打开摄像头")
else:
# 创建定时器,定期发布图像
self.timer = self.create_timer(0.1, self.publish_image)
def publish_image(self):
ret, frame = self.cap.read()
if ret:
try:
# 将 OpenCV 图像转换为 ROS 图像消息
ros_image = self.bridge.cv2_to_imgmsg(frame, "bgr8")
# 发布图像消息
self.publisher_.publish(ros_image)
self.get_logger().info('发布图像')
except Exception as e:
self.get_logger().error(f"Error converting image: {str(e)}")
else:
self.get_logger().error("无法读取图像帧")
def __del__(self):
# 释放摄像头资源
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()
控制oled
运行例程
开启OriginMan电源后,可以在MoboXterm或者Vscode中启动如下指令:
运行成功后,可以看到OriginMan背部的oled显示屏将会显示Wlan0的IP地址。
代码实现
实现该功能的代码文件是originman_demo/oled_display_node.py,详细的实现过程如下:
#!/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')
# 初始化OLED显示屏
self.screen = Adafruit_SSD1306.SSD1306_128_64(rst=None, i2c_bus=5, gpio=1, i2c_address=0x3C)
self.screen.begin() # 启动屏幕
self.screen.image(Image.fromarray(np.zeros((64, 128), dtype=np.uint8)).convert('1'))
self.screen.display()
# 加载字体
self.font = ImageFont.load_default()
# 创建定时器,每秒更新一次显示内容
self.timer = self.create_timer(1.0, self.update_display)
def get_wlan0_ip(self):
"""获取wlan0的IP地址,如果未连接则返回None"""
try:
# 使用ifconfig获取wlan0的IP地址
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] # 提取IP地址部分
return ip
return None # 如果没有inet行,说明未连接
except subprocess.CalledProcessError:
# 如果ifconfig wlan0失败(例如接口不存在或未启用)
return None
def update_display(self):
"""更新OLED显示内容"""
# 创建空白图像
img = Image.new('1', (self.screen.width, self.screen.height), color=0)
draw = ImageDraw.Draw(img)
# 获取wlan0的IP地址
ip_address = self.get_wlan0_ip()
if ip_address:
# 如果有IP地址,显示"IP: xxx.xxx.xxx.xxx"
display_text = f"IP: {ip_address}"
draw.text((3, 22), display_text, font=self.font, fill=255)
else:
# 如果未连接网络,显示"网络未连接"
draw.text((3, 22), "Network not connected", font=self.font, fill=255)
# 更新屏幕显示
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()