Skip to content

Commit 7279d6f

Browse files
committed
[PyKDL] add vector version of JntToCart for fk pos and vel
1 parent ec5d67e commit 7279d6f

File tree

2 files changed

+63
-6
lines changed

2 files changed

+63
-6
lines changed

python_orocos_kdl/PyKDL/kinfam.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,19 @@ void init_kinfam(pybind11::module &m)
335335
py::class_<ChainFkSolverPos, SolverI> chain_fk_solver_pos(m, "ChainFkSolverPos");
336336
chain_fk_solver_pos.def("JntToCart", (int (ChainFkSolverPos::*)(const JntArray&, Frame&, int)) &ChainFkSolverPos::JntToCart,
337337
py::arg("q_in"), py::arg("p_out"), py::arg("segmentNr")=-1);
338-
// Argument by reference doesn't work for container types
339-
// chain_fk_solver_pos.def("JntToCart", (int (ChainFkSolverPos::*)(const JntArray&, std::vector<Frame>&, int)) &ChainFkSolverPos::JntToCart,
340-
// py::arg("q_in"), py::arg("p_out"), py::arg("segmentNr")=-1);
338+
chain_fk_solver_pos.def("JntToCart", [](ChainFkSolverPos& self, const JntArray& q_in, py::list& p_out, int segmentNr)
339+
{
340+
std::vector<Frame> temp;
341+
temp.resize(p_out.size());
342+
int result = self.JntToCart(q_in, temp, segmentNr);
343+
p_out.clear();
344+
for (const Frame& f : temp)
345+
{
346+
p_out.append(f);
347+
}
348+
return result;
349+
},
350+
py::arg("q_in"), py::arg("p_out"), py::arg("segmentNr")=-1);
341351

342352

343353
// --------------------
@@ -346,9 +356,19 @@ void init_kinfam(pybind11::module &m)
346356
py::class_<ChainFkSolverVel, SolverI> chain_fk_solver_vel(m, "ChainFkSolverVel");
347357
chain_fk_solver_vel.def("JntToCart", (int (ChainFkSolverVel::*)(const JntArrayVel&, FrameVel&, int)) &ChainFkSolverVel::JntToCart,
348358
py::arg("q_in"), py::arg("p_out"), py::arg("segmentNr")=-1);
349-
// Argument by reference doesn't work for container types
350-
// chain_fk_solver_vel.def("JntToCart", (int (ChainFkSolverVel::*)(const JntArrayVel&, std::vector<FrameVel>&, int)) &ChainFkSolverVel::JntToCart,
351-
// py::arg("q_in"), py::arg("p_out"), py::arg("segmentNr")=-1);
359+
chain_fk_solver_vel.def("JntToCart", [](ChainFkSolverVel& self, const JntArrayVel& q_in, py::list& p_out, int segmentNr)
360+
{
361+
std::vector<FrameVel> temp;
362+
temp.resize(p_out.size());
363+
int result = self.JntToCart(q_in, temp, segmentNr);
364+
p_out.clear();
365+
for (const FrameVel& f : temp)
366+
{
367+
p_out.append(f);
368+
}
369+
return result;
370+
},
371+
py::arg("q_in"), py::arg("p_out"), py::arg("segmentNr")=-1);
352372

353373

354374
// ------------------------------

python_orocos_kdl/tests/kinfamtest.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,41 @@ def testFkPosAndIkPosGivens(self):
257257
epsJ = 1e-3
258258
self.testFkPosAndIkPosImpl(self.fksolverpos, self.iksolverpos_givens, epsJ)
259259

260+
def testFkPosVect(self):
261+
epsC = 1e-5
262+
263+
q = JntArray(self.chain.getNrOfJoints())
264+
265+
for i in range(q.rows()):
266+
q[i] = random.uniform(-0.99, 0.99)
267+
268+
v_out: list[Frame | None] = [None] * self.chain.getNrOfSegments() # Cheaper than Frames
269+
f_out = Frame()
270+
self.assertEqual(self.fksolverpos.JntToCart(q, f_out), 0)
271+
self.assertEqual(self.fksolverpos.JntToCart(q, v_out), 0)
272+
273+
self.assertEqual(len(v_out), self.chain.getNrOfSegments())
274+
self.assertTrue(Equal(v_out[self.chain.getNrOfSegments() - 1], f_out, epsC))
275+
276+
def testFkVelVect(self):
277+
epsC = 1e-5
278+
279+
q = JntArray(self.chain.getNrOfJoints())
280+
qdot = JntArray(self.chain.getNrOfJoints())
281+
282+
for i in range(q.rows()):
283+
q[i] = random.uniform(-0.99, 0.99)
284+
qdot[i] = random.uniform(-0.99, 0.99)
285+
286+
v_out: list[FrameVel | None] = [None] * self.chain.getNrOfSegments() # Cheaper than FrameVels
287+
f_out = FrameVel()
288+
q_vel = JntArrayVel(q, qdot)
289+
self.assertEqual(self.fksolvervel.JntToCart(q_vel, f_out), 0)
290+
self.assertEqual(self.fksolvervel.JntToCart(q_vel, v_out), 0)
291+
292+
self.assertEqual(len(v_out), self.chain.getNrOfSegments())
293+
self.assertTrue(Equal(v_out[self.chain.getNrOfSegments() - 1], f_out, epsC))
294+
260295
def compare_Jdot_Diff_vs_Solver(self, dt, representation):
261296
NrOfJoints = self.chain.getNrOfJoints()
262297
q = JntArray(NrOfJoints)
@@ -357,6 +392,8 @@ def suite():
357392
suite.addTest(KinfamTestFunctions('testFkVelAndIkVelGivens'))
358393
suite.addTest(KinfamTestFunctions('testFkPosAndIkPos'))
359394
suite.addTest(KinfamTestFunctions('testFkPosAndIkPosGivens'))
395+
suite.addTest(KinfamTestFunctions('testFkPosVect'))
396+
suite.addTest(KinfamTestFunctions('testFkVelVect'))
360397
suite.addTest(KinfamTestFunctions('testJacDot'))
361398
suite.addTest(KinfamTestTree('testTreeGetChainMemLeak'))
362399
return suite

0 commit comments

Comments
 (0)