Jump to content

Expert question again


---
 Share

Recommended Posts

Another expert question:

What can cause the function cmmosCommand("CC") to fail with error "Message not understood: #isUndefTool:" ?

I was able to calibrate several styli without issues as long as I kept my PCM code to a few lines (basically a loop that gets the stylus system from the rack, then calls this command).

But my longer code, which has some additional parameter inquiry, checks, messages etc. fails each and every time, although the code part for the actual calibration is 99.9% the same.

Link to comment
Share on other sites

Im thinking it could be, while the stylus changes it sometimes becomes some virtual generic stylus name until it is completely changed, perhaps try adding a wait() to make sure your stylus is picked up and ready. Also double check for typographical errors.

Edited
Link to comment
Share on other sites

Posted (edited)

The thing is, when the code fails, it doesn't even perform the stylus change, but immediately complains about cmmosCommand().

I already trie to insert wait() at various points, but it didn't change anything.
I also tried a executeCode version of the stylus change command, but that also made no difference

The following is the part of the code that

  • closes the currently opened rack assignment (if any)
  • assigns the selected stylus systems to the rack holders
  • prompts the user to confirm the actual rack configuration is correct 
  • picks up the stylus systems one after another and
  • calibrates them

There's more code before that, but it's really only standard PCM requesting a list of stylus names via inquireParameterList() and doing a number of checks to ensure the input was correct.

The variable "FinalList" contains the names of the selected stylus systems as a list and "AlleAblagen" is a string with the letters of the selected rack holders.

// Tasterablagen mit den eingegebenen Tastern bestücken
//
// Zuerst aktuelle Magazinbelegung schließen
executeCode("Zeiss.CMMOS.OMTCOInternalControl current resetAssignment")

// Taster auf Ablagen setzen
for x = 1 to FinalList.size
	AktAblage=mid(AlleAblagen,x,1)
	AktTaster=getParameterNamed(FinalList,x)
	executeCode("Zeiss.CMMOS.OMCMMOSServerAccessor assignStylusSystemOrComponent: '"+AktTaster+"' toPort: '"+AktAblage+"'")
next x

// Referenztaster auf G
executeCode("Zeiss.CMMOS.OMCMMOSServerAccessor assignStylusSystemOrComponent: 'CZReferenztaster' toPort: 'G'")

// Überprüfung und Kontrollabfrage der tatsächlichen Magazinbelegung
MsgString="Bitte die folgende Magazinbelegung prüfen und ggf. bestätigen:"+cr()+cr()
for x = 1 to FinalList.size
	AktAblage=mid(AlleAblagen,x,1)
	AktTaster=executeCode("Zeiss.Calypso.OMTCOInternalControl new getConfOrComponentNameFromPort: '"+AktAblage+"'")
	MsgString=MsgString+"Ablage "+AktAblage+":          "+AktTaster+cr()+cr()
next x
if confirm(MsgString)==false then
	cncBreak()
endif


// Start des Kalibrierablaufs
//
// Referenztaster abholen und kalibrieren / Kugel einmessen
changeStylusSystem("CZReferenztaster")
cmmosCommand("CC")

// Taster nacheinander abholen und kalibrieren
// 
for x = 1 to FinalList.size
	AktTaster=getParameterNamed(FinalList,x)
	changeStylusSystem(AktTaster)
	cmmosCommand("CC")
next x

 

Edited
  • Like! 1
Link to comment
Share on other sites

Norbert,

 

 Based on the code, it's clear this is expert level stuff, but may I still ask why not use standard calibration characteristic in Calypso ?  Also - does this always happen at the same spot ? or does it fail on different stylus , etc?

This is what chatgpt says

 

 

Thanks for sharing the code snippet! Based on your description and the error #undefTool, it sounds like the issue is related to the changeStylusSystem() or assignStylusSystemOrComponent calls not properly resolving the tool name at runtime. Here are some possible causes and suggestions to investigate:


🔍 Potential Causes of #undefTool Error

  1. Invalid or Missing Tool Name

    • If AktTaster is empty, null, or contains a typo, the system won't be able to resolve the tool name.
    • Check if getParameterNamed(FinalList,x) always returns a valid stylus name.
  2. Tool Not Properly Assigned to Port

    • If assignStylusSystemOrComponent fails silently or asynchronously, the tool might not be available when changeStylusSystem is called.
    • Consider adding a verification step after assignment.
  3. Timing or Race Condition

    • If the system tries to change to a stylus before the assignment is fully registered, it could throw #undefTool.
    • Adding a short delay or confirmation after assignment might help.
  4. Reference Stylus Name Mismatch

    • You use 'CZReferenztaster' in the assignment but 'CZReferenceStylus' in the calibration. If these refer to the same tool, the name mismatch could cause issues.
  5. Corrupted or Inconsistent Tool Library

    • If the tool definitions in the CMM software are corrupted or not synchronized, it may randomly fail to resolve tools.

Suggestions to Improve Robustness

Here are a few ideas to make the code more resilient:

1. Validate Tool Names Before Use

if AktTaster == "" or AktTaster == "#undefTool" then
    log("Invalid tool name at index " + x)
    cncBreak()
endif
 
if AktTaster == "" or AktTaster == "#undefTool" then
log("Invalid tool name at index " + x)
cncBreak()
endif
 
 

2. Confirm Assignment Success

You could check the result of assignStylusSystemOrComponent if it returns a status, or re-query the port to confirm the tool is assigned.

3. Add Delay or Retry Logic

If timing is an issue, a short delay or retry loop might help:

wait(1000) // wait 1 second
 

4. Ensure Consistent Naming

Double-check that 'CZReferenztaster' and 'CZReferenceStylus' refer to the same tool, or update to use consistent naming.

5. Log and Debug

Add logging around each tool change and assignment to help trace when and where the error occurs.

Link to comment
Share on other sites

Posted (edited)

The purpose of the program is to enable an untrained user to calibrate an arbitrary selection of stylus systems in one go. I intended to use standard calibration elements at first, but that would have required to insert >60 of them in the program and always keep them up-to-date when new stylus systems are added. 

My alternative idea was to use as many calibration elements as there are rack holders (6) and change their settings dynamically via PCM before executing them (see my other thread). But I couldn't find out how to do that and so I ended up with this solution.

I think you have a few points here and I will definitely include some additional checks to find out if some of the "expert" stuff is the culprit.

Timing doesn't seem to be an issue, at least not within the calibration loop. Because if I cut away everything above the line "// Start des Kalibrierablaufs", leaving only the stylus change / calibration loop and assign the necessary variables directly, it's running flawlessly.

Rack assignment failures shouldn't be an issue too, since I read the stylus names back out from the rack before presenting them to the user for confirmation. So I don't rely on the contents of my variables, but use information stored by Calypso beforehand.

Edited
  • Like! 1
Link to comment
Share on other sites

Also, out of curiosity do you have any unusual symbols in your stylus system names ?  ° + # ^ & * or umlauts, etc ? 

Link to comment
Share on other sites

Please sign in to view this quote.

Ok, I'll bite.

I use the "#" sign a lot in styli names.

Examples:

#01_1mm_-Z

#02_2mm_+Y

What could happen using the # sign?

Link to comment
Share on other sites

Rich,  

 

 My mistake # should be ok, but maybe not with Smalltalk & executeCode() as # is used for some things in the background #mySettings #Probe  etc.

  • Like! 1
Link to comment
Share on other sites

Please sign in to view this quote.

Please sign in to view this username.

 I don't have anything to add in regards to your PCM, but using a hashtag in most programming languages "comments" out what follows. By using a hashtag, the program/script will ignore everything that follows on that line. For example, this is what that looks like in PowerShell - 

 

# Define the input string (filename)
$filename = "example/filename:with?invalid|characters*<>.txt"

# Define a string of invalid characters for filenames
$invalidChars = '/\:?"<>|*'

# Remove invalid characters
$cleanFilename = -join ($filename.ToCharArray() | Where-Object { $invalidChars -notin $_ })

# Output the cleaned filename
$cleanFilename

 

This is to done to add comments or explain to others (or remind yourself) looking at your code what each snippet is doing. Been a long time since I've used PCM, I believe the way you comment out something in PCM is the double forward slash ("//").

 

 

 

  • Like! 1
Link to comment
Share on other sites

Posted (edited)

Please sign in to view this username.

 No special characters in my probe names. Most of them are only numbers (100, 101, 102....), some have an underscore. Nothing else.

And yes, I made sure they are treated as strings.

To answer your question from yesterday: It always fails at the same spot (before getting the master probe). And it either fails every time (when the complete code is used) or never (reduced code). And it even fails in the same way on the simulation seat, so no hardware controller issues possible. 

Edited
Link to comment
Share on other sites

Posted (edited)

I think I found the error. Seems like this line was causing all the trouble:

AktTaster=executeCode("Zeiss.Calypso.OMTCOInternalControl new getConfOrComponentNameFromPort: '"+AktAblage+"'")

I admit, using this function was a shot in the dark. It gave me the information I wanted ("which stylus is in rack holder X?"), so I didn't worry about side effects.

For now I resorted to the variables for the confirmation dialog, but I'd really like to retrieve the information from where Calypso stores it, just to rule out any mismatch.

Does anybody know how I can safely read the stylus name from a rack port?

Edited
  • Like! 1
Link to comment
Share on other sites

Norbert,  glad you figure it out, brilliant work.

 

Maybe this thread will be helpful : 

 

 

 

Link to comment
Share on other sites

Please sign in to view this quote.

rackArray = getRackPorts().asArray
for i=1 to rackArray.size
    styluses = styluses + getParameterNamed("rackArray", i) + " "
next i

  • Like! 2
Link to comment
Share on other sites

Please sign in to view this quote.

Excellent! 🙂 

A bit tricky to use as the result is unsorted, but with a bit more "expert stuff" I got what I needed and now the program works.

Thanks a lot!

  • Like! 2
Link to comment
Share on other sites

  • 2 weeks later...

Please sign in to view this quote.

Im glad you found the right command to be using getRackPorts() is what you needed.
I'll post some stuff I played around with not too long ago.  The comments and workflow might not be exact.  These are just some snippets of things I was toying with:

getRackPorts()
settingGet("usedProbeConfigs")

//probe list
deleteFile("c:\temp\pickProbe.txt")
P_List="probe=inquireList("+chr(34)+"Select Probe to Evaluate"+chr(34)
for i = 1 to baseSystem().machine.machineAllProbeObjects.keys.size
P_List=P_List+","+chr(34)+getParameterNamed(baseSystem().machine.machineAllProbeObjects.keys.asList,i)+chr(34)
next i
P_List=P_List+")"
addToFile("c:\temp\pickProbe.txt",P_List)
runPCMFile("c:\temp\pickProbe.txt")
display(probe)

getRackPorts()

//gets used probe list, puts in text file
deleteFile("c:\temp\pickProbe"+getRecordHead("planid")+".txt")
P_List="probe=inquireList("+chr(34)+"Select Probe to Evaluate"+chr(34)
for i = 1 to settingGet("usedProbeConfigs").size
P_List=P_List+","+chr(34)+getParameterNamed(settingGet("usedProbeConfigs").asList,i)+chr(34)
next i
P_List=P_List+")"
addToFile("c:\temp\probechangeover"+getRecordHead("planid")+".txt" ,P_List)
runPCMFile("c:\temp\pickProbe.txt")
display(probe)

//gets probes in rack, puts in text file
repeat
deleteFile("c:\temp\proberack"+"_"+getRecordHead("planid")+".txt")
P_List="probe=inquireList("+chr(34)+"Select Probe to Evaluate"+chr(34)
for i = 1 to getRackPorts().size
P_List=P_List+","+chr(34)+getParameterNamed(getRackPorts().asList,i)+chr(34)
next i
P_List=P_List+")"
addToFile("c:\temp\proberack"+"_"+getRecordHead("planid")+".txt" ,P_List)
runPCMFile("c:\temp\proberack"+"_"+getRecordHead("planid")+".txt")
message(probe)
until (probe) == ""
display(probe)

usedprobes = settingGet("usedProbeConfigs")
if fileExists("C:\temp\Used_Probes" + "_" +getRecordHead("planid") + "_" + usedprobes +".txt") == false then 
deleteFile("C:\temp\Used_Probes" + "_" +getRecordHead("planid") +*+ ".txt")
addToFile(("C:\temp\Used_Probes" + "_" +getRecordHead("planid") + "_" + usedprobes +".txt"),usedprobes)
endif
//display(readListFile("c:\temp\UsedProbes"+"_"+getRecordHead("planid")+probe+".txt"))
//readListFile("c:\temp\UsedProbes"+"_"+getRecordHead("planid")+probe+".txt")

//gets used probe list, puts in text file
deleteFile("c:\temp\pickProbe.txt")
P_List="probe=inquireList("+chr(34)+"Select Probe to Evaluate"+chr(34)
for i = 1 to getRackPorts().size
P_List=P_List+","+chr(34)+getParameterNamed(getRackPorts().asList,i)+chr(34)
next i
P_List=P_List+")"
addToFile("c:\temp\pickProbe.txt",P_List)
runPCMFile("c:\temp\pickProbe.txt")
display(probe)
changeStylusSystem(probe)

Please sign in to view this quote.

Due to Smalltalk line entries, not use # in CALYPSO or PCM - it WILL break something at some point. IE there is a workaround method of "display(#closeDisplay)" that the "#" effectively creates a new line and "closeDisplay" - well - closes the display.

  • Like! 3
Link to comment
Share on other sites

 Share

×
×
  • Create New...