-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathRobotState.lua
More file actions
355 lines (319 loc) · 11.8 KB
/
RobotState.lua
File metadata and controls
355 lines (319 loc) · 11.8 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
--- LUA wrapper for moveit robot state environment
-- dependency to tourch.ros
-- @classmod RobotState
local ffi = require 'ffi'
local torch = require 'torch'
local ros = require 'ros'
local moveit = require 'moveit.env'
local utils = require 'moveit.utils'
local std = ros.std
local tf = ros.tf
local RobotState = torch.class('moveit.RobotState', moveit)
local f
function init()
local RobotState_method_names = {
"createEmpty",
"createFromModel",
"clone",
"delete",
"release",
"getVariableCount",
"getVariableNames",
"getVariablePositions",
"hasVelocities",
"getVariableVelocities",
"hasAccelerations",
"getVariableAccelerations",
"hasEffort",
"getVariableEffort",
"setToDefaultValues",
"setToRandomPositions",
"setFromIK",
"getGlobalLinkTransform",
"setVariablePositions",
"setVariablePositions_",
"setVariableVelocities",
"setVariableVelocities_",
"setVariableAccelerations",
"setVariableAccelerations_",
"setVariableEffort",
"setVariableEffort_",
"updateLinkTransforms",
"update",
"toRobotStateMsg",
"fromRobotStateMsg",
"getJointTransform",
"getJacobian",
"enforceBounds",
"distance",
"satisfiesBounds",
"copyJointGroupPositions"
}
f = utils.create_method_table('moveit_RobotState_', RobotState_method_names)
end
init()
function RobotState.createEmpty()
local c = torch.factory('moveit.RobotState')()
rawset(c, 'o', f.createEmpty())
return c
end
function RobotState.createFromModel(kinematic_model)
if ffi.typeof(kinematic_model:cdata()) ~= ffi.typeof('RobotModelPtr*') then
error('RobotState object can only be initialized with existing RobotModel pointer.')
end
local c = torch.factory('moveit.RobotState')()
rawset(c, 'o', f.createFromModel(kinematic_model:cdata()))
return c
end
function RobotState:__init(o)
if type(o) ~= 'cdata' or ffi.typeof(o) ~= ffi.typeof('RobotStatePtr*') then
error('RobotState object can only be initialized with existing RobotState pointer.')
end
self.o = o
ffi.gc(o, f.delete)
self.moveit_msgs_RobotStateSpec = ros.MsgSpec('moveit_msgs/RobotState')
end
function RobotState:cdata()
return self.o
end
function RobotState:clone()
local c = torch.factory('moveit.RobotState')()
rawset(c, 'o', f.clone(self.o))
return c
end
---Get the number of variables that make up this state.
--@treturn int
function RobotState:getVariableCount()
return f.getVariableCount(self.o)
end
---Get the names of the variables that make up this state, in the order they are stored in memory.
--@tparam[opt] moveit.Strings names
--@treturn moveit.Strings
function RobotState:getVariableNames(names)
names = names or std.StringVector()
f.getVariableNames(self.o, names:cdata())
return names
end
---Get a raw pointer to the positions of the variables stored in this state. Use carefully.
--If you change these values externally you need to make sure you trigger a forced update for the state by calling update(true).
--@treturn torch.DoubleTensor
function RobotState:getVariablePositions()
local t = torch.DoubleTensor()
f.getVariablePositions(self.o, t:cdata())
return t
end
---By default, if velocities are never set or initialized, the state remembers that there are no velocities set.
--This is useful to know when serializing or copying the state.
--@treturn boolean
function RobotState:hasVelocities()
return f.hasVelocities(self.o)
end
---Get const access to the velocities of the variables that make up this state.
--The values are in the same order as reported by getVariableNames.
--@see getVariableNames
--@treturn torch.DoubleTensor
function RobotState:getVariableVelocities()
local t = torch.DoubleTensor()
f.getVariableVelocities(self.o, t:cdata())
return t
end
---Check if accelerations are provided.
--By default, if accelerations are never set or initialized, the state remembers that there are no accelerations set.
--This is useful to know when serializing or copying the state. If hasAccelerations() reports true, hasEffort() will certainly report false.
--@treturn boolean
function RobotState:hasAccelerations()
return f.hasAccelerations(self.o)
end
---Get raw access to the accelerations of the variables that make up this state.
--The values are in the same order as reported by getVariableNames().
--The area of memory overlaps with effort (effort and acceleration should not be set at the same time)
--@treturn torch.DoubleTensor
--@see getVariableNames
function RobotState:getVariableAccelerations()
local t = torch.DoubleTensor()
f.getVariableAccelerations(self.o, t:cdata())
return t
end
---Check if efforts are provided.
--By default, if effort is never set or initialized, the state remembers that there is no effort set.
--This is useful to know when serializing or copying the state. If hasEffort() reports true, hasAccelerations() will certainly report false.
--@treturn boolean
function RobotState:hasEffort()
return f.hasEffort(self.o)
end
---Get raw access to the effort of the variables that make up this state.
--The values are in the same order as reported by getVariableNames().
--@treturn torch.DoubleTensor
--@see getVariableNames
function RobotState:getVariableEffort()
local t = torch.DoubleTensor()
f.getVariableEffort(self.o, t:cdata())
return t
end
---Set all joints to their default positions.
--The default position is 0, or if that is not within bounds then half way between min and max bound.
function RobotState:setToDefaultValues()
f.setToDefaultValues(self.o)
end
---Set all joints to random values.
--Values will be within default bounds.
function RobotState:setToRandomPositions()
f.setToRandomPositions(self.o)
end
---If the group this state corresponds to is a chain and a solver is available, then the joint values can be set by computing inverse kinematics.
--The pose is assumed to be in the reference frame of the kinematic model.
--Returns true on success.
--@tparam string group_id
--@tparam tf.Transform pose
--@tparam[opt=10] int attempts
--@tparam[opt=0.1] number timeout
--@tparam[opt=''] string tip_link
--@treturn boolean
function RobotState:setFromIK(group_id, pose, attempts, timeout, return_approximate_solution, tip_link)
attempts = attempts or 10
timeout = timeout or 0.1
tip_link = tip_link or ''
return_approximate_solution = return_approximate_solution or false
if torch.isTensor(pose) then
pose = tf.Transform():fromTensor(pose)
end
local result_joint_positions = torch.DoubleTensor()
local found_ik =
f.setFromIK(
self.o,
group_id,
pose:cdata(),
tip_link,
attempts,
timeout,
return_approximate_solution,
result_joint_positions:cdata()
)
return found_ik, result_joint_positions
end
---Do forward Kinematic
--@tparam tf.Transform pose
--@tparam string link name
function RobotState:getGlobalLinkTransform(link_name, pose)
pose = pose or tf.Transform()
local success = f.getGlobalLinkTransform(self.o, pose:cdata(), link_name)
return success and pose or nil
end
---It is assumed positions is an array containing the new positions for all variables in this state. Those values are copied into the state.
--
function RobotState:setVariablePositions(group_variable_values, group_variable_names)
if group_variable_names then
if torch.type(group_variable_names) == 'table' then
group_variable_names = std.StringVector(group_variable_names)
end
if torch.type(group_variable_names) == 'std.StringVector' then
return f.setVariablePositions_(self.o, group_variable_values:cdata(), group_variable_names:cdata())
else
ros.ERROR('[RobotState:setVariablePositions] Could not set Positions ini robot state')
end
else
return f.setVariablePositions(self.o, group_variable_values:cdata())
end
end
---It is assumed positions is an array containing the new velocities for all variables in this state. Those values are copied into the state.
--
function RobotState:setVariableVelocities(group_variable_values, group_variable_names)
if group_variable_names then
if torch.type(group_variable_names) == 'table' then
group_variable_names = std.StringVector(group_variable_names)
end
if torch.type(group_variable_names) == 'std.StringVector' then
return f.setVariableVelocities_(self.o, group_variable_values:cdata(), group_variable_names:cdata())
else
ros.ERROR('[RobotState:setVariableVelocities] Could not set Positions ini robot state')
end
else
return f.setVariableVelocities(self.o, group_variable_values:cdata())
end
end
---It is assumed positions is an array containing the new accelerations for all variables in this state. Those values are copied into the state.
--
function RobotState:setVariableAccelerations(group_variable_values, group_variable_names)
if group_variable_names then
if torch.type(group_variable_names) == 'table' then
group_variable_names = std.StringVector(group_variable_names)
end
if torch.type(group_variable_names) == 'std.StringVector' then
return f.setVariableAccelerations_(self.o, group_variable_values:cdata(), group_variable_names:cdata())
else
ros.ERROR('[RobotState:setVariableVelocities] Could not set Positions ini robot state')
end
else
return f.setVariableAccelerations(self.o, group_variable_values:cdata())
end
end
---It is assumed positions is an array containing the new effort for all variables in this state. Those values are copied into the state.
--
function RobotState:setVariableEffort(group_variable_values)
return f.setVariableEffort(self.o, group_variable_values:cdata())
end
---Update the reference frame transforms for links. This call is needed before using the transforms of links for coordinate transforms.
--
function RobotState:updateLinkTransforms()
f.updateLinkTransforms(self.o)
end
---Update all transforms.
--
function RobotState:update()
f.update(self.o)
end
---Convert Robotstate to Message format
--@tparam boolean copy_attached_bodies
function RobotState:toRobotStateMsg(copy_attached_bodies)
copy_attached_bodies = copy_attached_bodies or false
local msg_bytes = torch.ByteStorage()
f.toRobotStateMsg(self.o, msg_bytes:cdata(), copy_attached_bodies)
local msg = ros.Message(self.moveit_msgs_RobotStateSpec or ros.MsgSpec('moveit_msgs/RobotState'), true)
msg:deserialize(msg_bytes)
return msg
end
---Convert Message format to Robotstate
--@tparam Robotstate_msg msg
function RobotState:fromRobotStateMsg(msg)
if torch.isTypeOf(msg, ros.Message) then
local msg_bytes = msg:serialize()
msg_bytes:shrinkToFit()
f.fromRobotStateMsg(self.o, msg_bytes.storage:cdata())
return true
end
return false
end
---Determines joint transformation from joint name
--@tparam string joint_name
function RobotState:getJointTransform(joint_name)
assert(joint_name and type(joint_name) == 'string' and #joint_name >= 0, 'Invalid joint_name specified.')
local result = torch.DoubleTensor()
f.getJointTransform(self.o, joint_name, result:cdata())
return result
end
---Determines Jacobian for move group name
--@tparam string group_name
function RobotState:getJacobian(group_name)
assert(group_name and type(group_name) == 'string' and #group_name >= 0, 'Invalid group_name specified.')
local result = torch.DoubleTensor()
f.getJacobian(self.o, group_name, result:cdata())
return result
end
function RobotState:enforceBounds()
f.enforceBounds(self.o)
end
function RobotState:distance(other)
if torch.isTypeOf(other, moveit.RobotState) then
return f.distance(self.o, other:cdata())
end
end
function RobotState:satisfiesBounds(margin)
local margin = margin or 0.0
return f.satisfiesBounds(self.o, margin)
end
function RobotState:copyJointGroupPositions(group_name)
assert(group_name and type(group_name) == 'string' and #group_name >= 0, 'Invalid group_name specified.')
local t = torch.DoubleTensor()
f.copyJointGroupPositions(self.o, group_name, t:cdata())
return t
end