(testmodels-kinematictreeprismaticjacobiantest)= # kinematicTreePrismaticJacobianTest.py You can view and download this file on Github: [kinematicTreePrismaticJacobianTest.py](https://github.com/jgerstmayr/EXUDYN/tree/master/python/TestModels/kinematicTreePrismaticJacobianTest.py) ```{code-block} python :linenos: #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # This is an EXUDYN example # # Details: The position Jacobian of a prismatic joint of ObjectKinematicTree in a rotated joint frame, # tested through a force on a MarkerKinematicTreeRigid (#2740). A prismatic link is rotated # either by a revolute parent link or by its joint transformation; a force of 1 N along # the prismatic axis accelerates a mass of 2 kg by 0.5 m/s^2, so q1 = 0.25 after 1 s in # every case - as long as the Jacobian column is the global axis. # # Author: Johannes Gerstmayr # Date: 2026-09-29 # # Copyright:This file is part of Exudyn. Exudyn is free software. You can redistribute it and/or modify it under the terms of the Exudyn license. See 'LICENSE.txt' for more details. # #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ import exudyn as exu from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities import numpy as np testIsActive = exu.sys.get('testIsActive', False) SC = exu.SystemContainer() mbs = SC.AddSystem() mass = 2 #mass of the prismatic link force = 1 #force along the prismatic axis testResult = 0 #(angle of the revolute parent link, rotation of the prismatic joint frame about z) cases = [(0, 0), (0.25*np.pi, 0), (0.5*np.pi, 0), (0, 0.5*np.pi), (0.5*np.pi, 0.25*np.pi)] for (q0, alpha) in cases: mbs.Reset() nGeneric = mbs.AddNode(NodeGenericODE2(referenceCoordinates=[0.,0.], initialCoordinates=[q0,0.], initialCoordinates_t=[0.,0.], numberOfODE2Coordinates=2)) #link 0: revolute about z, held by a huge inertia; link 1: prismatic along the x-axis of its joint frame oKT = mbs.AddObject(ObjectKinematicTree(nodeNumber=nGeneric, jointTypes=[exu.JointType.RevoluteZ, exu.JointType.PrismaticX], linkParents=[-1, 0], jointTransformations=exu.Matrix3DList([np.eye(3), RotationMatrixZ(alpha)]), jointOffsets=exu.Vector3DList([[0,0,0], [0,0,0]]), linkInertiasCOM=exu.Matrix3DList([1e8*np.eye(3), np.eye(3)]), linkCOMs=exu.Vector3DList([[0,0,0], [0,0,0]]), linkMasses=[1e8, mass])) mLink1 = mbs.AddMarker(MarkerKinematicTreeRigid(objectNumber=oKT, linkNumber=1, localPosition=[0,0,0])) #the prismatic axis in the global frame; its line passes through the revolute axis, so no torque on link 0 axis = RotationMatrixZ(q0 + alpha) @ np.array([1,0,0]) mbs.AddLoad(LoadForceVector(markerNumber=mLink1, loadVector=force*axis)) mbs.Assemble() simulationSettings = exu.SimulationSettings() simulationSettings.timeIntegration.numberOfSteps = 100 simulationSettings.timeIntegration.endTime = 1 simulationSettings.solution.file.write = not testIsActive mbs.SolveDynamic(simulationSettings) q = mbs.GetNodeOutput(nGeneric, exu.OutputVariableType.Coordinates) exu.Print('q0 =', round(q0, 4), ', alpha =', round(alpha, 4), ': q1 =', q[1], '(expected 0.25)') testResult += q[1] #5 cases of 0.25 exu.Print('solution of kinematicTreePrismaticJacobianTest=', testResult) exu.sys['testResult'] = testResult ```