From abda5935b24c9aa5f5c62a8454b93e20741b9399 Mon Sep 17 00:00:00 2001 From: sebastianHi Date: Wed, 8 Jan 2025 09:04:36 +0100 Subject: [PATCH] now also works with no service and with service --- .../build_src/fn_generator/generate_inputs.rs | 2 +- .../build_src/fn_generator/generate_main.rs | 9 ++-- .../fn_generator/generate_ros2_handler.rs | 44 +++++++++++++++++-- .../fn_generator/generate_rtloladata.rs | 19 ++++++-- monitor/build_src/templates/t_RTLolaData.rs | 4 +- monitor/build_src/templates/t_main.rs | 2 +- monitor/build_src/templates/t_ros2_handler.rs | 27 ++---------- specs/test_spec_no_srv.lola | 25 +++++++++++ 8 files changed, 95 insertions(+), 37 deletions(-) create mode 100644 specs/test_spec_no_srv.lola diff --git a/monitor/build_src/fn_generator/generate_inputs.rs b/monitor/build_src/fn_generator/generate_inputs.rs index 2862f19..1b9b11c 100644 --- a/monitor/build_src/fn_generator/generate_inputs.rs +++ b/monitor/build_src/fn_generator/generate_inputs.rs @@ -52,7 +52,7 @@ impl RustFileGenerator { if let Some((name, request, _response)) = rtlolaout_service { // Build path for each topic let new_file_location = Path::new(&format!("{}/input/", self.dest_path.clone())) - .join(format!("rtlola_request.rs")); // Creates file + .join("rtlola_request.rs".to_string()); // Creates file let file = File::create(new_file_location.clone()).unwrap(); // Create content of file self.create_input_ros2_srv(file, name.to_string(), request); diff --git a/monitor/build_src/fn_generator/generate_main.rs b/monitor/build_src/fn_generator/generate_main.rs index a1f7d6a..8ad324b 100644 --- a/monitor/build_src/fn_generator/generate_main.rs +++ b/monitor/build_src/fn_generator/generate_main.rs @@ -19,9 +19,6 @@ impl RustFileGenerator { let topic_name = parts.last().unwrap().to_lowercase(); pub_mods_content.push_str(&format!("\t\tpub mod {topic_name};\n")); } - if has_service { - pub_mods_content.push_str("\t\tpub mod rtlola_request;\n"); - } // Read the contents of the file into a String let mut file_content = String::new(); let crate_root = std::env::current_dir().expect("Failed to get current directory"); @@ -31,6 +28,12 @@ impl RustFileGenerator { .read_to_string(&mut file_content) .unwrap(); // Replace each template parameter by the actual values + if has_service { + pub_mods_content.push_str("\t\tpub mod rtlola_request;\n"); + file_content = file_content.replace("$SERVICEAVAILABLE$", "pub mod rtlolaout_service;"); + } else { + file_content = file_content.replace("$SERVICEAVAILABLE$", ""); + } file_content = file_content.replace("$INPUTMODS$", &pub_mods_content); // Write input source codeto file writeln!(&file, "{}", file_content).unwrap(); diff --git a/monitor/build_src/fn_generator/generate_ros2_handler.rs b/monitor/build_src/fn_generator/generate_ros2_handler.rs index d866915..7ac44a9 100644 --- a/monitor/build_src/fn_generator/generate_ros2_handler.rs +++ b/monitor/build_src/fn_generator/generate_ros2_handler.rs @@ -37,9 +37,6 @@ impl RustFileGenerator { )); select_statement.push_str(&format!("{}_subscriber,", topic_name.to_lowercase())); } - if has_service { - select_statement.push_str("service"); - } // Read the contents of the file into a String let mut file_content = String::new(); let crate_root = std::env::current_dir().expect("Failed to get current directory"); @@ -53,7 +50,46 @@ impl RustFileGenerator { file_content = file_content.replace("$RTLOLAENUM$", &rtlola_enum); file_content = file_content.replace("$ROS2MSGS$", &ros2_msgs); file_content = file_content.replace("$SUBSCRIBERS$", &subscribers); - file_content = file_content.replace("$SERVICE$", &service); + file_content = file_content.replace("$SERVICE$", service); + if has_service { + select_statement.push_str("service"); + file_content = file_content.replace( + "$SERVICEAVAILABLE$", + "rtlola_request::RTLolaServiceRequest,", + ); + file_content = file_content.replace( + "$SERVICEHANDLER$", + "let mut service_handler = Ros2ServiceHandler::new(monitor.ir())?;", + ); + file_content = file_content.replace( + "$SERVICEHANDLERUSE$", + "rtlolaout_service::Ros2ServiceHandler", + ); + file_content = file_content.replace( + "SERVICECASE", + "RTLolaType::Service(rtlola_data, service_request) => { + // Event received + let Verdicts { + timed, + event, + ts: _, + } = monitor + .accept_event(rtlola_data, ()) + .map_err(|_| println!(\"Message could not be parsed\")) + .unwrap(); + let timed_v: Vec)>> = + timed.into_iter().map(|(_, v)| v).collect(); + verdicts_vec.extend(timed_v); + verdicts_vec.push(event); + service_handler.handle(service_request, &verdicts_vec)?; + }", + ); + } else { + file_content = file_content.replace("$SERVICEAVAILABLE$", ""); + file_content = file_content.replace("$SERVICEHANDLER$", ""); + file_content = file_content.replace("$SERVICEHANDLERUSE$", ""); + file_content = file_content.replace("$SERVICECASE$", ""); + } file_content = file_content.replace("$SELECTSTATEMENT$", &select_statement); // Write input source codeto file writeln!(&file, "{}", file_content).unwrap(); diff --git a/monitor/build_src/fn_generator/generate_rtloladata.rs b/monitor/build_src/fn_generator/generate_rtloladata.rs index 73f8785..eb746fa 100644 --- a/monitor/build_src/fn_generator/generate_rtloladata.rs +++ b/monitor/build_src/fn_generator/generate_rtloladata.rs @@ -35,8 +35,8 @@ impl RustFileGenerator { )); } let package_name = if let Some(service) = rtlolaout_service { - members.push_str(&format!("RTLolaRequest (RTLolaServiceRequest),")); - includes.push_str(&format!("rtlola_request::RTLolaServiceRequest,")); + members.push_str(&"RTLolaRequest (RTLolaServiceRequest),".to_string()); + includes.push_str(&"rtlola_request::RTLolaServiceRequest,".to_string()); Some(service.0.clone()) } else { None @@ -53,7 +53,20 @@ impl RustFileGenerator { // Replace each template parameter by the actual values file_content = file_content.replace("$MEMBERS$", &members); if let Some(package_name) = package_name { - file_content = file_content.replace("$PACKAGENAME$", &package_name); + file_content = file_content.replace( + "$SERVICE$", + &format!( + "use r2r::{{{}::srv::RTLolaService, ServiceRequest}};", + package_name + ), + ); + file_content = file_content.replace( + "$SERVICETYPE$", + "Service(RTLolaData, ServiceRequest),", + ); + } else { + file_content = file_content.replace("$SERVICE$", ""); + file_content = file_content.replace("$SERVICETYPE$", ""); } file_content = file_content.replace("$INCLUDE$", &includes); // Write input source codeto file diff --git a/monitor/build_src/templates/t_RTLolaData.rs b/monitor/build_src/templates/t_RTLolaData.rs index ec04a66..8249fe4 100644 --- a/monitor/build_src/templates/t_RTLolaData.rs +++ b/monitor/build_src/templates/t_RTLolaData.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use super::{$INCLUDE$}; -use r2r::{$PACKAGENAME$::srv::RTLolaService, ServiceRequest}; +$SERVICE$ use rtlola_interpreter_macros::CompositFactory; #[derive(CompositFactory, Debug)] @@ -13,5 +13,5 @@ pub enum RTLolaData { pub enum RTLolaType { Subscription(RTLolaData), - Service(RTLolaData, ServiceRequest), + $SERVICETYPE$ } diff --git a/monitor/build_src/templates/t_main.rs b/monitor/build_src/templates/t_main.rs index 38309ee..c7884aa 100644 --- a/monitor/build_src/templates/t_main.rs +++ b/monitor/build_src/templates/t_main.rs @@ -8,7 +8,7 @@ pub mod input { } pub mod output { pub mod rtlolaout_publisher; - pub mod rtlolaout_service; + $SERVICEAVAILABLE$ pub mod sink_error; pub mod transformations; } diff --git a/monitor/build_src/templates/t_ros2_handler.rs b/monitor/build_src/templates/t_ros2_handler.rs index 483fb69..47d3a4b 100644 --- a/monitor/build_src/templates/t_ros2_handler.rs +++ b/monitor/build_src/templates/t_ros2_handler.rs @@ -5,9 +5,9 @@ use std::error::Error; use crate::{ input::{$RTLOLAENUM$ - rtlola_request::RTLolaServiceRequest, + $SERVICEAVAILABLE$ rtloladata::{RTLolaData, RTLolaDataFactory, RTLolaType}}, - output::{rtlolaout_publisher::Ros2Publisher, rtlolaout_service::Ros2ServiceHandler}, + output::{rtlolaout_publisher::Ros2Publisher, $SERVICEHANDLERUSE$}, }; use futures::{stream_select, StreamExt}; use r2r::{ @@ -39,7 +39,7 @@ impl Ros2Handler { // creates one ros2 publisher for RTLolaOutput let mut publisher = Ros2Publisher::new(monitor.ir(), &mut node)?; // create service handler - let mut service_handler = Ros2ServiceHandler::new(monitor.ir())?; + $SERVICEHANDLER$ // uses futures to handle asynchonous access let mut all = stream_select!($SELECTSTATEMENT$); // specifies frequency of monitor: 100ms = 10Hz @@ -56,7 +56,6 @@ impl Ros2Handler { Some(ty) => { match ty { RTLolaType::Subscription(rtlola_data) => { - println!("sub"); // Event received let Verdicts { timed, @@ -70,26 +69,8 @@ impl Ros2Handler { timed.into_iter().map(|(_, v)| v).collect(); verdicts_vec.extend(timed_v); verdicts_vec.push(event); - println!("esub"); - } - RTLolaType::Service(rtlola_data, service_request) => { - println!("ser"); - // Event received - let Verdicts { - timed, - event, - ts: _, - } = monitor - .accept_event(rtlola_data, ()) - .map_err(|_| println!("Message could not be parsed")) - .unwrap(); - let timed_v: Vec)>> = - timed.into_iter().map(|(_, v)| v).collect(); - verdicts_vec.extend(timed_v); - verdicts_vec.push(event); - service_handler.handle(service_request, &verdicts_vec)?; - println!("eser"); } + $SERVICECASE$ } } None => { diff --git a/specs/test_spec_no_srv.lola b/specs/test_spec_no_srv.lola new file mode 100644 index 0000000..2746a8e --- /dev/null +++ b/specs/test_spec_no_srv.lola @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2023 German Aerospace Center (DLR) +// SPDX-License-Identifier: Apache-2.0 + +input adc__a0: Float32 +input gpspos__lon: Float32 +output f_64 : Float32 @ 1Hz := + adc__a0.hold().defaults(to:0.0) + + f_64.offset(by: -1).defaults(to: 0.0) + + +output b : Bool @adc__a0 := true + +output f_32 : Float32 @ adc__a0 := 0.0 + +output i_8 : Int8 @adc__a0 := 0 +output u_8 : UInt8 @adc__a0 := 0 + +output i_16 : Int16 @ adc__a0 := i_16.offset(by: -1).defaults(to: 0) + 1 +output u_16 : UInt16 @ adc__a0 := u_16.offset(by: -1).defaults(to: 0) + 1 + +output i_32 : Int32 @ 1Hz := i_32.offset(by: -1).defaults(to: 0) + 1 +output u_32 : UInt32 @ 1Hz := u_32.offset(by: -1).defaults(to: 0) + 1 + +output i_64 : Int64 @ 1Hz := i_64.offset(by: -1).defaults(to: 0) + 1 +output u_64 : UInt64 @ 1Hz := u_64.offset(by: -1).defaults(to: 0) + 1 \ No newline at end of file