Remove the need for msgs.txt
This commit is contained in:
parent
7a423a8504
commit
15c9bb3674
19
README.md
19
README.md
|
|
@ -5,23 +5,28 @@ Minimal bindings for ROS2 that does *not* require hooking in to the ROS2 build i
|
|||
|
||||
How to use
|
||||
------------
|
||||
You need to source your ROS2 installation before building/running. A couple of examples are included in examples/
|
||||
1. Depend on this package: r2r = { git = "https://github.com/sequenceplanner/r2r" }.
|
||||
2. You need to source your ROS2 installation before building/running.
|
||||
3. The bindings will rebuild automatically if/when you source your workspaces.
|
||||
|
||||
A couple of examples are included in examples/
|
||||
```
|
||||
. /opt/ros/dashing/setup.sh
|
||||
cargo build
|
||||
cargo run --example subscriber_with_thread
|
||||
```
|
||||
In order to avoid building everything, put the message types you need in `msgs.txt` before building. (Or just `ros2 msg list > msgs.txt` if you want everything).
|
||||
|
||||
|
||||
What works?
|
||||
--------
|
||||
- Only tested with ROS2 Dashing
|
||||
- Simple publish/subscribe, see examples.
|
||||
- Up to date with ROS2 Dashing
|
||||
- Building Rust types
|
||||
- Publish/subscribe
|
||||
|
||||
TODO
|
||||
------------
|
||||
- The code generation is currently just a big hack. Needs cleanup and refactoring.
|
||||
- Implement error handling. Now all methods just return Err(()).
|
||||
- Expose more of the RCL.
|
||||
|
||||
|
||||
- Expose more of the RCL.
|
||||
- Services and action types are currently ignored.
|
||||
- QoS settings etc.
|
||||
|
|
|
|||
7
build.rs
7
build.rs
|
|
@ -6,8 +6,11 @@ use std::io::Write;
|
|||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let msgs_str = read_file("./msgs.txt").expect("You need to create msgs.txt");
|
||||
let msgs_list = parse_msgs(&msgs_str);
|
||||
println!("cargo:rerun-if-env-changed=AMENT_PREFIX_PATH");
|
||||
|
||||
let msgs = get_all_ros_msgs();
|
||||
let msgs_list = parse_msgs(&msgs);
|
||||
|
||||
let msgs = as_map(&msgs_list);
|
||||
|
||||
let mut codegen = String::new();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, Read};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RosMsg {
|
||||
|
|
@ -7,8 +11,72 @@ pub struct RosMsg {
|
|||
pub name: String, // e.g. "String"
|
||||
}
|
||||
|
||||
pub fn parse_msgs(msgs: &str) -> Vec<RosMsg> {
|
||||
let v: Vec<Vec<&str>> = msgs.lines().map(|l| l.split("/").into_iter().take(3).collect()).collect();
|
||||
// TODO: actions and srv are similiar
|
||||
pub fn get_all_ros_msgs() -> Vec<String> {
|
||||
let resource_index_subfolder = "share/ament_index/resource_index";
|
||||
let resource_type = "rosidl_interfaces";
|
||||
let ament_prefix_var_name = "AMENT_PREFIX_PATH";
|
||||
let ament_prefix_var = env::var(ament_prefix_var_name).expect("Source your ROS!");
|
||||
|
||||
let mut msgs: Vec<String> = Vec::new();
|
||||
|
||||
for ament_prefix_path in ament_prefix_var.split(":") {
|
||||
// println!("prefix: {}", ament_prefix_path);
|
||||
|
||||
let path = PathBuf::from(ament_prefix_path);
|
||||
let path = path.join(resource_index_subfolder);
|
||||
let path = path.join(resource_type);
|
||||
|
||||
if let Ok(paths) = fs::read_dir(path) {
|
||||
|
||||
for path in paths {
|
||||
// println!("PATH Name: {}", path.unwrap().path().display());
|
||||
|
||||
let path = path.unwrap().path();
|
||||
let path2 = path.clone();
|
||||
let file_name = path2.file_name().unwrap();
|
||||
|
||||
// println!("Messages for: {:?}", file_name);
|
||||
if let Ok(mut file) = File::open(path) {
|
||||
let mut s = String::new();
|
||||
file.read_to_string(&mut s).unwrap();
|
||||
let lines = s.lines();
|
||||
|
||||
lines.for_each(|l| {
|
||||
if l.starts_with("msg/") && (l.ends_with(".idl") || l.ends_with(".msg")) {
|
||||
if let Some(file_name_str) = file_name.to_str() {
|
||||
let substr = &l[4..l.len()-4];
|
||||
let msg_name = format!("{}/msg/{}", file_name_str, substr);
|
||||
msgs.push(msg_name);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msgs.sort();
|
||||
msgs.dedup();
|
||||
|
||||
return msgs;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_msg_list() {
|
||||
|
||||
let msgs = get_all_ros_msgs();
|
||||
for m in &msgs {
|
||||
println!("{}", m);
|
||||
}
|
||||
|
||||
assert!(msgs.contains(&"std_msgs/msg/String".to_string()));
|
||||
assert!(msgs.contains(&"builtin_interfaces/msg/Time".to_string()));
|
||||
|
||||
}
|
||||
|
||||
pub fn parse_msgs(msgs: &Vec<String>) -> Vec<RosMsg> {
|
||||
let v: Vec<Vec<&str>> = msgs.iter().map(|l| l.split("/").into_iter().take(3).collect()).collect();
|
||||
v.iter().filter(|v|v.len() == 3).
|
||||
map(|v| RosMsg { module: v[0].into(), prefix: v[1].into(), name: v[2].into()}).collect()
|
||||
|
||||
|
|
@ -23,16 +91,6 @@ pub fn as_map(included_msgs: &[RosMsg]) -> HashMap<&str, HashMap<&str, Vec<&str>
|
|||
msgs
|
||||
}
|
||||
|
||||
use std::io::{self, Read};
|
||||
use std::fs::File;
|
||||
|
||||
pub fn read_file(filename: &str) -> io::Result<String> {
|
||||
let mut file = File::open(filename)?;
|
||||
let mut s = String::new();
|
||||
file.read_to_string(&mut s)?;
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
@ -65,10 +123,9 @@ std_msgs/msg/String
|
|||
|
||||
assert_eq!(map.get("std_msgs").unwrap().get("msg").unwrap()[0], "Bool");
|
||||
assert_eq!(map.get("std_msgs").unwrap().get("msg").unwrap()[1], "String");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ use std::path::PathBuf;
|
|||
use common::*;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=../msgs.txt");
|
||||
println!("cargo:rerun-if-env-changed=AMENT_PREFIX_PATH");
|
||||
|
||||
let msgs = read_file("../msgs.txt").expect("You need to create msgs.txt");
|
||||
let msgs = get_all_ros_msgs();
|
||||
let msg_list = parse_msgs(&msgs);
|
||||
let msg_map = as_map(&msg_list);
|
||||
|
||||
|
|
|
|||
15
msgs.txt
15
msgs.txt
|
|
@ -1,15 +0,0 @@
|
|||
builtin_interfaces/msg/Duration
|
||||
builtin_interfaces/msg/Time
|
||||
geometry_msgs/msg/Vector3
|
||||
geometry_msgs/msg/AccelWithCovariance
|
||||
geometry_msgs/msg/Accel
|
||||
std_msgs/msg/String
|
||||
std_msgs/msg/Bool
|
||||
std_msgs/msg/Int32
|
||||
std_msgs/msg/UInt32
|
||||
std_msgs/msg/Header
|
||||
trajectory_msgs/msg/JointTrajectory
|
||||
trajectory_msgs/msg/JointTrajectoryPoint
|
||||
shape_msgs/msg/SolidPrimitive
|
||||
|
||||
|
||||
|
|
@ -4,6 +4,8 @@ use std::env;
|
|||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-env-changed=AMENT_PREFIX_PATH");
|
||||
|
||||
let mut builder = bindgen::Builder::default()
|
||||
.header("src/rcl_wrapper.h")
|
||||
.derive_copy(false)
|
||||
|
|
|
|||
Loading…
Reference in New Issue