-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathJoint tool.lua
130 lines (117 loc) · 4.45 KB
/
Joint tool.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
sim = require 'sim'
function sysCall_info()
return {autoStart = false, menu = 'Kinematics\nJoint tool'}
end
function sysCall_addOnScriptSuspend()
return {cmd = 'cleanup'}
end
function sysCall_init()
simUI = require 'simUI'
sim.addLog(
sim.verbosity_scriptinfos,
"Select a model, a joint group, or individual joints to use the Joint tool."
)
sel = {}
idToJointMap = {}
jointToIdMap = {}
end
function setJointPos(ui, id, val)
local h = idToJointMap[id]
local p = val * math.pi / 180
sim.setJointPosition(h, p)
sim.announceSceneContentChange()
end
function closeUi()
if not ui then return end
uiPos = table.pack(simUI.getPosition(ui))
simUI.destroy(ui)
ui = nil
end
function closeUi_user()
closeUi()
leaveNow = true
end
function printConfig()
local cfg = {}
for id, jointHandle in pairs(idToJointMap) do
table.insert(cfg, sim.getJointPosition(jointHandle))
end
print(cfg)
end
function sysCall_selChange(inData)
sel = inData.sel
-- get selected joints:
local jointHandles = {}
for i, objectHandle in ipairs(sel) do
local dat = sim.readCustomBufferData(objectHandle, '__jointGroup__')
if dat and #dat > 0 then
for j, jointHandle in ipairs(sim.getReferencedHandles(objectHandle)) do
if sim.getObjectType(jointHandle) == sim.sceneobject_joint then
table.insert(jointHandles, jointHandle)
else
sim.addLog(
sim.verbosity_warnings,
'ignoring object referenced by joint group ' ..
sim.getObjectAlias(objectHandle, 2) .. ': ' ..
sim.getObjectAlias(jointHandle, 2)
)
end
end
elseif sim.getModelProperty(objectHandle) & sim.modelproperty_not_model == 0 then
for j, jointHandle in ipairs(sim.getObjectsInTree(objectHandle, sim.sceneobject_joint)) do
table.insert(jointHandles, jointHandle)
end
elseif sim.getObjectType(objectHandle) == sim.sceneobject_joint then
table.insert(jointHandles, objectHandle)
else
sim.addLog(
sim.verbosity_warnings,
'ignoring selected object: ' .. sim.getObjectAlias(objectHandle, 2)
)
end
end
idToJointMap = {}
jointToIdMap = {}
local nid = 1
closeUi()
for i, jointHandle in ipairs(jointHandles) do
local isSpherical = sim.getJointType(jointHandle) == sim.joint_spherical
local mh, a, b = sim.getJointDependency(jointHandle)
if not isSpherical and mh == -1 and not jointToIdMap[jointHandle] then
jointToIdMap[jointHandle] = nid
idToJointMap[nid] = jointHandle
nid = nid + 1
end
end
if nid == 1 then return end
aliasOption = sim.getNamedInt32Param('jointTool.aliasOption') or 9
local uiPosStr = uiPos and
string.format('placement="absolute" position="%d,%d"', table.unpack(uiPos)) or
'placement="relative" position="280,500" '
xml = '<ui closeable="true" ' .. uiPosStr ..
'resizable="false" on-close="closeUi_user" title="Joint tool" layout="vbox">\n'
xml = xml .. ' <group flat="true" content-margins="0,0,0,0" layout="form">\n'
for id, jointHandle in pairs(idToJointMap) do
local v = sim.getJointPosition(jointHandle) * 180 / math.pi
local cyclic, i = sim.getJointInterval(jointHandle)
local vmin, vmax = i[1] * 180 / math.pi, (i[1] + i[2]) * 180 / math.pi
xml = xml ..
string.format(
' <label text="%s" />\n', sim.getObjectAlias(jointHandle, aliasOption)
)
xml = xml .. string.format(
' <group flat="true" content-margins="0,0,0,0" layout="hbox"><spinbox id="%s" value="%f" minimum="%f" maximum="%f" step="0.5" on-change="setJointPos" /><label text="%.1f~%.1f [deg]" enabled="false" /></group>\n',
id, v, vmin, vmax, vmin, vmax
)
end
xml = xml .. ' </group>\n'
xml = xml .. ' <button text="Print current config" on-click="printConfig" />\n'
xml = xml .. '</ui>'
ui = simUI.create(xml)
end
function sysCall_nonSimulation()
if leaveNow then return {cmd = 'cleanup'} end
end
function sysCall_cleanup()
if ui then simUI.destroy(ui) end
end