#![allow(dead_code)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(deref_nullptr)]
#![allow(non_snake_case)]
#![allow(improper_ctypes)]
#![allow(unused_imports)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::too_many_arguments)]
#![allow(clippy::manual_c_str_literals)]
#![allow(clippy::useless_conversion)]
#[cfg(feature = "rcl")]
pub mod rcl {
pub use crate::runtime_c::*;
}
pub mod primitives;
pub mod strings;
#[cfg(feature = "rcl")]
mod runtime_c {
include!(concat!(env!("OUT_DIR"), "/runtime_c.rs"));
}
#[cfg(feature = "rcl")]
pub use runtime_c::*;
pub mod msg {
pub use crate::primitives::{
BoolSeq, ByteSeq, F32Seq, F64Seq, I8Seq, I16Seq, I32Seq, I64Seq, U8Seq, U16Seq, U32Seq,
U64Seq,
};
pub use crate::strings::{RosString, RosStringSeq, RosWString, RosWStringSeq};
pub use oxidros_core::TypeSupport;
}
pub mod builtin_interfaces {
pub use oxidros_core::{UnsafeDuration, UnsafeTime};
}
pub use ros2_types::{
Ros2Msg, SequenceRaw, ServiceMsg, TryClone, TypeSupport, ros2_action, ros2_service,
};
#[rustfmt::skip]
pub mod common_interfaces {
include!(concat!(env!("OUT_DIR"), "/generated/common_interfaces/mod.rs"));
}
#[rustfmt::skip]
pub mod interfaces {
include!(concat!(env!("OUT_DIR"), "/generated/interfaces/mod.rs"));
}
#[rustfmt::skip]
pub mod ros2msg {
include!(concat!(env!("OUT_DIR"), "/generated/ros2msg/mod.rs"));
}
pub use ros2msg::*;
pub use oxidros_core;
pub use oxidros_core::{
ActionGoal, ActionMsg, ActionResult, GetUUID, GoalResponse, ResultResponse,
};
pub use oxidros_core::{UnsafeDuration, UnsafeTime};
use crate::interfaces::rcl_interfaces::msg::ParameterValue;
use crate::msg::{BoolSeq, ByteSeq, F64Seq, I64Seq, RosString, RosStringSeq};
use oxidros_core::Value;
impl From<&oxidros_core::parameter::IntegerRange>
for interfaces::rcl_interfaces::msg::IntegerRange
{
fn from(range: &oxidros_core::parameter::IntegerRange) -> Self {
interfaces::rcl_interfaces::msg::IntegerRange {
from_value: range.min,
to_value: range.max,
step: range.step as u64,
}
}
}
impl From<&oxidros_core::parameter::FloatingPointRange>
for interfaces::rcl_interfaces::msg::FloatingPointRange
{
fn from(range: &oxidros_core::parameter::FloatingPointRange) -> Self {
interfaces::rcl_interfaces::msg::FloatingPointRange {
from_value: range.min,
to_value: range.max,
step: range.step,
}
}
}
impl From<&ParameterValue> for Value {
fn from(var: &ParameterValue) -> Self {
match var.r#type {
1 => Value::Bool(var.bool_value),
2 => Value::I64(var.integer_value),
3 => Value::F64(var.double_value),
4 => Value::String(var.string_value.to_string()),
5 => {
let mut v = Vec::new();
var.byte_array_value.iter().for_each(|x| v.push(*x));
Value::VecU8(v)
}
6 => {
let mut v = Vec::new();
var.bool_array_value.iter().for_each(|x| v.push(*x));
Value::VecBool(v)
}
7 => {
let mut v = Vec::new();
var.integer_array_value.iter().for_each(|x| v.push(*x));
Value::VecI64(v)
}
8 => {
let mut v = Vec::new();
var.double_array_value.iter().for_each(|x| v.push(*x));
Value::VecF64(v)
}
9 => {
let mut v = Vec::new();
var.string_array_value
.iter()
.for_each(|x| v.push(x.to_string()));
Value::VecString(v)
}
_ => Value::NotSet,
}
}
}
impl From<&Value> for ParameterValue {
fn from(var: &Value) -> Self {
let mut result = ParameterValue::new().unwrap();
match var {
Value::NotSet => result.r#type = 0,
Value::Bool(val) => {
result.r#type = 1;
result.bool_value = *val;
}
Value::I64(val) => {
result.r#type = 2;
result.integer_value = *val;
}
Value::F64(val) => {
result.r#type = 3;
result.double_value = *val;
}
Value::String(val) => {
result.r#type = 4;
result.string_value = RosString::new(val).unwrap_or_else(|| {
log::error!("{}:{}: failed allocation", file!(), line!());
RosString::null()
});
}
Value::VecU8(val) => {
result.r#type = 5;
result.byte_array_value = ByteSeq::new(val.len()).unwrap_or_else(|| {
log::error!("{}:{}: failed allocation", file!(), line!());
ByteSeq::null()
});
result
.byte_array_value
.iter_mut()
.zip(val.iter())
.for_each(|(dst, src)| *dst = *src);
}
Value::VecBool(val) => {
result.r#type = 6;
result.bool_array_value = BoolSeq::new(val.len()).unwrap_or_else(|| {
log::error!("{}:{}: failed allocation", file!(), line!());
BoolSeq::null()
});
result
.bool_array_value
.iter_mut()
.zip(val.iter())
.for_each(|(dst, src)| *dst = *src);
}
Value::VecI64(val) => {
result.r#type = 7;
result.integer_array_value = I64Seq::new(val.len()).unwrap_or_else(|| {
log::error!("{}:{}: failed allocation", file!(), line!());
I64Seq::null()
});
result
.integer_array_value
.iter_mut()
.zip(val.iter())
.for_each(|(dst, src)| *dst = *src);
}
Value::VecF64(val) => {
result.r#type = 8;
result.double_array_value = F64Seq::new(val.len()).unwrap_or_else(|| {
log::error!("{}:{}: failed allocation", file!(), line!());
F64Seq::null()
});
result
.double_array_value
.iter_mut()
.zip(val.iter())
.for_each(|(dst, src)| *dst = *src);
}
Value::VecString(val) => {
result.r#type = 9;
result.string_array_value = RosStringSeq::new(val.len()).unwrap_or_else(|| {
log::error!("{}:{}: failed allocation", file!(), line!());
RosStringSeq::null()
});
result
.string_array_value
.iter_mut()
.zip(val.iter())
.for_each(|(dst, src)| {
dst.assign(src);
});
}
}
result
}
}
#[cfg(not(feature = "rcl"))]
#[cfg(test)]
mod tests {
use oxidros_core::ServiceTypeDescription;
const EXPECTED_HASHES: &[(&str, &str)] = &[
(
"rcl_interfaces/srv/ListParameters",
"RIHS01_3e6062bfbb27bfb8730d4cef2558221f51a11646d78e7bb30a1e83afac3aad9d",
),
(
"rcl_interfaces/srv/GetParameters",
"RIHS01_bf9803d5c74cf989a5de3e0c2e99444599a627c7ff75f97b8c05b01003675cbc",
),
(
"rcl_interfaces/srv/SetParameters",
"RIHS01_56eed9a67e169f9cb6c1f987bc88f868c14a8fc9f743a263bc734c154015d7e0",
),
(
"rcl_interfaces/srv/SetParametersAtomically",
"RIHS01_0e192ef259c07fc3c07a13191d27002222e65e00ccec653ca05e856f79285fcd",
),
(
"rcl_interfaces/srv/DescribeParameters",
"RIHS01_845b484d71eb0673dae682f2e3ba3c4851a65a3dcfb97bddd82c5b57e91e4cff",
),
(
"rcl_interfaces/srv/GetParameterTypes",
"RIHS01_da199c878688b3e530bdfe3ca8f74cb9fa0c303101e980a9e8f260e25e1c80ca",
),
];
#[test]
fn test_list_parameters_type_hash() {
use super::interfaces::rcl_interfaces::srv::ListParameters;
let hash = ListParameters::compute_hash().expect("failed to compute hash");
assert_eq!(
hash, EXPECTED_HASHES[0].1,
"ListParameters type hash mismatch - interop with ros2 param will fail"
);
}
#[test]
fn test_get_parameters_type_hash() {
use super::interfaces::rcl_interfaces::srv::GetParameters;
let td = GetParameters::type_description();
println!("GetParameters type description: {:?}", td);
let hash = GetParameters::compute_hash().expect("failed to compute hash");
assert_eq!(
hash, EXPECTED_HASHES[1].1,
"GetParameters type hash mismatch - interop with ros2 param will fail"
);
}
#[test]
fn test_set_parameters_type_hash() {
use super::interfaces::rcl_interfaces::srv::SetParameters;
let hash = SetParameters::compute_hash().expect("failed to compute hash");
assert_eq!(
hash, EXPECTED_HASHES[2].1,
"SetParameters type hash mismatch - interop with ros2 param will fail"
);
}
#[test]
fn test_set_parameters_atomically_type_hash() {
use super::interfaces::rcl_interfaces::srv::SetParametersAtomically;
let hash = SetParametersAtomically::compute_hash().expect("failed to compute hash");
assert_eq!(
hash, EXPECTED_HASHES[3].1,
"SetParametersAtomically type hash mismatch - interop with ros2 param will fail"
);
}
#[test]
fn test_describe_parameters_type_hash() {
use super::interfaces::rcl_interfaces::srv::DescribeParameters;
let hash = DescribeParameters::compute_hash().expect("failed to compute hash");
assert_eq!(
hash, EXPECTED_HASHES[4].1,
"DescribeParameters type hash mismatch - interop with ros2 param will fail"
);
}
#[test]
fn test_get_parameter_types_type_hash() {
use super::interfaces::rcl_interfaces::srv::GetParameterTypes;
let hash = GetParameterTypes::compute_hash().expect("failed to compute hash");
assert_eq!(
hash, EXPECTED_HASHES[5].1,
"GetParameterTypes type hash mismatch - interop with ros2 param will fail"
);
}
#[test]
fn test_all_parameter_service_hashes() {
use super::interfaces::rcl_interfaces::srv::{
DescribeParameters, GetParameterTypes, GetParameters, ListParameters, SetParameters,
SetParametersAtomically,
};
let services: Vec<(&str, String)> = vec![
(
"ListParameters",
ListParameters::compute_hash().expect("hash"),
),
(
"GetParameters",
GetParameters::compute_hash().expect("hash"),
),
(
"SetParameters",
SetParameters::compute_hash().expect("hash"),
),
(
"SetParametersAtomically",
SetParametersAtomically::compute_hash().expect("hash"),
),
(
"DescribeParameters",
DescribeParameters::compute_hash().expect("hash"),
),
(
"GetParameterTypes",
GetParameterTypes::compute_hash().expect("hash"),
),
];
let mut all_match = true;
for (i, (name, hash)) in services.iter().enumerate() {
let expected = EXPECTED_HASHES[i].1;
if hash != expected {
eprintln!("MISMATCH: {} - got {} expected {}", name, hash, expected);
all_match = false;
}
}
assert!(
all_match,
"One or more parameter service type hashes do not match ROS2 expectations"
);
}
}