241 lines
7.7 KiB
Tcl
Executable File
241 lines
7.7 KiB
Tcl
Executable File
# check_config.tcl
|
|
# Usage: tclsh path_to_this_file inifilename
|
|
# if a check fails, print message and exit 1
|
|
#
|
|
# checks:
|
|
# 1) mandatory items per ::mandatory_items list
|
|
# 2) if trivkins, check consistency of [JOINT_] and [AXIS_]
|
|
# MIN_LIMIT and MAX_LIMIT
|
|
#----------------------------------------------------------------------
|
|
set ::mandatory_items {KINS KINEMATICS
|
|
KINS JOINTS
|
|
}
|
|
# Ref: src/emc/nml_intf/emccfg.h,src/emc/ini/inijoint.cc,src/emc/iniaxis.cc:
|
|
set ::DEFAULT_AXIS_MAX_VELOCITY 1.0
|
|
set ::DEFAULT_AXIS_MAX_ACCELERATION 1.0
|
|
set ::DEFAULT_JOINT_MAX_VELOCITY 1.0
|
|
set ::DEFAULT_JOINT_MAX_ACCELERATION 1.0
|
|
|
|
# Ref: src/emc/ini/iniaxis.cc:
|
|
set ::DEFAULT_AXIS_MIN_LIMIT -1e99
|
|
set ::DEFAULT_AXIS_MAX_LIMIT +1e99
|
|
#----------------------------------------------------------------------
|
|
proc warnings msg {
|
|
puts -nonewline "\n$::progname:\n"
|
|
catch {puts ($::kins(module) kinematics) WARNING:"}
|
|
foreach m $msg {puts " $m"}
|
|
puts ""
|
|
} ;# warnings
|
|
|
|
proc err_exit msg {
|
|
puts -nonewline "\n$::progname:\n"
|
|
catch {puts ($::kins(module) kinematics) ERROR:"}
|
|
foreach m $msg {puts " $m"}
|
|
puts ""
|
|
exit 1
|
|
} ;# err_exit
|
|
|
|
proc check_mandatory_items {} {
|
|
foreach {section item} $::mandatory_items {
|
|
if  ] {
|
|
set section [string trim $section :]
|
|
lappend emsg "Missing \[$section\]$item="
|
|
}
|
|
}
|
|
if [info exists emsg] {
|
|
err_exit $emsg
|
|
}
|
|
} ;# check_mandatory_items
|
|
|
|
proc uniq {list_name} { ;# make list unique
|
|
foreach item $list_name { set tmp($item) "" }
|
|
return [array names tmp]
|
|
} ;# uniq
|
|
|
|
proc joints_for_trivkins {coords} {
|
|
# ref: src/emc/kinematics/trivkins.c
|
|
# order of coord letters determines assigned joint number
|
|
if {"$coords" == ""} {set coords {X Y Z A B C U V W}}
|
|
set i 0
|
|
foreach a [string toupper $coords] {
|
|
# assign to consecutive joints:
|
|
lappend ::kins(jointidx,$a) $i
|
|
incr i
|
|
}
|
|
} ;# joints_for_trivkins
|
|
|
|
proc consistent_coords_for_trivkins {trivcoords} {
|
|
set m {" " "" "\t" ""} ;# mapping to remove whitespace
|
|
set trivcoords [string map $m $trivcoords]
|
|
if {"$trivcoords" == "XYZABCUVW"} {
|
|
return ;# unspecified trivkins coordinates
|
|
# allows use of any coordinates
|
|
}
|
|
set trajcoords ""
|
|
if [info exists ::TRAJ(COORDINATES)] {
|
|
set trajcoords [string map $m [lindex $::TRAJ(COORDINATES) 0]]
|
|
}
|
|
if {[string toupper "$trivcoords"] != [string toupper "$trajcoords"]} {
|
|
lappend ::wmsg "INCONSISTENT coordinates specifications:
|
|
trivkins coordinates=$trivcoords
|
|
\[TRAJ\]COORDINATES=$trajcoords"
|
|
}
|
|
} ;# consistent_coords_for_trivkins
|
|
|
|
proc validate_identity_kins_limits {} {
|
|
set emsg ""
|
|
for {set j 0} {$j < $::KINS(JOINTS)} {incr j} {
|
|
if {] } {
|
|
lappend ::wmsg "Unspecified \[JOINT_$j\]MAX_VELOCITY, default used: $::DEFAULT_JOINT_MAX_VELOCITY"
|
|
}
|
|
if {] } {
|
|
lappend ::wmsg "Unspecified \[JOINT_$j\]MAX_ACCELERATION, default used: $::DEFAULT_JOINT_MAX_ACCELERATION"
|
|
}
|
|
}
|
|
foreach c [uniq $::kins(coordinates)] {
|
|
# array test avoids superfluous messages when coordinates= not specified
|
|
if [array exists ::AXIS_[set c]] {
|
|
if {] } {
|
|
lappend ::wmsg "Unspecified \[AXIS_$c\]MAX_VELOCITY, default used: $::DEFAULT_AXIS_MAX_VELOCITY"
|
|
}
|
|
if {] } {
|
|
lappend ::wmsg "Unspecified \[AXIS_$c\]MAX_ACCELERATION, default used: $::DEFAULT_AXIS_MAX_ACCELERATION"
|
|
}
|
|
}
|
|
|
|
set missing_axis_min_limit 0
|
|
set missing_axis_max_limit 0
|
|
if ] {
|
|
set ::AXIS_[set c](MIN_LIMIT) $::DEFAULT_AXIS_MIN_LIMIT
|
|
set missing_axis_min_limit 1
|
|
}
|
|
if ] {
|
|
set ::AXIS_[set c](MAX_LIMIT) $::DEFAULT_AXIS_MAX_LIMIT
|
|
set missing_axis_max_limit 1
|
|
}
|
|
foreach j $::kins(jointidx,$c) {
|
|
if [info exists ::JOINT_[set j](MIN_LIMIT)] {
|
|
set jlim [set ::JOINT_[set j](MIN_LIMIT)]
|
|
set clim [set ::AXIS_[set c](MIN_LIMIT)]
|
|
if {$jlim > $clim} {
|
|
if $missing_axis_min_limit {
|
|
lappend ::wmsg "Unspecified \[AXIS_$c\]MIN_LIMIT, default used: $::DEFAULT_AXIS_MIN_LIMIT"
|
|
}
|
|
lappend emsg "\[JOINT_$j\]MIN_LIMIT > \[AXIS_$c\]MIN_LIMIT ($jlim > $clim)"
|
|
}
|
|
}
|
|
if [info exists ::JOINT_[set j](MAX_LIMIT)] {
|
|
set jlim [set ::JOINT_[set j](MAX_LIMIT)]
|
|
set clim [set ::AXIS_[set c](MAX_LIMIT)]
|
|
if {$jlim < $clim} {
|
|
if $missing_axis_max_limit {
|
|
lappend ::wmsg "Unspecified \[AXIS_$c\]MAX_LIMIT, default used: $::DEFAULT_AXIS_MAX_LIMIT"
|
|
}
|
|
lappend emsg "\[JOINT_$j\]MAX_LIMIT < \[AXIS_$c\]MAX_LIMIT ($jlim < $clim)"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $emsg
|
|
} ;# validate_identity_kins_limits
|
|
|
|
proc check_extrajoints {} {
|
|
if ![info exists ::EMCMOT(EMCMOT)] return
|
|
if {[string first motmod $::EMCMOT(EMCMOT)] <= 0} return
|
|
set mot [split [lindex $::EMCMOT(EMCMOT) 0]]
|
|
foreach item $mot {
|
|
set pair [split $item =]
|
|
set parm [lindex $pair 0]
|
|
set val [lindex $pair 1]
|
|
if {"$parm" == "num_extrajoints"} {
|
|
set ::num_extrajoints $val
|
|
}
|
|
}
|
|
if [info exists ::num_extrajoints] {
|
|
lappend ::wmsg [format "Extra joints specified=%d\n \
|
|
\[KINS\]JOINTS=%d must accommodate kinematic joints *plus* extra joints " \
|
|
$::num_extrajoints $::KINS(JOINTS)]
|
|
}
|
|
} ;#check_extrajoints
|
|
|
|
proc warn_for_multiple_ini_values {} {
|
|
set sections [info globals]
|
|
set sections_to_check {JOINT_ AXIS_}
|
|
|
|
foreach section $sections {
|
|
set enforce 0
|
|
foreach csection $sections_to_check {
|
|
if {[string first $csection $section"] >= 0} {
|
|
set enforce 1
|
|
break
|
|
}
|
|
}
|
|
if !$enforce continue
|
|
foreach name [array names ::$section] {
|
|
set gsection ::$section
|
|
set val [set [set gsection]($name)]
|
|
set len [llength $val]
|
|
if {$len > 1} {
|
|
lappend ::wmsg "Unexpected multiple values \[$section\]$name: $val"
|
|
}
|
|
}
|
|
}
|
|
} ;# warn_for_multiple_ini_values
|
|
|
|
#----------------------------------------------------------------------
|
|
# begin
|
|
package require Linuxcnc ;# parse_ini
|
|
|
|
set ::progname [file rootname [file tail [info script]]]
|
|
set inifile [lindex $::argv 0]
|
|
if ![file exists $inifile] {
|
|
err_exit [list "No such file <$inifile>"]
|
|
}
|
|
if ![file readable $inifile] {
|
|
err_exit [list "File not readable <$inifile>"]
|
|
}
|
|
parse_ini $inifile
|
|
|
|
check_mandatory_items
|
|
|
|
set kins_kinematics [lindex $::KINS(KINEMATICS) end]
|
|
set ::kins(module) [lindex $kins_kinematics 0]
|
|
|
|
# parameters specified as parm=value --> ::kins(parm)=value
|
|
foreach item $kins_kinematics {
|
|
if {[string first = $item] >= 0} {
|
|
set l [split $item =]
|
|
set ::kins([lindex $l 0]) [lindex $l 1]
|
|
} else {
|
|
if {"$item" != $::kins(module)} {
|
|
puts "Unknown \[KINS\]KINEMATICS item: <$item>"
|
|
}
|
|
}
|
|
}
|
|
# coordinates --> ::kins(coordinates) (all if not specified)
|
|
if [info exists ::kins(coordinates)] {
|
|
set ::kins(coordinates) [split $::kins(coordinates) ""]
|
|
set ::kins(coordinates) [string toupper $::kins(coordinates)]
|
|
} else {
|
|
set ::kins(coordinates) {X Y Z A B C U V W}
|
|
}
|
|
|
|
# list of joints for each coord --> ::kins(jointidx,coordinateletter)
|
|
switch $::kins(module) {
|
|
trivkins {joints_for_trivkins $::kins(coordinates)}
|
|
default {
|
|
puts "$::progname: Unchecked: \[KINS\]KINEMATICS=$::KINS(KINEMATICS)"
|
|
exit 0
|
|
}
|
|
}
|
|
check_extrajoints
|
|
|
|
warn_for_multiple_ini_values
|
|
#parray ::kins
|
|
set emsg [validate_identity_kins_limits]
|
|
consistent_coords_for_trivkins $::kins(coordinates)
|
|
if [info exists ::wmsg] {warnings $::wmsg}
|
|
|
|
if {"$emsg" == ""} {exit 0}
|
|
err_exit $emsg
|