42 from geometry_msgs.msg
import Point
43 from sensor_msgs.msg
import LaserScan
44 from nav_msgs.msg
import Odometry
45 from tf
import transformations
47 from geometry_msgs.msg
import Twist
48 from final_assignment.srv
import switch_service, switch_serviceRequest, switch_serviceResponse
49 from final_assignment.srv
import bug0_status, bug0_statusRequest, bug0_statusResponse
50 from final_assignment.srv
import get_point, get_pointRequest, get_pointResponse
60 name_bug0_switch =
"/bug0_switch"
63 name_bug0_status =
"/bug0_status"
66 name_get_point =
"/get_point"
72 service_active =
False
87 desired_position_ = Point()
93 state_desc_ = [
'Go to point',
'wall following',
'target reached']
108 max_tolerance_target = 0.5
121 global name_get_point, srv_get_point
122 global desired_position_
128 rospy.set_param(
"des_pos_x", desired_position_.x)
129 rospy.set_param(
"des_pos_y", desired_position_.y)
147 global state_, state_desc_, only_once, service_active
148 global srv_client_wall_follower_, srv_client_go_to_point_
150 log =
"state changed: %s" % state_desc_[state]
162 twist_msg.linear.x = 0
163 twist_msg.angular.z = 0
164 pub.publish(twist_msg)
169 service_active =
False
181 if(math.fabs(angle) > math.pi):
182 angle = angle - (2 * math.pi * angle) / (math.fabs(angle))
190 srv_client_go_to_point_ =
None
193 srv_client_wall_follower_ =
None
221 global service_active, only_once
225 return switch_serviceResponse( success=
False, in_progress=
False )
228 only_once = data.only_once
234 service_active =
True
236 if not service_active:
237 return switch_serviceResponse( success=
True, in_progress=
False )
240 service_active =
False
247 twist_msg.linear.x = 0
248 twist_msg.angular.z = 0
249 pub.publish(twist_msg)
254 return switch_serviceResponse( success=
True, in_progress=
False )
268 global desired_position_, position_, yaw_, state_, err_pos, service_active, max_tolerance_target, err_pos
270 to_return = bug0_statusResponse( )
271 to_return.target_position = desired_position_
272 to_return.actual_position = position_
273 to_return.actual_yaw = yaw_
274 to_return.status = state_
275 to_return.active = service_active
276 to_return.distance = err_pos
277 to_return.reached = ( err_pos < max_tolerance_target )
294 global position_, yaw_
297 position_ = msg.pose.pose.position
301 msg.pose.pose.orientation.x,\
302 msg.pose.pose.orientation.y,\
303 msg.pose.pose.orientation.z,\
304 msg.pose.pose.orientation.w)
305 euler = transformations.euler_from_quaternion(quaternion)
322 'right': min(min(msg.ranges[0:143]), 10),\
323 'fright': min(min(msg.ranges[144:287]), 10),\
324 'front': min(min(msg.ranges[288:431]), 10),\
325 'fleft': min(min(msg.ranges[432:575]), 10),\
326 'left': min(min(msg.ranges[576:719]), 10),\
346 global regions_, position_, desired_position_, state_, yaw_, yaw_error_allowed_
347 global srv_client_go_to_point_, srv_client_wall_follower_, srv_client_user_interface_, pub
348 global service_active, err_pos, only_once, state_, max_tolerance_target
353 rate = rospy.Rate(20)
354 while not rospy.is_shutdown():
358 if not service_active:
362 err_pos = math.sqrt(pow(desired_position_.y - position_.y, 2) + pow(desired_position_.x - position_.x, 2))
363 if(err_pos < max_tolerance_target):
366 elif regions_[
'front'] < 0.5:
371 desired_yaw = math.atan2(desired_position_.y - position_.y, desired_position_.x - position_.x)
373 err_pos = math.sqrt(pow(desired_position_.y - position_.y, 2) + pow(desired_position_.x - position_.x, 2))
375 if(err_pos < max_tolerance_target):
378 if regions_[
'front'] > 1
and math.fabs(err_yaw) < 0.05:
384 desired_position_.x = rospy.get_param(
'des_pos_x')
385 desired_position_.y = rospy.get_param(
'des_pos_y')
387 err_pos = math.sqrt(pow(desired_position_.y - position_.y, 2) + pow(desired_position_.x - position_.x, 2))
389 if(err_pos > max_tolerance_target + 0.05):
402 rospy.loginfo(
" [%s] is OFFLINE", node_name )
407 if __name__ ==
"__main__":
409 rospy.init_node( node_name )
412 rospy.loginfo(
" [%s] advertising service %s ...", node_name, name_bug0_switch )
413 rospy.Service( name_bug0_switch, switch_service, srv_bug0_switch )
414 rospy.loginfo(
" [%s] service %s ... OK", node_name, name_bug0_switch )
417 rospy.loginfo(
" [%s] advertising service %s ...", node_name, name_bug0_status )
418 rospy.Service( name_bug0_status, bug0_status, srv_bug0_status )
419 rospy.loginfo(
" [%s] service %s ... OK", node_name, name_bug0_status )
422 rospy.loginfo(
" [%s] getting service %s ...", node_name, name_get_point )
423 rospy.wait_for_service( name_get_point )
424 srv_get_point = rospy.ServiceProxy( name_get_point, get_point )
425 rospy.loginfo(
" [%s] service %s ... OK", node_name, name_get_point )
427 sub_laser = rospy.Subscriber(
'/scan', LaserScan, clbk_laser)
428 sub_odom = rospy.Subscriber(
'/odom', Odometry, clbk_odom)
429 pub = rospy.Publisher(
'/cmd_vel', Twist, queue_size=1)
431 srv_client_go_to_point_ = rospy.ServiceProxy(
'/go_to_point_switch', SetBool)
432 srv_client_wall_follower_ = rospy.ServiceProxy(
'/wall_follower_switch', SetBool)
def main()
The main section of the Bug0 algorithm.
srv_get_point
call-point of the service 'get_point'
def cbk_on_shutdown()
Called on the shutdown of the node.
def srv_bug0_switch(data)
Turn on or off the node.
srv_client_wall_follower_
call-point of the service 'wall_follow_switch'
def clbk_laser(msg)
Get the laser measurements.
srv_client_go_to_point_
call-point of the service 'go_to_point_switch'
def change_state(state)
Change the state of the node.
def normalize_angle(angle)
Normalize an angle in [-pi, pi].
def srv_bug0_status(empty)
Get the status of the service.
def clbk_odom(msg)
Get the actual posture.
def new_random_target()
Get a new randomly-chosen target.