paparazzi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[paparazzi-commits] [4812] Update python quaternion attitude visualizer


From: Allen Ibara
Subject: [paparazzi-commits] [4812] Update python quaternion attitude visualizer ( plot multiple quaternions, more flexible message binding, more complex vehicle geometry, lighting, show bar graphs)
Date: Tue, 20 Apr 2010 00:45:58 +0000

Revision: 4812
          http://svn.sv.gnu.org/viewvc/?view=rev&root=paparazzi&revision=4812
Author:   aibara
Date:     2010-04-20 00:45:58 +0000 (Tue, 20 Apr 2010)
Log Message:
-----------
Update python quaternion attitude visualizer (plot multiple quaternions, more 
flexible message binding, more complex vehicle geometry, lighting, show bar 
graphs)

Modified Paths:
--------------
    paparazzi3/trunk/sw/in_progress/python/attitude_viz.py

Modified: paparazzi3/trunk/sw/in_progress/python/attitude_viz.py
===================================================================
--- paparazzi3/trunk/sw/in_progress/python/attitude_viz.py      2010-04-19 
13:22:50 UTC (rev 4811)
+++ paparazzi3/trunk/sw/in_progress/python/attitude_viz.py      2010-04-20 
00:45:58 UTC (rev 4812)
@@ -15,26 +15,57 @@
 
 _NAME = 'attitude_viz'
 
-DEFAULT_X = 320
-DEFAULT_Y = 240
+DEFAULT_X = 800
+DEFAULT_Y = 600
 
+class TelemetryQuat:
+  def __init__(self, message_name, index, name):
+    self.message_name = message_name
+    self.index = index
+    self.name = name
+    self.qi = 1
+    self.qx = 0
+    self.qy = 0
+    self.qz = 0
+
+class TelemetryValue:
+  def __init__(self, message_name, index, name, offset, scale, max):
+    self.message_name = message_name
+    self.index = index
+    self.name = name
+    self.offset = offset
+    self.scale = scale
+    self.max = max
+    self.value = 0
+
 class MyGLCanvas(wx.glcanvas.GLCanvas):
     def __init__(self, parent):
       wx.glcanvas.GLCanvas.__init__(self, parent,-1)
       self.Bind( wx.EVT_PAINT, self.OnPaint)
       self.init = False
-      self.qi = 1
-      self.qx = 0
-      self.qy = 0
-      self.qz = 0
+      self.quats = []
+      self.graph_values = []
+      self.throttle = 0.0
+      self.mode = 0.0
+      self.airspeed = 0.0
+      for message_name, index, name in VEHICLE_QUATS:
+       self.quats.append(TelemetryQuat(message_name, index, name))
+      for message_name, index, name, offset, scale, max in BAR_VALUES:
+       self.graph_values.append(TelemetryValue(message_name, index, name, 
offset, scale, max))
 
+
     def onmsgproc(self, agent, *larg):
       data = str(larg[0]).split(' ')
-      quat_start = DATA_INDEX
-      self.qi = float(data[quat_start + 0])
-      self.qx = float(data[quat_start + 1])
-      self.qy = float(data[quat_start + 2])
-      self.qz = float(data[quat_start + 3])
+      for telemetry_quat in self.quats:
+       if (telemetry_quat.message_name == data[1]):
+         telemetry_quat.qi = float(data[telemetry_quat.index + 0])
+         telemetry_quat.qx = float(data[telemetry_quat.index + 1])
+         telemetry_quat.qy = float(data[telemetry_quat.index + 2])
+         telemetry_quat.qz = float(data[telemetry_quat.index + 3])
+
+      for graph_value in self.graph_values:
+       if (graph_value.message_name == data[1]):
+         graph_value.value = (float(data[graph_value.index + 0]) + 
graph_value.offset) / graph_value.scale
   
     def OnPaint(self,event):
       if not self.init:
@@ -53,10 +84,12 @@
       self.init = True
       
       glutInit()
-      # set viewing projection
-
       glEnable(GL_LINE_SMOOTH)
       glEnable(GL_DEPTH_TEST)
+      glEnable(GL_LIGHTING)
+      glEnable(GL_LIGHT0)
+      glEnable(GL_BLEND)
+      glShadeModel (GL_SMOOTH)
       glClearColor(1.0, 1.0, 1.0, 1.0)
       glClearDepth(1.0)
       
@@ -64,79 +97,166 @@
 
       glMatrixMode(GL_PROJECTION)
       glLoadIdentity()
-      gluPerspective(50.0, 1.0, 1.0, 30.0)
+      gluPerspective(7.0, 1.0, 95.0, 105.0)
 
       glMatrixMode(GL_MODELVIEW)
-      glLoadIdentity()
-      gluLookAt(0.0, 0.0, 10.0,
-                0.0, 0.0, 0.0,
-                0.0, 1.0, 0.0)
 
+      glLight(GL_LIGHT0, GL_POSITION, [5, 30, -20])
+      glLight(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5])
+      glLight(GL_LIGHT0, GL_SPECULAR, [0.0, 0.0, 0.0])
+      glLight(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8])
+      glEnable(GL_COLOR_MATERIAL)
+      glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE)
+
+    def DrawCircle(self, radius):
+      glBegin(GL_TRIANGLE_FAN)
+      glVertex3f(0, 0, 0)
+      for angle in range (0, 361, 8):
+       glVertex3f( math.sin(math.radians(angle)) * radius, 
math.cos(math.radians(angle)) * radius, 0)
+      glEnd()
+  
+
+    # draw quad centered at origin, z = 0
+    def DrawQuad(self, width, height):
+      glBegin (GL_QUADS)
+      glVertex3f( width, height, 0)
+      glVertex3f( -width, height, 0)
+      glVertex3f( -width, -height, 0)
+      glVertex3f( width, -height, 0)
+      glEnd()
+
+    def DrawBox(self, width, height, depth):
+      glPushMatrix()
+      glTranslate(0, 0, depth)
+      self.DrawQuad(width, height)
+      glTranslate(0, 0, -2 * depth)
+      self.DrawQuad(width, height)
+      glPopMatrix()
+
+      glPushMatrix()
+      glRotate(90, 1, 0, 0)
+      glTranslate(0, 0, height)
+      self.DrawQuad(width, depth)
+      glTranslate(0, 0, -2 * height)
+      self.DrawQuad(width, depth)
+      glPopMatrix()
+
+      glPushMatrix()
+      glRotate(90, 0, 1, 0)
+      glTranslate(0, 0, width)
+      self.DrawQuad(depth, height)
+      glTranslate(0, 0, -2 * width)
+      self.DrawQuad(depth, height)
+      glPopMatrix()
+
+    def DrawVehicle(self, name):
+       wingspan = 2.7
+       separation = 0.7
+       chord = 0.35
+       thickness = 0.08
+       strutcount = 5
+       discradius = 0.45
+       discseparation = 0.01
+
+       #wings
+       glColor3f(0.1, 0.1, 0.9)
+       glPushMatrix()
+       glTranslate(0, 0, separation)
+       self.DrawBox(wingspan, chord, thickness)
+       glColor3f(0.0, 0.0, 0.0)
+       glTranslate(-wingspan, -0.2, thickness + 0.01)
+       glScale(0.004, 0.004, 0.004)
+       glutStrokeString(GLUT_STROKE_ROMAN, name)
+       glPopMatrix()
+
+       glPushMatrix()
+       glTranslate(0, 0, -separation)
+       glColor3f(0.6, 0.6, 0.2)
+       self.DrawBox(wingspan, chord, thickness)
+       glColor3f(0.0, 0.0, 0.0)
+       glTranslate(wingspan, -0.2, -0.01 - thickness)
+       glScale(0.004, 0.004, 0.004)
+       glRotate(180, 0, 1, 0)
+       glutStrokeString(GLUT_STROKE_ROMAN, name)
+       glPopMatrix()
+
+       # struts
+       glColor3f(0.4, 0.4, 0.4)
+       glPushMatrix()
+       glTranslate(-wingspan, 0, 0)
+       glRotate(90, 0, 1, 0)
+       for x in range (0, strutcount):
+         self.DrawBox(separation, chord - .01, thickness)
+         glTranslate(0, 0, 2 * wingspan/(strutcount - 1))
+       glPopMatrix()
+
+       #rotors
+       glColor3f(0.9, 0.1, 0.1)
+       glPushMatrix()
+       glRotate(90, 1, 0, 0)
+       glTranslate(-wingspan, separation, -(chord + .01))
+       for x in range (0, strutcount):
+         if (x != strutcount/2):
+           self.DrawCircle(discradius)
+         glTranslate(2 * wingspan/(strutcount - 1), 0, 0)
+       glPopMatrix()
+
+       glPushMatrix()
+       glRotate(90, 1, 0, 0)
+       glTranslate(-wingspan, -separation, -(chord + .01))
+       for x in range (0, strutcount):
+         if (x != strutcount/2):
+           self.DrawCircle(discradius)
+         glTranslate(2 * wingspan/(strutcount - 1), 0, 0)
+       glPopMatrix()
+
+    def DrawBar(self, name, value):
+      bar_height = 0.12
+      bar_length = 3
+      glPushMatrix()
+      glColor3f(0, 0, 0)
+      glTranslate(-bar_length, -0.09, 0.02)
+      glScale(0.0015, 0.0015, 0.0015)
+      glutStrokeString(GLUT_STROKE_ROMAN, name)
+      glPopMatrix()
+      glColor3f(0.92, 0.92, 0.92)
+      glPushMatrix()
+      glTranslate(0, 0, 0)
+      self.DrawQuad(bar_length, bar_height)
+      glPopMatrix()
+      glPushMatrix()
+      glTranslate(bar_length * value - bar_length, 0, 0.01)
+      glColor3f(0.6, 0.6, 0.6)
+      self.DrawQuad(bar_length * value, bar_height)
+      glPopMatrix()
+
     def Draw(self):
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
 
       glMatrixMode(GL_MODELVIEW)
       glLoadIdentity()
-      gluLookAt(0.0, 0.0, 10.0,
+      gluLookAt(0.0, 0.0, 100.0,
                 0.0, 0.0, 0.0,
                 0.0, 1.0, 0.0)
 
-      glRotate(ROTATION_DIRECTION * 360 * math.acos(self.qi) / math.pi, 
self.qy, -self.qz, -self.qx)
-      if (ROTATE_180):
-       glRotate(180, 0, 1, 0)
-  
-      span = 3 * 0.8
-      height = 3 * 0.5
-      length = 3 * 0.3
-      
-      glBegin (GL_QUADS)
-      glColor3f( 0.9, 0.0, 0.0)
-      glVertex3f( span, length, height)
-      glVertex3f( -span, length, height)
-      glVertex3f( -span, -length, height)
-      glVertex3f( span, -length, height)
-      glEnd()
+      height = 5
 
-      glBegin (GL_QUADS)
-      glColor3f( 0.0, 0.8, 0.8)
-      glVertex3f( span, length, -height)
-      glVertex3f( -span, length, -height)
-      glVertex3f( -span, -length, -height)
-      glVertex3f( span, -length, -height)
-      glEnd()
+      glDisable(GL_LIGHTING)
+      glPushMatrix()
+      for graph_value in self.graph_values:
+       self.DrawBar(graph_value.name % (graph_value.value), graph_value.value 
/ graph_value.max)
+       glTranslate(0, 0.35, 0)
+      glPopMatrix()
+      glEnable(GL_LIGHTING)
 
-      glBegin (GL_QUADS)
-      glColor3f( 0.0, 0.6, 0.6)
-      glVertex3f( span, length, height)
-      glVertex3f( span, -length, height)
-      glVertex3f( span, -length, -height)
-      glVertex3f( span, length, -height)
-      glEnd()
+      glTranslate(0, -height + (height / len(self.quats) + 1),  0)
+      for telemetry_quat in self.quats:
+        glPushMatrix()
+        glRotate(360 * math.acos(telemetry_quat.qi) / math.pi, 
telemetry_quat.qy, -telemetry_quat.qz, -telemetry_quat.qx)
+       self.DrawVehicle(telemetry_quat.name)
+       glPopMatrix()
+        glTranslate(0,  2 * height / (len(self.quats)), 0)
 
-      glBegin (GL_QUADS)
-      glColor3f( 0.6, 0.0, 0.0)
-      glVertex3f( -span, length, height)
-      glVertex3f( -span, -length, height)
-      glVertex3f( -span, -length, -height)
-      glVertex3f( -span, length, -height)
-      glEnd()
-
-      glBegin (GL_QUADS)
-      glColor3f( 0.0, 0.6, 0.0)
-      glVertex3f(  span, length, height)
-      glVertex3f( -span, length, height)
-      glVertex3f( -span, length, -height)
-      glVertex3f( span, length, -height)
-      glEnd()
-
-      glBegin (GL_QUADS)
-      glColor3f( 0.6, 0.0, 0.6)
-      glVertex3f(  span, -length, height)
-      glVertex3f( -span, -length, height)
-      glVertex3f( -span, -length, -height)
-      glVertex3f( span, -length, -height)
-      glEnd()
-
 class MainWindow(wx.Frame):
   """ simple wx.Frame derived class. """
   def __init__(self, parent, id, title):
@@ -161,9 +281,22 @@
       lambda x,y: y, 
       lambda x,z: z 
     )
+
     IvyStart("")
-    bind_string = "(^.*" + MESSAGE_NAME + ".*$)"
-    IvyBindMsg(self.panel.onmsgproc, bind_string)
+
+    # list of all message names
+    messages = []
+
+    # append all message names
+    for vehicle_quat in VEHICLE_QUATS:
+      messages.append(vehicle_quat[0])
+    for bar_value in BAR_VALUES:
+      messages.append(bar_value[0])
+    
+    # bind to set of messages (ie, only bind each message once)
+    for message_name in set(messages): 
+      bind_string = "(^.*" + message_name + ".*$)"
+      IvyBindMsg(self.panel.onmsgproc, bind_string)
   def OnPaint(self, event):
     pass
        
@@ -172,13 +305,11 @@
     self.size_x = DEFAULT_X
     self.size_y = DEFAULT_X
 
-    self.edit = wx.TextCtrl(self)
     self.panel = MyGLCanvas(self)
     self.panel.SetClientSize( (self.size_x, self.size_y))
   def InitLayout( self):
       box = wx.BoxSizer(wx.VERTICAL)
       box.Add( self.panel, 0, wx.EXPAND)
-      box.Add( self.edit, 0, wx.EXPAND)
       box.Fit( self)
       self.SetSizer( box)
       self.Fit()
@@ -188,49 +319,23 @@
 
       
 if __name__ == "__main__":
-  global DATA_INDEX
-  DATA_INDEX = 6
-  ROTATION_DIRECTION = 1
-  ROTATE_180 = 0
-  MESSAGE_NAME = "BOOZ2_AHRS_REF_QUAT"
-  TITLE = "Attitude_Viz"
+  global VEHICLE_QUATS, BAR_VALUES
+  VEHICLE_QUATS = [ ["AHRS_DEBUG_QUAT", 2, "JOBY"], ["AHRS_DEBUG_QUAT", 10, 
"POINE"], ["AHRS_DEBUG_QUAT", 6, "XSENS Estimation"], ["BOOZ2_AHRS_REF_QUAT", 
2, "Reference"]]
+  BAR_VALUES = [ ["AIRSPEED", 3, "Airspeed (m/s) %i", 0, 1, 40], 
["BOOZ2_RADIO_CONTROL", 5, "Throttle (%%) %i", 9600, 96 * 2, 100], 
["BOOZ2_RADIO_CONTROL", 6, "Mode %i", -9600, -9600, 2]]
+  window_title = "Attitude_Viz"
   try:
-    opts, args = getopt.getopt(sys.argv[1:], "braod:t:m:",
-      ["double-buffer", 
-       "reverse",
-       "rot",
-       "title",
-       "message",
-       "data-index"])
+    opts, args = getopt.getopt(sys.argv[1:], "t:",
+      ["title"])
     for o,a in opts:
-      if o in ("-b", "--double-buffer"):
-        doubleBuffer = True
-      elif o in ("-d", "--data-index"):
-        DATA_INDEX = int(a)
-      elif o in ("-r", "--reverse"):
-       ROTATION_DIRECTION=-1
-      elif o in ("-o", "--rot"):
-       print "rot"
-       ROTATE_180=1
-      elif o in ("-t", "--title"):
-       TITLE=a
-      elif o in ("-m", "--message"):
-       MESSAGE_NAME=a
-      elif o in ("-a", "--alt-message"):
-       MESSAGE_NAME = "AHRS_DEBUG"
+      if o in ("-t", "--title"):
+       window_title = a
   except getopt.error, msg:
       print msg
       print """usage:
--b, --double-buffer           enable double buffer
--d, --data-index              set data index
--r, --reverse                 reverse rotation direction
--o, --rot                     rotate 180 in roll
 -t, --title                   set window title
--m, --message                 set message name
--a, --alt-message             use alternate message name
 """
 
   app = wx.PySimpleApp()
-  frame = MainWindow( None, -1, TITLE)
+  frame = MainWindow( None, -1, window_title)
   frame.Center()
   app.MainLoop()





reply via email to

[Prev in Thread] Current Thread [Next in Thread]