Skip to content

Commit

Permalink
Removes the lifecycle trait (#115)
Browse files Browse the repository at this point in the history
* Removes the lifecycle trait

It split artificially the implementation of tasks and couples the passed
types.

* Fixedd comments + template

* Another pass on removing the lifecycle trait.
  • Loading branch information
gbin authored Dec 1, 2024
1 parent 13c79fe commit 178174a
Show file tree
Hide file tree
Showing 26 changed files with 354 additions and 386 deletions.
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,33 +173,33 @@ pub struct FlippingSource {
state: bool,
}
// You need to provide at least "new". But you have other hooks in to the Lifecycle you can leverage
// to maximize your opportunity to not use resources outside of the critical execution path: for example start, stop,
// pre_process, post_process etc...
impl CuTaskLifecycle for FlippingSource {
fn new(_config: Option<&copper::config::ComponentConfig>) -> CuResult<Self>
// We implement the CuSrcTask trait for our task as it is a source / driver (with no internal input from Copper itself).
impl<'cl> CuSrcTask<'cl> for FlippingSource {
type Output = output_msg!('cl, RPGpioPayload);
// You need to provide at least "new" out of the lifecycle methods.
// But you have other hooks in to the Lifecycle you can leverage to maximize your opportunity
// to not use resources outside of the critical execution path: for example start, stop,
// pre_process, post_process etc...
fn new(config: Option<&copper::config::ComponentConfig>) -> CuResult<Self>
where
Self: Sized,
{
// the config is passed from the RON config file as a Map.
Ok(Self { state: true })
}
}
// We implement the CuSrcTask trait for our task as it is a source / driver (with no internal input from Copper itself).
impl<'cl> CuSrcTask<'cl> for FlippingSource {
type Output = output_msg!('cl, RPGpioPayload);
// Process is called by the runtime at each cycle. It will give:
// 1. the reference to a monotonic clock
// 2. a mutable reference to the output message (so no need to allocate of copy anything)
// 3. a CuResult to handle errors
fn process(&mut self, clock: &RobotClock, output: Self::Output) -> CuResult<()> {
self.state = !self.state; // Flip our internal state and send the message in our output.
output.payload = RPGpioPayload {
output.set_payload(RPGpioPayload {
on: self.state,
creation: Some(clock.now()).into(),
actuation: Some(clock.now()).into(),
};
});
Ok(())
}
}
Expand Down
25 changes: 10 additions & 15 deletions components/sinks/cu_iceoryx2_sink/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use cu29::clock::RobotClock;
use cu29::config::ComponentConfig;
use cu29::cutask::{CuMsg, CuMsgPayload};
use cu29::cutask::{CuSinkTask, CuTaskLifecycle, Freezable};
use cu29::cutask::{CuSinkTask, Freezable};
use cu29::input_msg;
use cu29_log_derive::debug;
use cu29_traits::{CuError, CuResult};
Expand All @@ -25,10 +25,12 @@ where

impl<P> Freezable for IceoryxSink<P> where P: CuMsgPayload {}

impl<P> CuTaskLifecycle for IceoryxSink<P>
impl<'cl, P> CuSinkTask<'cl> for IceoryxSink<P>
where
P: CuMsgPayload,
P: CuMsgPayload + 'cl,
{
type Input = input_msg!('cl, P);

fn new(config: Option<&ComponentConfig>) -> CuResult<Self>
where
Self: Sized,
Expand Down Expand Up @@ -72,18 +74,6 @@ where
Ok(())
}

fn stop(&mut self, _clock: &RobotClock) -> CuResult<()> {
self.publisher = None;
Ok(())
}
}

impl<'cl, P> CuSinkTask<'cl> for IceoryxSink<P>
where
P: CuMsgPayload + 'cl,
{
type Input = input_msg!('cl, P);

fn process(&mut self, _clock: &RobotClock, input: Self::Input) -> CuResult<()> {
let publisher = self
.publisher
Expand All @@ -101,4 +91,9 @@ where

Ok(())
}

fn stop(&mut self, _clock: &RobotClock) -> CuResult<()> {
self.publisher = None;
Ok(())
}
}
50 changes: 24 additions & 26 deletions components/sinks/cu_lewansoul/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bincode::error::{DecodeError, EncodeError};
use bincode::{Decode, Encode};
use cu29::clock::RobotClock;
use cu29::config::ComponentConfig;
use cu29::cutask::{CuMsg, CuSinkTask, CuTaskLifecycle, Freezable};
use cu29::cutask::{CuMsg, CuSinkTask, Freezable};
use cu29::{input_msg, CuError, CuResult};
use serialport::{DataBits, FlowControl, Parity, SerialPort, StopBits};
use std::io::{self, Read, Write};
Expand Down Expand Up @@ -178,7 +178,29 @@ impl Freezable for Lewansoul {
// This driver is stateless as the IDs are recreate at new time, we keep the default implementation.
}

impl CuTaskLifecycle for Lewansoul {
#[derive(Debug, Clone, Default)]
pub struct ServoPositionsPayload {
pub positions: [Angle; MAX_SERVOS],
}

impl Encode for ServoPositionsPayload {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
let angles: [f32; MAX_SERVOS] = self.positions.map(|a| a.value);
angles.encode(encoder)
}
}

impl Decode for ServoPositionsPayload {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
let angles: [f32; 8] = Decode::decode(decoder)?;
let positions: [Angle; 8] = angles.map(Angle::new::<radian>);
Ok(ServoPositionsPayload { positions })
}
}

impl<'cl> CuSinkTask<'cl> for Lewansoul {
type Input = input_msg!('cl, ServoPositionsPayload);

fn new(config: Option<&ComponentConfig>) -> CuResult<Self>
where
Self: Sized,
Expand Down Expand Up @@ -220,30 +242,6 @@ impl CuTaskLifecycle for Lewansoul {

Ok(Lewansoul { port, ids })
}
}

#[derive(Debug, Clone, Default)]
pub struct ServoPositionsPayload {
pub positions: [Angle; MAX_SERVOS],
}

impl Encode for ServoPositionsPayload {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
let angles: [f32; MAX_SERVOS] = self.positions.map(|a| a.value);
angles.encode(encoder)
}
}

impl Decode for ServoPositionsPayload {
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
let angles: [f32; 8] = Decode::decode(decoder)?;
let positions: [Angle; 8] = angles.map(Angle::new::<radian>);
Ok(ServoPositionsPayload { positions })
}
}

impl<'cl> CuSinkTask<'cl> for Lewansoul {
type Input = input_msg!('cl, ServoPositionsPayload);

fn process(&mut self, _clock: &RobotClock, _input: Self::Input) -> CuResult<()> {
todo!()
Expand Down
15 changes: 7 additions & 8 deletions components/sinks/cu_rp_gpio/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use bincode::{Decode, Encode};
use cu29::config::ComponentConfig;
use cu29::cutask::{CuMsg, CuSinkTask, CuTaskLifecycle, Freezable};
use cu29::cutask::{CuMsg, CuSinkTask, Freezable};
use cu29::input_msg;
use cu29::CuResult;
use cu29::{clock, input_msg};
use serde::{Deserialize, Serialize};

#[cfg(mock)]
use cu29_log_derive::debug;

use cu29::clock::RobotClock;
#[cfg(hardware)]
use {
cu29::CuError,
Expand Down Expand Up @@ -64,7 +65,9 @@ impl From<RPGpioPayload> for Level {

impl Freezable for RPGpio {}

impl CuTaskLifecycle for RPGpio {
impl<'cl> CuSinkTask<'cl> for RPGpio {
type Input = input_msg!('cl, RPGpioPayload);

fn new(config: Option<&ComponentConfig>) -> CuResult<Self>
where
Self: Sized,
Expand All @@ -86,12 +89,8 @@ impl CuTaskLifecycle for RPGpio {
let pin = pin_nb;
Ok(Self { pin })
}
}

impl<'cl> CuSinkTask<'cl> for RPGpio {
type Input = input_msg!('cl, RPGpioPayload);

fn process(&mut self, _clock: &clock::RobotClock, msg: Self::Input) -> CuResult<()> {
fn process(&mut self, _clock: &RobotClock, msg: Self::Input) -> CuResult<()> {
#[cfg(hardware)]
self.pin.write((*msg.payload().unwrap()).into());

Expand Down
51 changes: 23 additions & 28 deletions components/sinks/cu_rp_sn754410/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bincode::error::{DecodeError, EncodeError};
use bincode::{Decode, Encode};
use cu29::clock::{CuTime, RobotClock};
use cu29::config::ComponentConfig;
use cu29::cutask::{CuMsg, CuSinkTask, CuTaskLifecycle, Freezable};
use cu29::cutask::{CuMsg, CuSinkTask, Freezable};
use cu29::{input_msg, CuResult};
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -126,7 +126,19 @@ impl SN754410 {
}
}

impl CuTaskLifecycle for SN754410 {
impl Freezable for SN754410 {
fn freeze<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
Encode::encode(&self.current_power, encoder)
}

fn thaw<D: Decoder>(&mut self, decoder: &mut D) -> Result<(), DecodeError> {
self.current_power = Decode::decode(decoder)?;
Ok(())
}
}

impl<'cl> CuSinkTask<'cl> for SN754410 {
type Input = input_msg!('cl, MotorPayload);
fn new(config: Option<&ComponentConfig>) -> CuResult<Self>
where
Self: Sized,
Expand Down Expand Up @@ -162,26 +174,6 @@ impl CuTaskLifecycle for SN754410 {
debug!("Enabling SN754410.");
self.enable_pwms()
}
fn stop(&mut self, _clock: &RobotClock) -> CuResult<()> {
debug!("Disabling SN754410.");
self.disable_pwms()
}
}

impl Freezable for SN754410 {
fn freeze<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
Encode::encode(&self.current_power, encoder)
}

fn thaw<D: Decoder>(&mut self, decoder: &mut D) -> Result<(), DecodeError> {
self.current_power = Decode::decode(decoder)?;
Ok(())
}
}

impl<'cl> CuSinkTask<'cl> for SN754410 {
type Input = input_msg!('cl, MotorPayload);

fn process(&mut self, clock: &RobotClock, input: Self::Input) -> CuResult<()> {
if let Some(power) = input.payload() {
if self.dryrun {
Expand Down Expand Up @@ -224,27 +216,30 @@ impl<'cl> CuSinkTask<'cl> for SN754410 {
}
Ok(())
}

fn stop(&mut self, _clock: &RobotClock) -> CuResult<()> {
debug!("Disabling SN754410.");
self.disable_pwms()
}
}

pub mod test_support {
use crate::MotorPayload;
use cu29::clock::RobotClock;
use cu29::config::ComponentConfig;
use cu29::cutask::{CuMsg, CuSrcTask, CuTaskLifecycle, Freezable};
use cu29::cutask::{CuMsg, CuSrcTask, Freezable};
use cu29::{output_msg, CuResult};

pub struct SN754410TestSrc;

impl Freezable for SN754410TestSrc {}

impl CuTaskLifecycle for SN754410TestSrc {
impl<'cl> CuSrcTask<'cl> for SN754410TestSrc {
type Output = output_msg!('cl, MotorPayload);

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

impl<'cl> CuSrcTask<'cl> for SN754410TestSrc {
type Output = output_msg!('cl, MotorPayload);

fn process(&mut self, _clock: &RobotClock, _new_msg: Self::Output) -> CuResult<()> {
todo!()
Expand Down
2 changes: 1 addition & 1 deletion components/sinks/cu_rp_sn754410/tests/sn754410_tester.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cu29::cutask::{CuSinkTask, CuTaskLifecycle};
use cu29::cutask::CuSinkTask;
use cu29_derive::copper_runtime;
use cu29_helpers::basic_copper_setup;
use cu29_log_derive::debug;
Expand Down
Loading

0 comments on commit 178174a

Please sign in to comment.