00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 from starmac_viz.viz_module_base import VizModuleBase
00033 import rospy
00034
00035 import random
00036 import numpy as np
00037 from math import degrees, radians
00038
00039 import tf.transformations as tft
00040 from tf import TransformBroadcaster
00041
00042 from starmac_roslib.viz.colors import Alpha, Colors
00043 from starmac_roslib.viz.markers import MarkerGroup, VerticalLineMarker, TextMarker, TrailMarker, \
00044 HeadingMarker, PolygonMarker, QuadrotorMarker
00045
00046
00047 from nav_msgs.msg import Odometry
00048 from visualization_msgs.msg import Marker, MarkerArray
00049 from flyer_controller.msg import controller_status
00050
00051 from util import alt_color
00052
00053 XMAX = 3.5
00054 YMAX = 3.5
00055 XMIN = -3.5
00056 YMIN = -4.0
00057 WARN_DIST = 1.0
00058
00059 class BasicVizModule(VizModuleBase):
00060 """
00061 A 'basic' visualization module. Provides the following:
00062
00063 - altitude (graphical and text)
00064 - heading (graphical and text)
00065 - position (text)
00066 - trajectory 'trail', with altitude-color-coding
00067 - ground track, the projection of the trajectory on the ground plane
00068 - boundary, changes color from green -> yellow -> red depending on proximity of flyer
00069 """
00070
00071 def __init__(self):
00072 super(BasicVizModule, self).__init__(id="basic")
00073
00074 def init_viz(self):
00075 self.mode_t = TextMarker('mode', '', (0,0,0))
00076 self.heading_marker = HeadingMarker('heading', (0,0,0))
00077 self.vlm = VerticalLineMarker('altitude', (1,1), color=Colors.WHITE + Alpha(0.5))
00078 self.alt_t = TextMarker('altitude', '0.0', (0,0,0))
00079 self.pos_t = TextMarker('position', '0.0,0.0', (0,0,0))
00080 self.trail = TrailMarker('trail', [], colors=[], color=Colors.BLUE + Alpha(0.8))
00081 self.trail.set_max_points(500)
00082 self.ground_trail = TrailMarker('ground_track', [], color=Colors.WHITE + Alpha(0.2))
00083 self.ground_trail.set_max_points(500)
00084 self.boundary = PolygonMarker('boundary', ((XMAX,YMAX,0), (XMIN,YMAX,0), (XMIN,YMIN,0), (XMAX,YMIN,0)),
00085 color=Colors.RED+Alpha(0.5), width=0.02)
00086 self.quadrotor = QuadrotorMarker('quadrotor', frame_id='/viz/flyer_axes')
00087 self.mg = MarkerGroup(VizModuleBase.mapub)
00088 self.mg.add(self.mode_t, self.vlm, self.alt_t, self.pos_t, self.trail,
00089 self.ground_trail, self.heading_marker, self.boundary, self.quadrotor)
00090
00091
00092
00093
00094
00095
00096 def init_vars(self):
00097 self.trajectory = np.empty((1000,3))
00098 self.n_trajectory = 0
00099
00100 def init_subscribers(self):
00101 prefix = self.subscriber_topic_prefix
00102
00103 self.odom_sub = rospy.Subscriber('~odom', Odometry, self.odom_callback)
00104 self.controller_status_sub = rospy.Subscriber(prefix+'controller/status', controller_status, self.controller_status_callback)
00105
00106 def publish_timer_callback(self, event):
00107 now = rospy.Time.now()
00108 if self.latest_controller_status is not None:
00109 self.mode_t.set(text=self.latest_controller_status.active_mode)
00110 if self.latest_odom is not None:
00111 pos = self.latest_odom.pose.pose.position
00112 loppo = self.latest_odom.pose.pose.orientation
00113 ori_ypr = tft.euler_from_quaternion((loppo.x, loppo.y, loppo.z, loppo.w), 'rzyx')
00114 self.vlm.set((pos.x,pos.y), zend=pos.z)
00115 self.mode_t.set(pos=(pos.x,pos.y,pos.z - 0.1))
00116 self.alt_t.set(text="%.3f" % -pos.z, pos=(pos.x,pos.y,pos.z/2))
00117 self.pos_t.set(text="%.2f, %.2f" % (pos.x, pos.y), pos=(pos.x,pos.y,0.02))
00118 self.heading_marker.set(pos=(pos.x,pos.y,pos.z), heading=degrees(ori_ypr[0]))
00119 self.tfbr.sendTransform((pos.x,pos.y,pos.z), (loppo.x, loppo.y, loppo.z, loppo.w), now, '/viz/flyer_axes', '/ned')
00120 self.tfbr.sendTransform((pos.y,pos.x,-pos.z), (0,0,0,1), now, '/viz/chase', '/enu')
00121 self.tfbr.sendTransform((0,0,0), tft.quaternion_from_euler(0,radians(180),0,'rzyx'), now, '/viz/onboard', '/viz/flyer_axes')
00122 VizModuleBase.publish(self,now)
00123
00124 def odom_callback(self, msg):
00125 self.latest_odom = msg
00126 pos = self.latest_odom.pose.pose.position
00127 self.trajectory[self.n_trajectory,:] = (pos.x, pos.y, pos.z)
00128 self.n_trajectory += 1
00129 if self.n_trajectory == self.trajectory.shape[0]:
00130 self.trajectory.resize((self.n_trajectory+1000,3))
00131 self.trail.append_points([(pos.x, pos.y, pos.z)], [alt_color(-pos.z)])
00132 self.ground_trail.append_points([(pos.x, pos.y, 0)])
00133 mindist = min([a-b for a,b in ((XMAX, pos.x), (pos.x, XMIN), (YMAX, pos.y), (pos.y, YMIN))])
00134 if mindist <= 0:
00135 bcolor = Colors.RED + Alpha(1.0)
00136 elif mindist <= WARN_DIST:
00137 bcolor = Colors.YELLOW + Alpha(1.0)
00138 else:
00139 bcolor = Colors.GREEN + Alpha(1.0)
00140 self.boundary.set(color=bcolor)
00141
00142 def controller_status_callback(self, msg):
00143 self.latest_controller_status = msg