@@ -35,7 +35,7 @@ type Input<'m> = input_msg!(SensorA, SensorB);
3535In ` process() ` , the ` input ` parameter becomes a tuple that you can destructure:
3636
3737``` rust
38- fn process (& mut self , _clock : & RobotClock , input : & Self :: Input <'_ >, ... ) -> CuResult <()> {
38+ fn process (& mut self , _ctx : & CuContext , input : & Self :: Input <'_ >, ... ) -> CuResult <()> {
3939 let (sensor_a_msg , sensor_b_msg ) = * input ;
4040 // Use sensor_a_msg.payload() and sensor_b_msg.payload()
4141 Ok (())
@@ -86,8 +86,12 @@ You can read the values in `new()`:
8686``` rust
8787fn new (config : Option <& ComponentConfig >, _resources : Self :: Resources <'_ >) -> CuResult <Self > {
8888 let cfg = config . ok_or (" MotorDriver requires a config block" )? ;
89- let pin : u8 = cfg . get (" pin" ). unwrap (). clone (). into ();
90- let max_speed : f64 = cfg . get (" max_speed" ). unwrap (). clone (). into ();
89+ let pin : u8 = cfg
90+ . get :: <u8 >(" pin" )?
91+ . ok_or_else (|| CuError :: from (" MotorDriver missing `pin`" ))? ;
92+ let max_speed : f64 = cfg
93+ . get :: <f64 >(" max_speed" )?
94+ . ok_or_else (|| CuError :: from (" MotorDriver missing `max_speed`" ))? ;
9195 Ok (Self { pin , max_speed })
9296}
9397```
@@ -101,14 +105,14 @@ depends on the trait:
101105
102106| Trait | Signature |
103107| ---| ---|
104- | ` CuSrcTask ` | ` process(&mut self, clock , output) ` |
105- | ` CuTask ` | ` process(&mut self, clock , input, output) ` |
106- | ` CuSinkTask ` | ` process(&mut self, clock , input) ` |
108+ | ` CuSrcTask ` | ` process(&mut self, ctx , output) ` |
109+ | ` CuTask ` | ` process(&mut self, ctx , input, output) ` |
110+ | ` CuSinkTask ` | ` process(&mut self, ctx , input) ` |
107111
108112In our simple example, the source ignores most parameters and just writes a value:
109113
110114``` rust
111- fn process (& mut self , _clock : & RobotClock , output : & mut Self :: Output <'_ >) -> CuResult <()> {
115+ fn process (& mut self , _ctx : & CuContext , output : & mut Self :: Output <'_ >) -> CuResult <()> {
112116 output . set_payload (MyPayload { value : 42 });
113117 Ok (())
114118}
@@ -143,32 +147,35 @@ arrive. This is a good fit for calibration bundles, static transforms, lookup ta
143147other low-rate metadata that should not be rebuilt every cycle. The full producer and
144148consumer pattern is covered in [ Defining Messages] ( ./ch06-messages.md#latched-state-updates ) .
145149
146- #### The clock : ` &RobotClock `
150+ #### The context : ` &CuContext `
147151
148- Every ` process() ` receives a ` clock ` parameter. This is Copper's ** only clock ** -- a
149- monotonic clock that starts at zero when your program launches and ticks forward in
150- nanoseconds. There is no UTC or wall-clock in Copper; tasks should never call
151- ` std::time::SystemTime::now() ` or ` std::time::Instant::now() ` .
152+ Every lifecycle callback receives a ` ctx ` parameter of type ` &CuContext ` . It dereferences
153+ to Copper's monotonic ` RobotClock ` , so ` ctx.now() ` gives you the current Copper time, and
154+ it also carries runtime metadata such as ` ctx.cl_id() ` , ` ctx.instance_id() ` , and the
155+ currently executing task ID .
152156
153- ` clock.now() ` returns a ` CuTime ` (a ` u64 ` of nanoseconds since startup). In our simple
154- project we prefix the parameter with ` _ ` because we don't use it. But on a real robot
155- you'd use it like this:
157+ ` ctx.now() ` returns a ` CuTime ` (a ` u64 ` of nanoseconds since startup). There is no UTC or
158+ wall-clock in Copper; tasks should never call ` std::time::SystemTime::now() ` or
159+ ` std::time::Instant::now() ` .
160+
161+ In our simple project we prefix the parameter with ` _ ` because we don't use it. But on a
162+ real robot you'd use it like this:
156163
157164** Timestamp your output** (typical for source tasks):
158165
159166``` rust
160- fn process (& mut self , clock : & RobotClock , output : & mut Self :: Output <'_ >) -> CuResult <()> {
167+ fn process (& mut self , ctx : & CuContext , output : & mut Self :: Output <'_ >) -> CuResult <()> {
161168 output . set_payload (MyPayload { value : read_sensor () });
162- output . tov = Tov :: Time (clock . now ());
169+ output . tov = Tov :: Time (ctx . now ());
163170 Ok (())
164171}
165172```
166173
167174** Compute a time delta** (e.g., for a PID controller):
168175
169176``` rust
170- fn process (& mut self , clock : & RobotClock , input : & Self :: Input <'_ >, output : & mut Self :: Output <'_ >) -> CuResult <()> {
171- let now = clock . now ();
177+ fn process (& mut self , ctx : & CuContext , input : & Self :: Input <'_ >, output : & mut Self :: Output <'_ >) -> CuResult <()> {
178+ let now = ctx . now ();
172179 let dt = now - self . last_time; // CuDuration in nanoseconds
173180 self . last_time = now ;
174181
@@ -182,9 +189,9 @@ fn process(&mut self, clock: &RobotClock, input: &Self::Input<'_>, output: &mut
182189** Detect a timeout** :
183190
184191``` rust
185- fn process (& mut self , clock : & RobotClock , input : & Self :: Input <'_ >) -> CuResult <()> {
192+ fn process (& mut self , ctx : & CuContext , input : & Self :: Input <'_ >) -> CuResult <()> {
186193 if input . payload (). is_none () {
187- let elapsed = clock . now () - self . last_seen;
194+ let elapsed = ctx . now () - self . last_seen;
188195 if elapsed > CuDuration :: from_millis (100 ) {
189196 debug! (" Sensor timeout! No data for {}ms" , elapsed . as_millis ());
190197 }
@@ -196,8 +203,8 @@ fn process(&mut self, clock: &RobotClock, input: &Self::Input<'_>) -> CuResult<(
196203** Why not use the system clock?** Because Copper supports ** deterministic replay** . When
197204you replay a recorded run, the runtime feeds your tasks the exact same clock values from
198205the original recording. If you used ` std::time ` , the replay would have different
199- timestamps and your tasks would behave differently. With ` RobotClock ` , same clock + same
200- inputs = same outputs, every time.
206+ timestamps and your tasks would behave differently. With ` CuContext ` (and its underlying
207+ ` RobotClock ` ), same clock + same inputs = same outputs, every time.
201208
202209### The golden rule of ` process() `
203210
0 commit comments