Rust机器人动作库r2r_actions的使用:高效实现机器人控制与自动化任务
Rust机器人动作库r2r_actions的使用:高效实现机器人控制与自动化任务
r2r_actions是r2r的内部依赖库,主要用于机器人控制和自动化任务。
安装
在项目目录中运行以下Cargo命令:
cargo add r2r_actions
或者在你的Cargo.toml中添加以下行:
r2r_actions = "0.9.5"
元数据
- 版本:0.9.5
- 发布时间:4个月前
- 2021 edition
- 许可证:MIT
- 大小:8.28 KiB
所有者
- Martin Dahl (m-dahl)
示例代码
以下是一个使用r2r_actions库的基本示例:
use r2r_actions::ActionServer;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建一个动作服务器
let mut action_server = ActionServer::new()?;
// 定义机器人动作
action_server.register_action("move_arm", |params| {
println!("Moving arm with parameters: {:?}", params);
// 这里实现实际的机器人手臂移动逻辑
Ok(())
});
// 定义另一个动作
action_server.register_action("gripper_control", |params| {
println!("Controlling gripper with parameters: {:?}", params);
// 这里实现实际的夹爪控制逻辑
Ok(())
});
// 启动动作服务器
action_server.run()?;
Ok(())
}
这个示例展示了如何:
- 创建一个动作服务器
- 注册自定义机器人动作
- 启动服务器处理动作请求
完整示例代码
下面是一个更完整的示例,展示了如何使用r2r_actions实现机器人控制:
use r2r_actions::ActionServer;
use std::collections::HashMap;
use std::time::Duration;
// 定义机器人状态结构体
struct RobotState {
arm_position: f32,
gripper_open: bool,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 初始化机器人状态
let mut robot_state = RobotState {
arm_position: 0.0,
gripper_open: false,
};
// 创建动作服务器
let mut action_server = ActionServer::new()?;
// 注册移动手臂动作
action_server.register_action("move_arm", move |params: HashMap<String, String>| {
// 解析参数
let target_pos = params.get("position")
.and_then(|v| v.parse::<f32>().ok())
.unwrap_or(0.0);
println!("Moving arm to position: {}", target_pos);
// 模拟移动过程
std::thread::sleep(Duration::from_secs(1));
// 更新机器人状态
robot_state.arm_position = target_pos;
Ok(())
});
// 注册夹爪控制动作
action_server.register_action("gripper_control", |params: HashMap<String, String>| {
// 解析参数
let action = params.get("action").map(|s| s.as_str()).unwrap_or("");
match action {
"open" => {
println!("Opening gripper");
robot_state.gripper_open = true;
}
"close" => {
println!("Closing gripper");
robot_state.gripper_open = false;
}
_ => println!("Unknown gripper action"),
}
Ok(())
});
// 注册状态查询动作
action_server.register_action("get_status", |_params| {
println!("Current status - Arm position: {}, Gripper: {}",
robot_state.arm_position,
if robot_state.gripper_open { "open" } else { "closed" }
);
Ok(())
});
println!("Robot action server started. Ready to receive commands...");
// 启动动作服务器
action_server.run()?;
Ok(())
}
这个完整示例展示了:
- 定义机器人状态结构体
- 实现更复杂的动作处理逻辑
- 处理不同类型的动作参数
- 模拟实际的机器人动作执行
- 状态查询功能
你可以根据实际需求进一步扩展这个示例,添加更多动作类型和更复杂的控制逻辑。
1 回复
Rust机器人动作库r2r_actions的使用:高效实现机器人控制与自动化任务
以下是基于r2r_actions库的完整机器人控制示例demo,展示了如何实现一个完整的机器人导航系统:
use r2r_actions::prelude::*;
use async_trait::async_trait;
use r2r_actions::{ActionSequence, ActionParallel};
use r2r::{Context, Node};
use r2r_actions::ros2::RosAction;
// 定义基本机器人动作
#[derive(Debug)]
struct MoveAction {
distance: f32,
}
#[derive(Debug)]
struct TurnAction {
angle: f32, // 角度,单位度
}
#[derive(Debug)]
struct ScanAction {
duration: f32, // 扫描持续时间,单位秒
}
// 实现移动动作
#[async_trait]
impl Action for MoveAction {
type Result = f32;
async fn execute(&mut self) -> Result<Self::Result, ActionError> {
println!("开始移动 {} 米...", self.distance);
// 模拟移动过程
for i in 1..=10 {
let progress = i as f32 / 10.0 * self.distance;
println!("移动进度: {:.1} 米", progress);
tokio::time::sleep(std::time::Duration::from_millis(300)).await;
// 模拟障碍检测
if progress > self.distance * 0.8 {
return Err(ActionError::new("检测到障碍物!"));
}
}
println!("移动完成!");
Ok(self.distance)
}
}
// 实现旋转动作
#[async_trait]
impl Action for TurnAction {
type Result = f32;
async fn execute(&mut self) -> Result<Self::Result, ActionError> {
println!("开始旋转 {} 度...", self.angle);
tokio::time::sleep(std::time::Duration::from_secs_f32(self.angle.abs() / 90.0)).await;
println!("旋转完成!");
Ok(self.angle)
}
}
// 实现扫描动作
#[async_trait]
impl Action for ScanAction {
type Result = Vec<f32>; // 返回扫描到的障碍物距离
async fn execute(&mut self) -> Result<Self::Result, ActionError> {
println!("开始环境扫描,持续 {} 秒...", self.duration);
tokio::time::sleep(std::time::Duration::from_secs_f32(self.duration)).await;
// 模拟返回扫描结果
let obstacles = vec![1.5, 2.8, 0.7];
println!("扫描完成,发现 {} 个障碍物", obstacles.len());
Ok(obstacles)
}
}
// 定义高级导航动作
struct NavigateToPoint {
x: f32,
y: f32,
}
#[async_trait]
impl Action for NavigateToPoint {
type Result = (f32, f32); // 返回实际到达的坐标
async fn execute(&mut self) -> Result<Self::Result, ActionError> {
println!("开始导航到坐标 ({}, {})", self.x, self.y);
// 计算需要旋转的角度和移动的距离
let angle = self.y.atan2(self.x).to_degrees();
let distance = (self.x.powi(2) + self.y.powi(2)).sqrt();
// 创建动作序列:先旋转,再移动
let mut sequence = ActionSequence::new();
sequence.add(TurnAction { angle });
sequence.add(MoveAction { distance });
// 执行动作序列
sequence.execute().await?;
// 返回最终位置
Ok((self.x, self.y))
}
}
// 主函数
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== 机器人控制系统启动 ===");
// 示例1: 执行单个动作
println!("\n1. 测试移动动作:");
let move_act = MoveAction { distance: 2.0 };
match move_act.execute().await {
Ok(d) => println!("成功移动了 {} 米", d),
Err(e) => println!("移动失败: {}", e),
}
// 示例2: 执行动作序列
println!("\n2. 测试动作序列:");
let mut seq = ActionSequence::new();
seq.add(TurnAction { angle: 90.0 });
seq.add(MoveAction { distance: 1.5 });
seq.add(TurnAction { angle: -45.0 });
seq.add(MoveAction { distance: 1.0 });
match seq.execute().await {
Ok(_) => println!("所有动作执行完成!"),
Err(e) => println!("动作序列执行失败: {}", e),
}
// 示例3: 并行执行动作
println!("\n3. 测试并行动作:");
let mut parallel = ActionParallel::new();
parallel.add(MoveAction { distance: 1.0 });
parallel.add(ScanAction { duration: 2.0 });
match parallel.execute().await {
Ok(results) => println!("并行动作结果: {:?}", results),
Err(e) => println!("并行执行失败: {}", e),
}
// 示例4: 高级导航
println!("\n4. 测试导航功能:");
let nav_action = NavigateToPoint { x: 3.0, y: 4.0 };
match nav_action.execute().await {
Ok((x, y)) => println!("成功导航到坐标 ({}, {})", x, y),
Err(e) => println!("导航失败: {}", e),
}
// 示例5: 与ROS 2集成
println!("\n5. 测试ROS 2集成:");
let ctx = Context::create()?;
let node = Node::create(ctx, "robot_controller", "")?;
// 创建ROS 2动作客户端 (这里需要实际的ROS 2环境)
let move_client = RosAction::new(
node.clone(),
"move_robot",
"robot_control_msgs/action/Move"
)?;
// 执行ROS动作 (这里需要实际的ROS 2服务)
let goal = MoveGoal { distance: 1.5 };
match move_client.execute(goal).await {
Ok(result) => println!("ROS动作执行结果: {:?}", result),
Err(e) => println!("ROS动作执行失败: {}", e),
}
println!("\n=== 机器人控制系统关闭 ===");
Ok(())
}
这个完整示例展示了:
- 定义了三种基本机器人动作:移动、旋转和扫描
- 实现了高级导航动作,组合基本动作形成复杂行为
- 演示了单个动作、动作序列和并行动作的执行
- 展示了与ROS 2集成的代码
- 包含了完整的错误处理机制
要运行此代码,需要:
- 安装Rust和Cargo
- 在Cargo.toml中添加r2r_actions和tokio依赖
- 对于ROS 2集成部分,需要安装ROS 2和r2r库
这个示例可以作为机器人控制应用的起点,您可以根据实际需求扩展更多动作类型和复杂行为。