Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ members = [
"examples/cu_monitoring",
"examples/cu_missions",
"examples/cu_multisources",
"examples/cu_multisources_structs",
"examples/cu_nologging_tasks",
"examples/cu_rate_target",
"examples/cu_pointclouds",
Expand Down
1 change: 1 addition & 0 deletions examples/cu_multisources_structs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/
26 changes: 26 additions & 0 deletions examples/cu_multisources_structs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "cu-multisources-structs"
version = "0.1.0"
edition = "2021"
default-run = "sim-test"

[[bin]]
name = "sim-test"
path = "src/main.rs"

[[bin]]
name = "sim-test-logreader"
path = "src/logreader.rs"
required-features = ["logreader"]

[features]
default = []
logreader = ["dep:cu29-export"]

[dependencies]
cu29 = { workspace=true, features = ["macro_debug"] }
bincode = { workspace=true, features = ["derive"] }
serde = { workspace=true, features = ["derive"] }
cu29-helpers = { workspace=true }
cu29-export = { workspace=true, optional = true }

6 changes: 6 additions & 0 deletions examples/cu_multisources_structs/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
println!(
"cargo:rustc-env=LOG_INDEX_DIR={}",
std::env::var("OUT_DIR").unwrap()
);
}
32 changes: 32 additions & 0 deletions examples/cu_multisources_structs/copperconfig.ron
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// A sample configuration to get you started.
(
tasks: [
(
id: "src",
type: "tasks::MySource",
),
(
id: "t-0",
type: "tasks::MyTask",
),
(
id: "sink",
type: "tasks::MySink",
),
(
id: "src1",
type: "tasks::MySource",
),
(
id: "t-1",
type: "tasks::MyTask",
),
],
// Makes a connection from the source to the task and from the task to the sink.
cnx: [
(src: "src", dst: "t-0", msg: "crate::tasks::MyPayload"),
(src: "t-0", dst: "sink", msg: "crate::tasks::MyPayload"),
(src: "src1", dst: "t-1", msg: "crate::tasks::MyPayload"),
(src: "t-1", dst: "sink", msg: "crate::tasks::MyPayload"),
],
)
13 changes: 13 additions & 0 deletions examples/cu_multisources_structs/src/logreader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
pub mod tasks;

use cu29::prelude::*;
use cu29_export::run_cli;

// This will create the CuStampedDataSet that is specific to your copper project.
// It is used to instruct the log reader how to decode the logs.
gen_cumsgs!("copperconfig.ron");

#[cfg(feature = "logreader")]
fn main() {
run_cli::<CuStampedDataSet>().expect("Failed to run the export CLI");
}
49 changes: 49 additions & 0 deletions examples/cu_multisources_structs/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
pub mod tasks;

use cu29::prelude::*;
use cu29_helpers::basic_copper_setup;
use std::path::{Path, PathBuf};
use std::thread::sleep;
use std::time::Duration;

use crate::default::SimStep;

const PREALLOCATED_STORAGE_SIZE: Option<usize> = Some(1024 * 1024 * 100);

#[copper_runtime(config = "copperconfig.ron", sim_mode = true)]
struct SimTestApplication {}

fn main() {
let logger_path = "logs/sim-test.copper";
if let Some(parent) = Path::new(logger_path).parent() {
if !parent.exists() {
std::fs::create_dir_all(parent).expect("Failed to create logs directory");
}
}
let copper_ctx = basic_copper_setup(
&PathBuf::from(&logger_path),
PREALLOCATED_STORAGE_SIZE,
true,
None,
)
.expect("Failed to setup logger.");
debug!("Logger created at {}.", logger_path);
debug!("Creating application... ");
let mut application = SimTestApplicationBuilder::new()
.with_sim_callback(&mut default_callback)
.with_context(&copper_ctx)
.build()
.expect("Failed to create application.");
let clock = copper_ctx.clock.clone();
debug!("Running... starting clock: {}.", clock.now());

application
.run(&mut default_callback)
.expect("Failed to run application.");
debug!("End of program: {}.", clock.now());
sleep(Duration::from_secs(1));
}

fn default_callback(sim_step: SimStep) -> SimOverride {
SimOverride::ExecutedBySim
}
94 changes: 94 additions & 0 deletions examples/cu_multisources_structs/src/tasks.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use bincode::{Decode, Encode};
use cu29::prelude::*;

// Define a message type
#[derive(Default, Debug, Clone, Encode, Decode, Serialize)]
pub struct MyPayload {
value: i32,
}

// Defines a source (ie. driver)
#[derive(Default)]
pub struct MySource {}

// Needs to be fully implemented if you want to have a stateful task.
impl Freezable for MySource {}

impl CuSrcTask for MySource {
type Output<'m> = output_msg!(MyPayload);

fn new(_config: Option<&ComponentConfig>) -> CuResult<Self>
where
Self: Sized,
{
Ok(Self {})
}

// don't forget the other lifecycle methods if you need them: start, stop, preprocess, postprocess

fn process(&mut self, _clock: &RobotClock, output: &mut Self::Output<'_>) -> CuResult<()> {
// Generated a 42 message.
output.set_payload(MyPayload { value: 42 });
Ok(())
}
}

// Defines a processing task
pub struct MyTask {
// if you add some task state here, you need to implement the Freezable trait
}

// Needs to be fully implemented if you want to have a stateful task.
impl Freezable for MyTask {}

impl CuTask for MyTask {
type Input<'m> = input_msg!(MyPayload);
type Output<'m> = output_msg!(MyPayload);

fn new(_config: Option<&ComponentConfig>) -> CuResult<Self>
where
Self: Sized,
{
// add the task state initialization here
Ok(Self {})
}

// don't forget the other lifecycle methods if you need them: start, stop, preprocess, postprocess

fn process(
&mut self,
_clock: &RobotClock,
input: &Self::Input<'_>,
output: &mut Self::Output<'_>,
) -> CuResult<()> {
debug!("Received message: {}", input.payload().unwrap().value);
output.set_payload(MyPayload { value: 43 });
Ok(()) // outputs another message for downstream
}
}

// Defines a sink (ie. actualtion)
#[derive(Default)]
pub struct MySink {}

// Needs to be fully implemented if you want to have a stateful task.
impl Freezable for MySink {}

impl CuSinkTask for MySink {
type Input<'m> = input_msg!('m, MyPayload, MyPayload);

fn new(_config: Option<&ComponentConfig>) -> CuResult<Self>
where
Self: Sized,
{
Ok(Self {})
}
// don't forget the other lifecycle methods if you need them: start, stop, preprocess, postprocess

fn process(&mut self, _clock: &RobotClock, input: &Self::Input<'_>) -> CuResult<()> {
// debug!("Sink Received message: {}", input.payload().unwrap().value);
// debug!("Sink Received message: {}", input.payload().unwrap().value);

Ok(())
}
}
Loading