golang机器人操作系统(ROS)功能实现插件库goroslib的使用

golang机器人操作系统(ROS)功能实现插件库goroslib的使用

简介

goroslib 是一个纯 Go 语言实现的库,用于构建机器人操作系统(ROS)的客户端(节点)。ROS 是一个项目,提供了一套规范,使多个程序能够通过主题(topic)、服务(service)、动作(action)和参数(parameter)相互通信,交换结构化数据。

功能特性

  • 通过 TCP 或 UDP 发布和订阅主题
  • 提供和调用服务
  • 提供和调用动作
  • 提供和调用简单动作
  • 获取和设置参数
  • 支持命名空间和相对主题
  • 支持 IPv6(仅限有状态地址)
  • 支持时间 API
  • 不需要编译 .msg 文件,直接从代码中提取消息定义
  • 可以编译或交叉编译到所有 Go 支持的操作系统(Linux、Windows、Mac OS X)和架构
  • 为每个功能提供示例,全面的测试套件,持续集成

安装

  1. 安装 Go ≥ 1.23
  2. 创建一个空文件夹,打开终端并初始化 Go 模块系统:
    go mod init main
    
  3. 下载其中一个示例文件并放入文件夹
  4. 编译并运行(需要先运行 ROS master):
    go run name-of-the-go-file.go
    

示例代码

订阅者示例

package main

import (
	"fmt"
	"time"

	"github.com/bluenviron/goroslib/v2"
	"github.com/bluenviron/goroslib/v2/pkg/msgs/std_msgs"
)

func main() {
	// 创建节点
	n, err := goroslib.NewNode(goroslib.NodeConf{
		Name:          "goroslib_sub",
		MasterAddress: "127.0.0.1:11311",
	})
	if err != nil {
		panic(err)
	}
	defer n.Close()

	// 创建订阅者
	sub, err := goroslib.NewSubscriber(goroslib.SubscriberConf{
		Node:     n,
		Topic:    "test_topic",
		Callback: func(msg *std_msgs.String) {
			fmt.Printf("Received: %s\n", msg.Data)
		},
	})
	if err != nil {
		panic(err)
	}
	defer sub.Close()

	// 保持运行
	time.Sleep(time.Second * 10)
}

发布者示例

package main

import (
	"time"

	"github.com/bluenviron/goroslib/v2"
	"github.com/bluenviron/goroslib/v2/pkg/msgs/std_msgs"
)

func main() {
	// 创建节点
	n, err := goroslib.NewNode(goroslib.NodeConf{
		Name:          "goroslib_pub",
		MasterAddress: "127.0.0.1:11311",
	})
	if err != nil {
		panic(err)
	}
	defer n.Close()

	// 创建发布者
	pub, err := goroslib.NewPublisher(goroslib.PublisherConf{
		Node:  n,
		Topic: "test_topic",
		Msg:   &std_msgs.String{},
	})
	if err != nil {
		panic(err)
	}
	defer pub.Close()

	// 发布消息
	for {
		msg := &std_msgs.String{
			Data: "hello world",
		}
		fmt.Printf("Publishing: %s\n", msg.Data)
		pub.Write(msg)
		time.Sleep(time.Second)
	}
}

自定义消息、服务和动作

自定义消息

import (
	"github.com/bluenviron/goroslib/v2/pkg/msgs"
)

type MessageName struct {
	msg.Package `ros:"my_package"`
	Field1 bool
	Field2 int32
}

自定义服务

type ServiceNameReq struct {
	Input uint32
}

type ServiceNameRes struct {
	Output uint32
}

type ServiceName struct {
	msg.Package `ros:"my_package"`
	ServiceNameReq
	ServiceNameRes
}

自定义动作

type ActionNameGoal struct {
	Goal uint32
}

type ActionNameResult struct {
	Result uint32
}

type ActionNameFeedback struct {
	Feedback uint32
}

type ActionName struct {
	msg.Package `ros:"my_package"`
	ActionNameGoal
	ActionNameResult
	ActionNameFeedback
}

导入现有消息、服务和动作

可以使用以下工具将现有的 .msg.srv.action 文件转换为 Go 结构:

# 安装工具
go install github.com/bluenviron/goroslib/v2/cmd/msg-import@latest
go install github.com/bluenviron/goroslib/v2/cmd/srv-import@latest
go install github.com/bluenviron/goroslib/v2/cmd/action-import@latest

# 转换消息
msg-import --rospackage=my_package mymessage.msg > mymessage.go

# 转换服务
srv-import --rospackage=my_package myservice.srv > myservice.go

# 转换动作
action-import --rospackage=my_package myaction.action > myaction.go

跨平台编译

要为其他操作系统编译节点,可以使用标准的 Go 交叉编译方法。例如,要为 Windows 编译:

GOOS=windows GOARCH=amd64 go build -o node.exe name-of-source-file.go

注意事项

2025年5月31日,ROS 1(与此库兼容的 ROS 发行版)将到达生命周期终点。使此库与 ROS 2 兼容需要大量工作,因此我们被迫归档 goroslib。


更多关于golang机器人操作系统(ROS)功能实现插件库goroslib的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang机器人操作系统(ROS)功能实现插件库goroslib的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang机器人操作系统(ROS)功能实现插件库goroslib使用指南

goroslib简介

goroslib是Go语言实现的ROS(机器人操作系统)客户端库,允许Go程序与ROS系统进行交互。它支持ROS的核心功能,包括:

  • 发布/订阅消息
  • 服务调用
  • 参数服务器操作
  • 动作服务器/客户端

安装

go get github.com/aler9/goroslib

基本使用示例

1. 发布者(Publisher)

package main

import (
	"fmt"
	"time"

	"github.com/aler9/goroslib"
	"github.com/aler9/goroslib/pkg/msgs/std_msgs"
)

func main() {
	// 创建节点
	node, err := goroslib.NewNode(goroslib.NodeConf{
		Name:          "/gopublisher",
		MasterAddress: "127.0.0.1:11311",
	})
	if err != nil {
		panic(err)
	}
	defer node.Close()

	// 创建发布者
	pub, err := goroslib.NewPublisher(goroslib.PublisherConf{
		Node:  node,
		Topic: "/test_topic",
		Msg:   &std_msgs.String{},
	})
	if err != nil {
		panic(err)
	}
	defer pub.Close()

	// 发布消息
	for i := 0; i < 10; i++ {
		msg := &std_msgs.String{
			Data: fmt.Sprintf("hello %d", i),
		}
		fmt.Printf("Publishing: %s\n", msg.Data)
		pub.Write(msg)
		time.Sleep(1 * time.Second)
	}
}

2. 订阅者(Subscriber)

package main

import (
	"fmt"

	"github.com/aler9/goroslib"
	"github.com/aler9/goroslib/pkg/msgs/std_msgs"
)

func main() {
	// 创建节点
	node, err := goroslib.NewNode(goroslib.NodeConf{
		Name:          "/gosubscriber",
		MasterAddress: "127.0.0.1:11311",
	})
	if err != nil {
		panic(err)
	}
	defer node.Close()

	// 创建订阅者
	sub, err := goroslib.NewSubscriber(goroslib.SubscriberConf{
		Node:     node,
		Topic:    "/test_topic",
		Callback: func(msg *std_msgs.String) {
			fmt.Printf("Received: %s\n", msg.Data)
		},
	})
	if err != nil {
		panic(err)
	}
	defer sub.Close()

	// 保持运行
	select {}
}

3. 服务服务器(Service Server)

package main

import (
	"fmt"

	"github.com/aler9/goroslib"
	"github.com/aler9/goroslib/pkg/msgs/std_srvs"
)

func main() {
	// 创建节点
	node, err := goroslib.NewNode(goroslib.NodeConf{
		Name:          "/goservice_server",
		MasterAddress: "127.0.0.1:11311",
	})
	if err != nil {
		panic(err)
	}
	defer node.Close()

	// 创建服务服务器
	srv, err := goroslib.NewServiceServer(goroslib.ServiceServerConf{
		Node: node,
		Name: "/test_service",
		Srv:  &std_srvs.SetBool{},
		Callback: func(req *std_srvs.SetBoolReq) *std_srvs.SetBoolRes {
			fmt.Printf("Request received: %v\n", req.Data)
			return &std_srvs.SetBoolRes{
				Success: true,
				Message: "processed",
			}
		},
	})
	if err != nil {
		panic(err)
	}
	defer srv.Close()

	// 保持运行
	select {}
}

4. 服务客户端(Service Client)

package main

import (
	"fmt"
	"time"

	"github.com/aler9/goroslib"
	"github.com/aler9/goroslib/pkg/msgs/std_srvs"
)

func main() {
	// 创建节点
	node, err := goroslib.NewNode(goroslib.NodeConf{
		Name:          "/goservice_client",
		MasterAddress: "127.0.0.1:11311",
	})
	if err != nil {
		panic(err)
	}
	defer node.Close()

	// 创建服务客户端
	cli, err := goroslib.NewServiceClient(goroslib.ServiceClientConf{
		Node: node,
		Name: "/test_service",
		Srv:  &std_srvs.SetBool{},
	})
	if err != nil {
		panic(err)
	}
	defer cli.Close()

	// 等待服务可用
	for {
		time.Sleep(1 * time.Second)
		if cli.IsServiceAvailable() {
			break
		}
		fmt.Println("waiting for service...")
	}

	// 调用服务
	req := std_srvs.SetBoolReq{
		Data: true,
	}
	res := std_srvs.SetBoolRes{}
	err = cli.Call(&req, &res)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Response: %v\n", res)
}

高级功能

自定义消息类型

创建自定义消息文件MyMessage.msg:

string first_name
string last_name
uint8 age
float32 score

然后使用goroslib-msg工具生成Go代码:

goroslib-msg generate MyMessage.msg

参数服务器操作

// 设置参数
err := node.ParamSet("/my_param", "value")
if err != nil {
    panic(err)
}

// 获取参数
val, err := node.ParamGet("/my_param")
if err != nil {
    panic(err)
}
fmt.Println("Parameter value:", val)

注意事项

  1. 确保ROS master正在运行(roscore)
  2. 不同语言间的消息类型必须完全匹配
  3. 注意goroslib与ROS版本的兼容性
  4. 生产环境中需要考虑错误处理和重连机制

goroslib为Go开发者提供了与ROS系统交互的能力,使得可以使用Go语言开发机器人应用,充分利用Go语言的高效和并发特性。

回到顶部