Joint between Rod and RigidBody
See original GitHub issueDescribe the bug According to the documentation, a numerous number of joints (and particularly the FixedJoint) should have compatibility for connecting a CosseratRod and a RigidBody (for example a Cylinder). However in practice, there are some bugs when trying to use this feature:
Error message for call simulator.connect(rigid_body, rod, first_connect_idx=0, second_connect_idx=-1)
:
File "/Users/maximilianstoelzle/opt/miniconda3/envs/hsa-control/lib/python3.10/site-packages/elastica/wrappers/connections.py", line 99, in _call_connections
connection.apply_torques(
File "/Users/maximilianstoelzle/opt/miniconda3/envs/hsa-control/lib/python3.10/site-packages/elastica/joint.py", line 250, in apply_torques
+ rod_two.rest_lengths[index_two] * rod_one.tangents[..., index_one]
AttributeError: 'Cylinder' object has no attribute 'tangents'
Error message for call simulator.connect(rod, rigid_body, first_connect_idx=0, second_connect_idx=0)
:
File "/Users/maximilianstoelzle/opt/miniconda3/envs/hsa-control/lib/python3.10/site-packages/elastica/wrappers/connections.py", line 99, in _call_connections
connection.apply_torques(
File "/Users/maximilianstoelzle/opt/miniconda3/envs/hsa-control/lib/python3.10/site-packages/elastica/joint.py", line 250, in apply_torques
+ rod_two.rest_lengths[index_two] * rod_one.tangents[..., index_one]
AttributeError: 'Cylinder' object has no attribute 'rest_lengths'
Error message for call simulator.connect(rod, rigid_body, first_connect_idx=-1, second_connect_idx=0)
:
File "/Users/maximilianstoelzle/opt/miniconda3/envs/hsa-control/lib/python3.10/site-packages/elastica/wrappers/connections.py", line 99, in _call_connections
connection.apply_torques(
File "/Users/maximilianstoelzle/opt/miniconda3/envs/hsa-control/lib/python3.10/site-packages/elastica/joint.py", line 239, in apply_torques
rod_two.position_collection[..., index_two + 1]
IndexError: index 1 is out of bounds for axis 1 with size 1
To Reproduce
from elastica.joint import FixedJoint
from elastica.rod.cosserat_rod import CosseratRod
from elastica.rigidbody import Cylinder
rod = CosseratRod.straight_rod(
n_elements=50, # number of elements
start=rod_base_position, # Starting position of first node in rod
direction=np.array([0.0, 1.0, 0.0]), # Direction the rod extends
normal=np.array([0.0, 0.0, 1.0]), # normal vector of rod
base_length=1., # original length of rod (m)
base_radius=0.05, # original radius of rod (m)
density=1e3, # density of rod (kg/m^3)
nu=1e-3, # Energy dissipation of rod
youngs_modulus=youngs_modulus,
shear_modulus=shear_modulus,
)
rigid_body = Cylinder(start=np.array[0., 0., 1.),
normal=np.array([0., 0., 1.]),
direction=np.array([1., 0., 0.]),
base_length=platform_thickness,
base_radius=platform_radius,
density=1., # TODO: replace with actual density of platform
)
simulator.connect(rigid_body, rod, first_connect_idx=0, second_connect_idx=-1).using(
FixedJoint,
k=1e8, kt=1e6, nu=1,
)
Environment
- Python=3.10.5, pip=22.1.2
- Numpy/numba version: 22.1.2
- PyElastica version: 0.2.3
- OS, Device: macOS / macBook Pro 15’’ 2019
Expected behavior
I expect the be able to connect a RigidBody and a CosseratRod via a (Fixed)Joint, no matter which is referenced as rod_1
or rod_2
in the connect
method.
Screenshots If applicable, add screenshots to help explain your problem.
Additional context Add any other context about the problem here.
Issue Analytics
- State:
- Created a year ago
- Comments:7 (6 by maintainers)
Hi @mstoelzle
Thanks for reporting the bug. Fixed joint can only connect two rods, not rigid body and a rod. So documentation was misleading and I will correct that.
However, you can still write your joint class to connect rigid body and rod. The Joint class you need to write is similar to the fixed joint. First you need to compute the tip position of rigid body to find the connection point of rigid-body and rod. Second you need to write a torque spring to fix relative orientation of rigid body and rod.
Here are some hints for you to get starting:
rod_one
iscylinder
, you also need to correct this line instead ofrod_one.tangents[..., index_one]
you need to writerod_one.director_collection[2, :, 0]
Also after implementing joint class, you are welcome to do a PR and contribute to the PyElastica . Let me know if you have any other questions.
I will close this issue for now as #149 is merged now into the v0.3.0 branch.