11use color_eyre:: Result ;
22use context_attribute:: context;
3- use framework:: MainOutput ;
3+ use framework:: { AdditionalOutput , MainOutput } ;
44use serde:: { Deserialize , Serialize } ;
55use types:: {
66 fall_state:: Kind ,
@@ -10,7 +10,8 @@ use types::{
1010
1111#[ derive( Deserialize , Serialize ) ]
1212pub struct MotionSelector {
13- current_motion : MotionType ,
13+ last_motion : MotionType ,
14+ stand_up_count : u32 ,
1415}
1516
1617#[ context]
@@ -22,6 +23,7 @@ pub struct CycleContext {
2223 has_ground_contact : Input < bool , "has_ground_contact" > ,
2324
2425 motion_safe_exits : CyclerState < MotionSafeExits , "motion_safe_exits" > ,
26+ stand_up_count : AdditionalOutput < u32 , "stand_up_count" > ,
2527}
2628
2729#[ context]
@@ -33,22 +35,30 @@ pub struct MainOutputs {
3335impl MotionSelector {
3436 pub fn new ( _context : CreationContext ) -> Result < Self > {
3537 Ok ( Self {
36- current_motion : MotionType :: Unstiff ,
38+ last_motion : MotionType :: Unstiff ,
39+ stand_up_count : 0 ,
3740 } )
3841 }
3942
40- pub fn cycle ( & mut self , context : CycleContext ) -> Result < MainOutputs > {
41- let motion_safe_to_exit = context. motion_safe_exits [ self . current_motion ] ;
43+ pub fn cycle ( & mut self , mut context : CycleContext ) -> Result < MainOutputs > {
44+ let motion_safe_to_exit = context. motion_safe_exits [ self . last_motion ] ;
4245 let requested_motion = motion_type_from_command ( context. motion_command ) ;
4346
44- self . current_motion = transition_motion (
45- self . current_motion ,
47+ let current_motion = transition_motion (
48+ self . last_motion ,
4649 requested_motion,
4750 motion_safe_to_exit,
4851 * context. has_ground_contact ,
4952 ) ;
5053
51- let dispatching_motion = if self . current_motion == MotionType :: Dispatching {
54+ self . stand_up_count =
55+ stand_up_counting ( self . last_motion , current_motion, self . stand_up_count ) ;
56+
57+ context
58+ . stand_up_count
59+ . fill_if_subscribed ( || self . stand_up_count ) ;
60+
61+ let dispatching_motion = if current_motion == MotionType :: Dispatching {
5262 if requested_motion == MotionType :: Unstiff {
5363 Some ( MotionType :: SitDown )
5464 } else {
@@ -58,9 +68,10 @@ impl MotionSelector {
5868 None
5969 } ;
6070
71+ self . last_motion = current_motion;
6172 Ok ( MainOutputs {
6273 motion_selection : MotionSelection {
63- current_motion : self . current_motion ,
74+ current_motion,
6475 dispatching_motion,
6576 }
6677 . into ( ) ,
@@ -156,3 +167,19 @@ fn transition_motion(
156167 _ => from,
157168 }
158169}
170+
171+ fn stand_up_counting (
172+ last_motion : MotionType ,
173+ current_motion : MotionType ,
174+ stand_up_count : u32 ,
175+ ) -> u32 {
176+ if !last_motion. is_standup_motion ( ) && current_motion. is_standup_motion ( ) {
177+ return stand_up_count + 1 ;
178+ }
179+
180+ if current_motion. is_stable ( ) {
181+ return 0 ;
182+ }
183+
184+ stand_up_count
185+ }
0 commit comments