10 from actionlib_msgs.msg
import GoalStatus
11 from geometry_msgs.msg
import Twist, Transform, TransformStamped, PoseStamped
12 from geometry_msgs.msg
import Pose, PoseWithCovarianceStamped, Quaternion
13 from move_base_msgs.msg
import MoveBaseAction, MoveBaseGoal, MoveBaseResult
14 from nav_msgs.msg
import Odometry
15 from std_srvs.srv
import Trigger, TriggerRequest, TriggerResponse
37 rospy.Subscriber(
"/base/twist_controller/command", Twist, self.
twist_callback, queue_size=1)
38 rospy.Subscriber(
"/initialpose", PoseWithCovarianceStamped, self.
initalpose_callback, queue_size=1)
39 self.
pub_odom = rospy.Publisher(
"/base/odometry_controller/odometry", Odometry, queue_size=1)
40 rospy.Service(
"/base/odometry_controller/reset_odometry", Trigger, self.
reset_odometry)
51 self.odom.header.frame_id =
"odom_combined" 52 self.odom.child_frame_id =
"base_footprint" 53 self.odom.pose.pose.orientation.w = 1
57 initialpose = rospy.get_param(
"~initialpose",
None)
58 if type(initialpose) == list:
59 rospy.loginfo(
"using initialpose from parameter server: %s", str(initialpose))
60 elif type(initialpose) == str:
61 rospy.loginfo(
"using initialpose from script server: %s", str(initialpose))
62 initialpose = rospy.get_param(
"/script_server/base/" + initialpose)
64 rospy.loginfo(
"initialpose not set, using [0, 0, 0] as initialpose")
65 initialpose = [0, 0, 0]
68 self.initial_pose.translation.x = initialpose[0]
69 self.initial_pose.translation.y = initialpose[1]
70 quat = tf.transformations.quaternion_from_euler(0, 0, initialpose[2])
71 self.initial_pose.rotation = Quaternion(*quat)
73 rospy.Timer(rospy.Duration(0.1), self.
timer_cb)
75 rospy.loginfo(
"Emulation for base running")
80 rospy.loginfo(
"Emulation running without move_base")
85 self.as_move_base.start()
88 rospy.logwarn(
"Emulation running without move_base due to invalid value for parameter move_base_mode: '%s'", self.
move_base_mode)
91 self.initial_pose.translation.x = msg.pose.pose.position.x
92 self.initial_pose.translation.y = msg.pose.pose.position.y
93 self.initial_pose.translation.z = msg.pose.pose.position.z
95 yaw1 = tf.transformations.euler_from_quaternion(
96 [msg.pose.pose.orientation.x,
97 msg.pose.pose.orientation.y,
98 msg.pose.pose.orientation.z,
99 msg.pose.pose.orientation.w])[2]
100 yaw2 = tf.transformations.euler_from_quaternion(
101 [self.odom.pose.pose.orientation.x,
102 self.odom.pose.pose.orientation.y,
103 self.odom.pose.pose.orientation.z,
104 self.odom.pose.pose.orientation.w])[2]
106 self.initial_pose.rotation = Quaternion(*[msg.pose.pose.orientation.x,
107 msg.pose.pose.orientation.y,
108 msg.pose.pose.orientation.z,
109 msg.pose.pose.orientation.w])
110 self.odom.pose.pose = Pose()
111 self.odom.pose.pose.orientation.w = 1
114 transform = self.tf_buffer.lookup_transform(
"map",
"base_link", rospy.Time(0))
118 self.odom.pose.pose = Pose()
119 self.odom.pose.pose.orientation.w = 1
121 return TriggerResponse(
True,
"odometry resetted")
135 if time_since_last_twist < rospy.Duration(0.1):
136 new_pose = copy.deepcopy(self.odom.pose.pose)
137 yaw = tf.transformations.euler_from_quaternion([self.odom.pose.pose.orientation.x, self.odom.pose.pose.orientation.y, self.odom.pose.pose.orientation.z, self.odom.pose.pose.orientation.w])[2] + self.twist.angular.z * dt.to_sec()
138 quat = tf.transformations.quaternion_from_euler(0, 0, yaw)
139 new_pose.orientation.x = quat[0]
140 new_pose.orientation.y = quat[1]
141 new_pose.orientation.z = quat[2]
142 new_pose.orientation.w = quat[3]
143 new_pose.position.x += self.twist.linear.x * dt.to_sec() * math.cos(yaw) - self.twist.linear.y * dt.to_sec() * math.sin(yaw)
144 new_pose.position.y += self.twist.linear.x * dt.to_sec() * math.sin(yaw) + self.twist.linear.y * dt.to_sec() * math.cos(yaw)
145 self.odom.pose.pose = new_pose
148 self.odom.twist.twist.linear.x = self.twist.linear.x
149 self.odom.twist.twist.linear.y = self.twist.linear.y
150 self.odom.twist.twist.angular.z = self.twist.angular.z
153 self.odom.twist.twist = Twist()
156 odom = copy.deepcopy(self.
odom)
157 odom.header.stamp = rospy.Time.now()
158 self.pub_odom.publish(odom)
162 t_loc = TransformStamped()
163 t_loc.header.stamp = rospy.Time.now()
164 t_loc.header.frame_id =
"odom_combined" 165 t_loc.child_frame_id =
"base_footprint" 166 t_loc.transform.translation = self.odom.pose.pose.position
167 t_loc.transform.rotation = self.odom.pose.pose.orientation
170 t_odom = TransformStamped()
171 t_odom.header.stamp = rospy.Time.now()
172 t_odom.header.frame_id =
"map" 173 t_odom.child_frame_id =
"odom_combined" 176 transforms = [t_loc, t_odom]
178 self.br.sendTransform(transforms)
181 pwcs = PoseWithCovarianceStamped()
182 pwcs.header = goal.target_pose.header
183 pwcs.pose.pose = goal.target_pose.pose
185 rospy.loginfo(
"move_base: beaming robot to new goal")
188 move_base_linear_action_name =
"/move_base_linear" 190 rospy.loginfo(
"Waiting for ActionServer: %s", move_base_linear_action_name)
191 if not ac_move_base_linear.wait_for_server(rospy.Duration(1)):
192 rospy.logerr(
"Emulator move_base failed because move_base_linear action server is not available")
193 self.as_move_base.set_aborted()
195 rospy.loginfo(
"send goal to %s", move_base_linear_action_name)
196 ac_move_base_linear.send_goal(goal)
197 ac_move_base_linear.wait_for_result()
198 ac_move_base_linear_status = ac_move_base_linear.get_state()
199 ac_move_base_linear_result = ac_move_base_linear.get_result()
200 if ac_move_base_linear_status != GoalStatus.SUCCEEDED:
201 rospy.logerr(
"Emulator move_base failed because move_base_linear failed")
202 self.as_move_base.set_aborted()
205 rospy.logerr(
"Invalid move_base_action_mode")
206 self.as_move_base.set_aborted()
208 rospy.loginfo(
"Emulator move_base succeeded")
209 self.as_move_base.set_succeeded(MoveBaseResult())
212 goal = MoveBaseGoal()
213 goal.target_pose = msg
216 if not ac_move_base.wait_for_server(rospy.Duration(1)):
217 rospy.logerr(
"Emulator move_base simple failed because move_base action server is not available")
220 ac_move_base.send_goal(goal)
223 if __name__ ==
'__main__':
224 rospy.init_node(
'emulation_base')
def initalpose_callback(self, msg)
def move_base_cb(self, goal)
def move_base_simple_callback(self, msg)
def timer_cb(self, event)
def reset_odometry(self, req)
def twist_callback(self, msg)