axis.py,glcanon.py rework icons display (JA)

whac-a-mole to work better with permutations of
   trivkins with omitted axis letter (example: xz lathe with dummy y)
   gentrivkins with duplicated axis letters (example: gantry)

Known JA Issue:
     An axis coordinate may specify a corresponding
     locking indexer joint.  Jogging is not allowed
     on this joint.  Currently, the axis can be jogged
     in teleop mode.  This should be disallowed too.

Signed-off-by: Dewey Garrett <dgarrett@panix.com>
This commit is contained in:
Dewey Garrett 2016-03-14 11:05:32 -07:00 committed by Sebastian Kuzminsky
parent 9931f1b1dc
commit ac063ef2bd
2 changed files with 207 additions and 68 deletions

View file

@ -382,6 +382,8 @@ class GlCanonDraw:
self.cached_tool = -1 self.cached_tool = -1
self.initialised = 0 self.initialised = 0
self.no_joint_display = False self.no_joint_display = False
self.kinstype = "UNKNOWN"
self.trajcoordinates = "unknown"
def realize(self): def realize(self):
self.hershey = hershey.Hershey() self.hershey = hershey.Hershey()
@ -923,7 +925,7 @@ class GlCanonDraw:
def axes_count(self): def axes_count(self):
ct = 0 ct = 0
for i in range(linuxcnc.MAX_JOINTS): for i in range(self.stat.joints):
if self.stat.axis_mask & (1<<i): ct +=1 if self.stat.axis_mask & (1<<i): ct +=1
return ct return ct
@ -1172,7 +1174,9 @@ class GlCanonDraw:
glPushMatrix() glPushMatrix()
glLoadIdentity() glLoadIdentity()
limit, homed, posstrs, droposstrs = self.posstrs(self.no_joint_display) limit, homed, posstrs, droposstrs = self.posstrs(self.no_joint_display,
self.kinstype,
self.trajcoordinates)
charwidth, linespace, base = self.get_font_info() charwidth, linespace, base = self.get_font_info()
@ -1198,7 +1202,7 @@ class GlCanonDraw:
maxlen = 0 maxlen = 0
ypos -= linespace+5 ypos -= linespace+5
i=0 sline = 0 # zeroth line of string in posstrs
glColor3f(*self.colors['overlay_foreground']) glColor3f(*self.colors['overlay_foreground'])
if not self.get_show_offsets(): if not self.get_show_offsets():
for string in posstrs: for string in posstrs:
@ -1207,40 +1211,67 @@ class GlCanonDraw:
for char in string: for char in string:
glCallList(base + ord(char)) glCallList(base + ord(char))
if i < len(homed) and homed[i]: if ( ("Dia" in string)
if "Dia" in string: or ("Vel" in string)
# use line below or ("DTG" in string)
glRasterPos2i(pixel_width + 8, ypos - linespace) or (len(string) == 0)
glBitmap(13, 16, 0, 3, 17, 0, homeicon) ):
else: ypos -= linespace
if ( ( self.get_joints_mode() continue
or (self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY)
or all_joints_homed
)
and not (("Vel" in string) or ("DTG" in string))
):
glRasterPos2i(pixel_width + 8, ypos)
glBitmap(13, 16, 0, 3, 17, 0, homeicon)
if i < len(homed) and limit[i]: aletter = string.replace(" ","").split(":")[0]
if ( self.get_joints_mode() if ( aletter in ["X","Y","Z","A","B","C","U","V","W"]
or ( (self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY) and self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY
and (i < axes_count) ):
# pathological case may have more limits than axis letters idx = self.jnum_for_aletter(aletter,
# but rejecting i >=_axes count prevents some wrong display self.kinstype,
) self.trajcoordinates)
elif aletter == "Rad":
idx = 0; # specialcase
else: idx = sline
# print "!!!sline=%d aletter=%s idx=%d kinstype=%s"%(sline,aletter,idx,self.kinstype)
if homed[idx]:
if ( self.get_joints_mode()
or (self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY)
or all_joints_homed
):
glRasterPos2i(pixel_width + 8, ypos)
glBitmap(13, 16, 0, 3, 17, 0, homeicon)
if limit[idx]:
if ( self.get_joints_mode()
or self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY
): ):
glBitmap(13, 16, 0, 1, 17, 0, limiticon) glBitmap(13, 16, 0, 1, 17, 0, limiticon)
ypos -= linespace ypos -= linespace
i = i + 1 sline = sline + 1
#-----------------------------------------------------------------------
if self.get_show_offsets(): if self.get_show_offsets():
i=0 sline = 0 # zeroth line in droposstrs
for string in droposstrs: for string in droposstrs:
maxlen = max(maxlen, len(string)) maxlen = max(maxlen, len(string))
glRasterPos2i(5, ypos) glRasterPos2i(5, ypos)
for char in string: for char in string:
glCallList(base + ord(char)) glCallList(base + ord(char))
if i < len(homed) and homed[i]:
if ( ("G5" in string)
or ("TL" in string)
or ("Dia" in string)
or (len(string) == 0)
):
ypos -= linespace
continue
aletter = string.replace(" ","").split(":")[0]
if ( aletter in ["X","Y","Z","A","B","C","U","V","W"]
and self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY
):
idx = self.jnum_for_aletter(aletter,
self.kinstype,
self.trajcoordinates)
elif aletter == "Rad":
idx = 0; # specialcase
else: idx = sline
if homed[idx]:
if ( ( self.get_joints_mode() if ( ( self.get_joints_mode()
or (self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY) or (self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY)
or all_joints_homed or all_joints_homed
@ -1251,7 +1282,7 @@ class GlCanonDraw:
glBitmap(13, 16, 0, 3, 17, 0, homeicon) glBitmap(13, 16, 0, 3, 17, 0, homeicon)
ypos -= linespace ypos -= linespace
i = i + 1 sline = sline + 1
glDepthFunc(GL_LESS) glDepthFunc(GL_LESS)
glDepthMask(GL_TRUE) glDepthMask(GL_TRUE)
@ -1287,7 +1318,31 @@ class GlCanonDraw:
gluDeleteQuadric(q) gluDeleteQuadric(q)
glEndList() glEndList()
def posstrs(self,no_joint_display=False): def aletter_for_jnum(self,jnum,kinstype,trajcoordinates):
if kinstype == "trivkins":
if not (self.stat.axis_mask & (1<<jnum)):
return "NOALETTER"
else:
return "XYZABCUVW"[jnum]
elif "gentrivkins" in kinstype:
return trajcoordinates[jnum]
else:
guess = trajcoordinates[jnum]
return guess
def jnum_for_aletter(self,aletter,kinstype,trajcoordinates):
aletter = aletter.upper()
if kinstype == "trivkins":
return "XYZABCUVW".index(aletter)
elif "gentrivkins" in kinstype:
return trajcoordinates.index(aletter)
else:
guess = trajcoordinates.index(aletter)
return guess
def posstrs(self,no_joint_display=False,kinstype="UNKNOWN",trajcoordinates="UNKNOWN"):
self.kinstype = kinstype
self.trajcoordinates = trajcoordinates.upper()
s = self.stat s = self.stat
self.no_joint_display = no_joint_display self.no_joint_display = no_joint_display
limit = list(s.limit[:]) limit = list(s.limit[:])
@ -1369,32 +1424,57 @@ class GlCanonDraw:
rotformat = "% 5s %1s:% 9.4f" rotformat = "% 5s %1s:% 9.4f"
diaformat = " " + format diaformat = " " + format
coord_letters = []
for l in self.trajcoordinates.upper():
if l == " ": continue
coord_letters.append(l)
traj_letters = []
for l in self.trajcoordinates: traj_letters.append(l)
posstrs = [] posstrs = []
droposstrs = [] droposstrs = []
for i in range(9): used_letters = []
a = "XYZABCUVW"[i] for i in range(self.stat.joints):
if s.axis_mask & (1<<i): if self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY:
posstrs.append(format % (a, positions[i])) a = self.aletter_for_jnum(i,self.kinstype,self.trajcoordinates)
droposstrs.append(droformat % (a, positions[i], a, axisdtg[i])) else:
a = self.trajcoordinates.upper()[i]
if a == "NOALETTER": continue
idx = "XYZABCUVW".index(a)
if ((a not in used_letters) and (a in traj_letters)):
posstrs.append(format % (a, positions[idx]))
droposstrs.append(droformat % (a, positions[idx], a, axisdtg[idx]))
used_letters.append(a)
droposstrs.append("") droposstrs.append("")
for i in range(9): for i in range(self.stat.joints):
index = s.g5x_index index = s.g5x_index
if index<7: if index<7:
label = "G5%d" % (index+3) label = "G5%d" % (index+3)
else: else:
label = "G59.%d" % (index-6) label = "G59.%d" % (index-6)
a = "XYZABCUVW"[i] if self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY:
if s.axis_mask & (1<<i): a = self.aletter_for_jnum(i,self.kinstype,self.trajcoordinates)
else:
a = "XYZABCUVW"[i]
if a == "NOALETTER": continue
if (a in traj_letters):
# if s.axis_mask & (1<<i):
droposstrs.append(offsetformat % (label, a, g5x_offset[i], a, g92_offset[i])) droposstrs.append(offsetformat % (label, a, g5x_offset[i], a, g92_offset[i]))
droposstrs.append(rotformat % (label, 'R', s.rotation_xy)) droposstrs.append(rotformat % (label, 'R', s.rotation_xy))
droposstrs.append("") droposstrs.append("")
for i in range(9): for i in range(self.stat.joints):
a = "XYZABCUVW"[i] if self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY:
if s.axis_mask & (1<<i): a = self.aletter_for_jnum(i,self.kinstype,self.trajcoordinates)
else:
a = "XYZABCUVW"[i]
if a == "NOALETTER": continue
if (a in traj_letters):
# if s.axis_mask & (1<<i):
droposstrs.append(rotformat % ("TLO", a, tlo_offset[i])) droposstrs.append(rotformat % ("TLO", a, tlo_offset[i]))

View file

@ -568,7 +568,9 @@ class MyOpengl(GlCanonDraw, Opengl):
def redraw_dro(self): def redraw_dro(self):
self.stat.poll() self.stat.poll()
limit, homed, posstrs, droposstrs = self.posstrs(no_joint_display) limit, homed, posstrs, droposstrs = self.posstrs(no_joint_display,
kinstype,
trajcoordinates)
text = widgets.numbers_text text = widgets.numbers_text
@ -584,40 +586,60 @@ class MyOpengl(GlCanonDraw, Opengl):
text.delete("0.0", "end") text.delete("0.0", "end")
t = droposstrs[:] t = droposstrs[:]
i = 0 sline = 0 # zeroth line in t string
axes_count = masked_axes_count() axes_count = masked_axes_count()
for ts in t: for ts in t:
idx = sline
aletter = ts.replace(" ","").split(":")[0]
if ( ("Dia" in ts)
or ("Vel" in ts)
or ("G5" in ts)
or ("TLO" in ts)
or (len(ts) == 0)
):
sline += 1
continue
if ( aletter in ["X","Y","Z","A","B","C","U","V","W"]
and self.stat.kinematics_type == linuxcnc.KINEMATICS_IDENTITY
):
idx = jnum_for_aletter(aletter)
elif aletter == "Rad":
idx = 0; # specialcase
else: idx = sline
if s.motion_mode == linuxcnc.TRAJ_MODE_FREE: if s.motion_mode == linuxcnc.TRAJ_MODE_FREE:
imax = len(homed) imax = len(homed)
if s.kinematics_type == linuxcnc.KINEMATICS_IDENTITY: if s.kinematics_type == linuxcnc.KINEMATICS_IDENTITY:
imax = axes_count imax = axes_count
if i < imax and homed[i]: if homed[idx]:
t[i] += "*" t[sline] += "*"
else: else:
t[i] += " " t[sline] += " "
if i < imax and limit[i]: if limit[idx]:
t[i] += "!" t[sline] += "!"
else: else:
t[i] += " " t[sline] += " "
else: # teleop mode else: # teleop mode
if s.kinematics_type == linuxcnc.KINEMATICS_IDENTITY: if s.kinematics_type == linuxcnc.KINEMATICS_IDENTITY:
if i < axes_count and homed[i]: if idx < axes_count and homed[idx]:
t[i] += "*" t[sline] += "*"
else: else:
t[i] += " " t[sline] += " "
if i < axes_count and limit[i]: if idx < axes_count and limit[idx]:
t[i] += "!" t[sline] += "!"
else: else:
t[i] += " " t[sline] += " "
else: # non-identity kinematics else: # non-identity kinematics
all_joints_homed = all_homed() all_joints_homed = all_homed()
if i < axes_count and all_joints_homed: #if idx < axes_count and all_joints_homed:
t[i] += "*" if all_joints_homed:
t[sline] += "*"
else: else:
t[i] += " " t[sline] += " "
# Note: teleop and non-identity: # Note: teleop and non-identity:
# don't try to display joint limits # don't try to display joint limits
i+=1 sline+=1
text.insert("end", "\n".join(t)) text.insert("end", "\n".join(t))
@ -1802,7 +1824,6 @@ def go_home(num):
def switch_to_teleop(ct,delta_secs,max_wait_secs): def switch_to_teleop(ct,delta_secs,max_wait_secs):
import threading import threading
s.poll() s.poll()
#print ct,get_states()
if s.task_state != linuxcnc.STATE_ON: if s.task_state != linuxcnc.STATE_ON:
print("AUTO_TELEOP: ABANDON (task_state=%s)" print("AUTO_TELEOP: ABANDON (task_state=%s)"
% task_statename(s.task_state)) % task_statename(s.task_state))
@ -2543,10 +2564,12 @@ class TclCommands(nf.TclCommands):
c.unhome(jnum) c.unhome(jnum)
def home_joint_number(num): def home_joint_number(num):
# invoked by machine menu/home widgets
ensure_mode(linuxcnc.MODE_MANUAL) ensure_mode(linuxcnc.MODE_MANUAL)
go_home(num) go_home(num)
def unhome_joint_number(num): def unhome_joint_number(num):
# invoked by machine menu/unhome widgets
ensure_mode(linuxcnc.MODE_MANUAL) ensure_mode(linuxcnc.MODE_MANUAL)
c.unhome(num) c.unhome(num)
@ -3225,6 +3248,8 @@ root_window.tk.call("setup_menu_accel", widgets.unhomemenu, "end", _("Unhome All
trajcoordinates=inifile.find("TRAJ", "COORDINATES").lower().replace(" ","") trajcoordinates=inifile.find("TRAJ", "COORDINATES").lower().replace(" ","")
vars.trajcoordinates.set(trajcoordinates) vars.trajcoordinates.set(trajcoordinates)
kinstype=inifile.find("KINS", "KINEMATICS").lower()
duplicate_coord_letters = "" duplicate_coord_letters = ""
for i in range(len(trajcoordinates)): for i in range(len(trajcoordinates)):
if trajcoordinates[i] == " ": continue if trajcoordinates[i] == " ": continue
@ -3259,16 +3284,50 @@ while s.joints == 0:
"More information may be available when running from a terminal.") "More information may be available when running from a terminal.")
s.poll() s.poll()
num_joints = s.joints def jnum_for_aletter(aletter):
for i in range(num_joints): if s.kinematics_type != linuxcnc.KINEMATICS_IDENTITY:
#if not (s.axis_mask & (1<<i)): continue # ja:not needed for consecutive joints raise SystemExit("jnum_for_aletter: Must be KINEMATICS_IDENTITY")
widgets.homemenu.add_command(command=lambda i=i: commands.home_joint_number(i)) aletter = aletter.lower()
widgets.unhomemenu.add_command(command=lambda i=i: commands.unhome_joint_number(i)) if kinstype == "trivkins":
if i >= len(trajcoordinates): break return "xyzabcuvw".index(aletter)
if s.kinematics_type == linuxcnc.KINEMATICS_IDENTITY: elif "gentrivkins" in kinstype:
ja_name = "Axis"; ja_id = trajcoordinates[i].upper() return trajcoordinates.index(aletter)
else: else:
ja_name = "Joint"; ja_id = i guess = trajcoordinates.index(aletter)
print "jnum_for_aletter guessing %s --> %d"%(aletter,guess)
return guess
def aletter_for_jnum(jnum):
if s.kinematics_type != linuxcnc.KINEMATICS_IDENTITY:
raise SystemExit("aletter_for_jnum: Must be KINEMATICS_IDENTITY")
if kinstype == "trivkins":
if not (s.axis_mask & (1<<jnum)):
return "NOALETTER"
else:
return "XYZABCUVW"[jnum]
elif "gentrivkins" in kinstype:
return trajcoordinates.upper()[jnum]
else:
guess = trajcoordinates.upper()[jnum]
print "aletter_for_jnum guessing %d --> %s"%(jnum,guess)
return guess
num_joints = s.joints
for jnum in range(num_joints):
if s.kinematics_type == linuxcnc.KINEMATICS_IDENTITY:
ja_name = "Axis"
ja_id = aletter_for_jnum(jnum)
if ja_id == "NOALETTER": continue
widgets.homemenu.add_command(
command=lambda jnum=jnum: commands.home_joint_number(jnum))
widgets.unhomemenu.add_command(
command=lambda jnum=jnum: commands.unhome_joint_number(jnum))
else:
widgets.homemenu.add_command(
command=lambda jnum=jnum: commands.home_joint_number(jnum))
widgets.unhomemenu.add_command(
command=lambda jnum=jnum: commands.unhome_joint_number(jnum))
ja_name = "Joint"; ja_id = jnum
root_window.tk.call("setup_menu_accel", widgets.homemenu, "end", root_window.tk.call("setup_menu_accel", widgets.homemenu, "end",
_("Home %(name)s _%(id)s") % {"name":ja_name, "id":ja_id}) _("Home %(name)s _%(id)s") % {"name":ja_name, "id":ja_id})
root_window.tk.call("setup_menu_accel", widgets.unhomemenu, "end", root_window.tk.call("setup_menu_accel", widgets.unhomemenu, "end",