MoveDlg.py
Go to the documentation of this file.
00001 ###############################################################################
00002 #
00003 # Package:   RoadNarrows Hekateros Robotic Manipulator Package
00004 #
00005 # Link:      https://github.com/roadnarrows-robotics/hekateros
00006 #
00007 # ROS Node:  hek_*
00008 #
00009 # File:      MoveDlg.py
00010 #
00011 ## \file 
00012 ##
00013 ## $LastChangedDate$
00014 ## $Rev$
00015 ##
00016 ## \brief Pan-Tilt move dialog.
00017 ##
00018 ## \author Daniel Packard (daniel@roadnarrows.com)
00019 ## \author Robin Knight (robin.knight@roadnarrows.com)
00020 ##  
00021 ## \par Copyright:
00022 ##   (C) 2013-2014.  RoadNarrows LLC.\n
00023 ##   (http://www.roadnarrows.com)\n
00024 ##   All Rights Reserved
00025 ##
00026 # @EulaBegin@
00027 # @EulaEnd@
00028 #
00029 ###############################################################################
00030 
00031 import sys
00032 import os
00033 import time
00034 import math
00035 
00036 from Tkinter import *
00037 from Tkconstants import *
00038 from tkFileDialog import *
00039 import tkFont
00040 
00041 import roslib; roslib.load_manifest('hekateros_control')
00042 import rospy
00043 import trajectory_msgs.msg
00044 
00045 
00046 from hekateros_control.Utils import *
00047 
00048 
00049 # ------------------------------------------------------------------------------
00050 # Class MoveDlg
00051 # ------------------------------------------------------------------------------
00052 
00053 class MoveDlg(Toplevel):
00054   #
00055   ## \brief Constructor.
00056   ##
00057   ## \param cnf     Configuration dictionary.
00058   ## \param kw      Keyword options.
00059   #
00060   def __init__(self, master=None, cnf={}, **kw):
00061     # initialize dialog data
00062     kw = self.initData(kw)
00063 
00064     Toplevel.__init__(self, master=master, cnf=cnf, **kw)
00065     self.title(self.m_title)
00066 
00067     # create and show widgets
00068     self.createWidgets()
00069 
00070     # allows the enter button to fire either button's action
00071     self.m_bttnCancel.bind('<KeyPress-Return>', func=self.close)
00072 
00073     # center the dialog over parent panel
00074     if master is not None:
00075       self.update_idletasks()
00076       x0 = master.winfo_rootx()
00077       y0 = master.winfo_rooty()
00078       xp = x0 + (master.winfo_width() - self.winfo_width()) / 2 - 8
00079       yp = y0 + (master.winfo_height() - self.winfo_height()) / 2 - 20
00080       glist = [self.winfo_width(), self.winfo_height(), xp, yp]
00081       #self.withdraw() # hide the dialog until position and size is set
00082       self.geometry('{0}x{1}+{2}+{3}'.format(*glist))
00083       #self.deiconify() # now show
00084 
00085     # allows us to customize what happens when the close button is pressed
00086     self.protocol("WM_DELETE_WINDOW", self.close)
00087 
00088     #
00089     # Modal diagle settings.
00090     #
00091     # set the focus on dialog window (needed on Windows)
00092     self.focus_set()
00093 
00094     # make sure events only go to our dialog
00095     self.grab_set()
00096 
00097     # make sure dialog stays on top of its parent window (if needed)
00098     self.transient(master)
00099 
00100     # display the window and wait for it to close
00101     self.wait_window(self)
00102 
00103   #
00104   ## \brief Initialize class state data.
00105   ##
00106   ## \param kw      Keyword options.
00107   ##
00108   ## \return Modified keywords sans this specific class.
00109   ##
00110   def initData(self, kw):
00111     self.m_icons          = {}    # must keep loaded icons referenced
00112     if kw.has_key('title'):
00113       self.m_title = kw['title']
00114       del kw['title']
00115     else:
00116       self.m_title = "Move Pan-Tilt To..."
00117     if kw.has_key('image'):
00118       imageLoader = ImageLoader(py_pkg='hekateros_control.images')
00119       self.m_icons['image'] = imageLoader.load(kw['image'])
00120       del kw['image']
00121     else:
00122       self.m_icons['image'] = None
00123     self.m_result = False
00124     self.m_trajectory = kw['trajectory']
00125     self.m_vals = { }
00126     del kw['trajectory']
00127     return kw
00128 
00129   #
00130   ## \brief Create gui widgets with supporting data and show.
00131   #
00132   def createWidgets(self):
00133     frame = Frame(self)
00134     frame.grid(row=0, column=0)
00135 
00136     # move image 
00137     w = Label(frame)
00138     if self.m_icons['image'] is not None:
00139       w = Label(frame)
00140       w['image']  = self.m_icons['image']
00141     w['anchor'] = CENTER
00142     w.grid(row=0, column=0, rowspan=2, sticky=W+N+S)
00143 
00144     # top heading
00145     w = Label(frame)
00146     helv = tkFont.Font(family="Helvetica",size=12,weight="bold")
00147     w['font']   = helv
00148     w['text']   = 'Specify Trajectory'
00149     w['anchor'] = CENTER
00150     w.grid(row=0, column=1, sticky=E+W)
00151 
00152     width = 12
00153     padx  = 2
00154     pady  = 3
00155     row   = 1
00156 
00157     wframe = Frame(frame)
00158     wframe.grid(row=row, column=1)
00159 
00160     #
00161     # Trajectory Table
00162     #
00163     row   = 0
00164 
00165     # left column of labels
00166     for text in [' ', 'Position(deg):', 'Velocity(%max):', 'Group Velocity:']:
00167       w = Label(wframe, width=width, padx=padx, pady=pady, anchor=W, text=text)
00168       w.grid(row=row, column=0, sticky=W+S)
00169       row += 1
00170 
00171     col         = 1
00172     trajPoint   = self.m_trajectory.points[0]
00173     startGroupV = 0.0
00174 
00175     i = 0
00176     for name in self.m_trajectory.joint_names:
00177       # joint label
00178       row = 0
00179       w = Label(wframe, width=width, padx=padx, pady=pady, anchor=W, text=name)
00180       w.grid(row=row, column=col, sticky=W)
00181       self.m_vals[name] = { }
00182 
00183       # joint position
00184       row += 1
00185       var = DoubleVar()
00186       var.set(round10th(radToDeg(trajPoint.positions[i])))
00187       w = Spinbox(wframe, justify=RIGHT, textvar=var,
00188                         increment=0.1, from_=-50000.0, to=50000.0)
00189       w['width'] = 7
00190       w.grid(row=row, column=col, padx=1, pady=0, sticky=W)
00191       d = {'var': var, 'w': w}
00192       self.m_vals[name]['position'] = d
00193     
00194       # joint velocity
00195       row += 1
00196       var = DoubleVar()
00197       var.set(round10th(trajPoint.velocities[i]))
00198       startGroupV = var.get()
00199       w = Spinbox(wframe, justify=RIGHT, textvar=var,
00200                         increment=0.1, from_=0.0, to=100.0)
00201       w['width'] = 7
00202       w.grid(row=row, column=col, padx=1, pady=0, sticky=W)
00203       d = {'var': var, 'w': w}
00204       self.m_vals[name]['velocity'] = d
00205     
00206       col += 1
00207       i += 1
00208 
00209     if i > 0:
00210       self.update_idletasks()
00211       name = self.m_trajectory.joint_names[0]
00212       x0 = self.m_vals[name]['position']['w'].winfo_rootx()
00213       name = self.m_trajectory.joint_names[i-1]
00214       x1 = self.m_vals[name]['position']['w'].winfo_rootx() + \
00215            self.m_vals[name]['position']['w'].winfo_width()
00216       length = x1 - x0
00217     else:
00218       i = 1
00219       length = 100
00220 
00221     # delta group velocity
00222     self.m_varGroupVel = DoubleVar()
00223     self.m_varGroupVel.set(round10th(startGroupV))
00224     w = Scale(wframe, variable=self.m_varGroupVel,
00225                         from_=0.0, to=100.0, resolution=1.0,
00226                         orient=HORIZONTAL, command=self.setGroupV)
00227     w['width']  = 10
00228     w['length'] = length
00229     w.grid(row=3, column=1, columnspan=i, padx=1, pady=0, sticky=W)
00230 
00231     #
00232     # Dialog Buttons
00233     #
00234     row = 2
00235 
00236     wframe = Frame(frame)
00237     wframe.grid(row=row, column=1)
00238 
00239     # cancel button
00240     w = Button(wframe, width=10, text='Cancel', command=self.close)
00241     w.grid(row=0, column=0, padx=2, pady=5)
00242     w['anchor']  = CENTER
00243     self.m_bttnCancel = w
00244 
00245     # ok button
00246     w = Button(wframe, width=10, text='Move', command=self.ok)
00247     w.grid(row=0, column=1, padx=2, pady=5)
00248     w['anchor']  = CENTER
00249     self.m_bttnContinue = w
00250 
00251   #
00252   ## \brief Delta velocity callback
00253   #
00254   def setGroupV(self, v):
00255     vel = self.m_varGroupVel.get()
00256     for name in self.m_vals:
00257       self.m_vals[name]['velocity']['var'].set(vel)
00258 
00259   #
00260   ## \brief Destroy window callback.
00261   #
00262   def ok(self):
00263     i = 0
00264     trajPoint = self.m_trajectory.points[0]
00265     for name in self.m_trajectory.joint_names:
00266       pos = self.m_vals[name]['position']['var'].get()
00267       pos = degToRad(pos)
00268       vel = self.m_vals[name]['velocity']['var'].get()
00269       if vel < 0.0:
00270         vel = 0.0
00271       elif vel > 100.0:
00272         vel = 100.0
00273       trajPoint.positions[i]  = pos
00274       trajPoint.velocities[i] = vel
00275       i += 1
00276     self.m_result = True
00277     self.close()
00278 
00279   #
00280   ## \brief Destroy window callback.
00281   #
00282   def close(self):
00283     self.destroy()


hekateros_control
Author(s): Robin Knight , Daniel Packard
autogenerated on Mon Oct 6 2014 00:36:42