1- import math
2-
3- import tf2_ros as tf2
41from bitbots_localization .srv import ResetFilter
5- from rclpy .duration import Duration
6- from rclpy .time import Time
72
83from bitbots_localization_handler .localization_dsd .actions import AbstractLocalizationActionElement
94
105
11- class AbstractInitialize (AbstractLocalizationActionElement ):
12- def __init__ (self , blackboard , dsd , parameters ):
13- super ().__init__ (blackboard , dsd , parameters )
14-
15- # Save the type the instance that called super, so we know what was the last init mode
16- if not isinstance (self , RedoLastInit ):
17- self .blackboard .last_init_action_type = self .__class__
18- try :
19- # only need this in simulation
20- if self .blackboard .use_sim_time :
21- self .blackboard .last_init_odom_transform = self .blackboard .tf_buffer .lookup_transform (
22- self .blackboard .odom_frame ,
23- self .blackboard .base_footprint_frame ,
24- Time (),
25- Duration (seconds = 1.0 ),
26- ) # wait up to 1 second for odom data
27- except (tf2 .LookupException , tf2 .ConnectivityException , tf2 .ExtrapolationException ) as e :
28- self .blackboard .node .get_logger ().warn (f"Not able to save the odom position due to a tf error: { e } " )
29- self .blackboard .node .get_logger ().debug (
30- f"Set last init action type to { self .blackboard .last_init_action_type } "
31- )
32-
33- def perform (self , reevaluate = False ):
34- raise NotImplementedError
35-
36-
37- class InitOpponentHalf (AbstractInitialize ):
6+ class InitOpponentHalf (AbstractLocalizationActionElement ):
387 def perform (self , reevaluate = False ):
398 self .do_not_reevaluate ()
409 self .blackboard .node .get_logger ().debug ("Initializing on the opponent half" )
@@ -44,7 +13,7 @@ def perform(self, reevaluate=False):
4413 return self .pop ()
4514
4615
47- class InitOwnHalf (AbstractInitialize ):
16+ class InitOwnHalf (AbstractLocalizationActionElement ):
4817 def perform (self , reevaluate = False ):
4918 self .do_not_reevaluate ()
5019 self .blackboard .node .get_logger ().debug ("Initializing on our half" )
@@ -54,7 +23,7 @@ def perform(self, reevaluate=False):
5423 return self .pop ()
5524
5625
57- class InitPosition (AbstractInitialize ):
26+ class InitPosition (AbstractLocalizationActionElement ):
5827 def perform (self , reevaluate = False ):
5928 self .do_not_reevaluate ()
6029 self .blackboard .node .get_logger ().debug ("Initializing position" )
@@ -79,42 +48,7 @@ def perform(self, reevaluate=False):
7948 return self .pop ()
8049
8150
82- class InitPoseAfterFall (AbstractInitialize ):
83- def perform (self , reevaluate = False ):
84- self .do_not_reevaluate ()
85- self .blackboard .node .get_logger ().debug ("Initializing at pose after fall" )
86- while not self .blackboard .reset_filter_proxy .wait_for_service (timeout_sec = 3.0 ):
87- self .blackboard .node .get_logger ().info ("Localization reset service not available, waiting again..." )
88-
89- # Abort if we don't know the current pose
90- if self .blackboard .robot_pose is None :
91- self .blackboard .node .get_logger ().warn (
92- "Can't initialize position, because we don't know the current position"
93- )
94- return self .pop ()
95-
96- # Calculate the angle of the robot after the fall by adding the yaw difference during the fall
97- # (estimated by the IMU) to the last known localization yaw
98- esimated_angle = (
99- self .blackboard .get_imu_yaw ()
100- - self .blackboard .imu_yaw_before_fall
101- + self .blackboard .get_localization_yaw ()
102- + math .tau
103- ) % math .tau
104-
105- # Tell the localization to reset to the last position and the estimated angle
106- self .blackboard .reset_filter_proxy .call_async (
107- ResetFilter .Request (
108- init_mode = ResetFilter .Request .POSE ,
109- x = self .blackboard .robot_pose .pose .pose .position .x ,
110- y = self .blackboard .robot_pose .pose .pose .position .y ,
111- angle = esimated_angle ,
112- )
113- )
114- return self .pop ()
115-
116-
117- class InitSide (AbstractInitialize ):
51+ class InitSide (AbstractLocalizationActionElement ):
11852 def perform (self , reevaluate = False ):
11953 self .do_not_reevaluate ()
12054 self .blackboard .node .get_logger ().debug ("Initializing on the side lines of our side" )
@@ -124,7 +58,7 @@ def perform(self, reevaluate=False):
12458 return self .pop ()
12559
12660
127- class InitGoal (AbstractInitialize ):
61+ class InitGoal (AbstractLocalizationActionElement ):
12862 def perform (self , reevaluate = False ):
12963 self .do_not_reevaluate ()
13064 self .blackboard .node .get_logger ().debug ("Initializing on the side lines of our side" )
@@ -136,7 +70,7 @@ def perform(self, reevaluate=False):
13670 return self .pop ()
13771
13872
139- class InitPenaltyKick (AbstractInitialize ):
73+ class InitPenaltyKick (AbstractLocalizationActionElement ):
14074 def perform (self , reevaluate = False ):
14175 self .do_not_reevaluate ()
14276 self .blackboard .node .get_logger ().debug ("Initializing behind penalty mark" )
@@ -148,32 +82,3 @@ def perform(self, reevaluate=False):
14882 )
14983 )
15084 return self .pop ()
151-
152-
153- class RedoLastInit (AbstractInitialize ):
154- """
155- Executes an action with the type of the last action
156- """
157-
158- def __init__ (self , blackboard , dsd , parameters ):
159- super ().__init__ (blackboard , dsd , parameters )
160- if self .blackboard .last_init_action_type is None :
161- raise ValueError ("There is no last init action to redo" )
162-
163- # Creates an instance of the last init action
164- self .sub_action : AbstractInitialize = self .blackboard .last_init_action_type (blackboard , dsd , parameters )
165-
166- def perform (self , reevaluate = False ):
167- self .blackboard .node .get_logger ().debug ("Redoing the last init" )
168- return self .sub_action .perform (reevaluate )
169-
170-
171- class StoreCurrentIMUYaw (AbstractLocalizationActionElement ):
172- def perform (self , reevaluate = False ):
173- self .do_not_reevaluate ()
174- self .blackboard .node .get_logger ().debug ("Storing current IMU yaw" )
175- # Get yaw component of the current orientation before the fall
176- # It drifts over time, so this is not an absolute measurement, but it will help to overcome
177- # The short time during the fall at which we have no odometry
178- self .blackboard .imu_yaw_before_fall = self .blackboard .get_imu_yaw ()
179- return self .pop ()
0 commit comments