TypeError ChForce.SetAlign(), PyChrono

75 views
Skip to first unread message

Dash

unread,
Dec 11, 2023, 7:52:57 PM12/11/23
to ProjectChrono
Dear Chrono Community,
I have created two bodies and I added a ChForce to the second body. I would like the force to align with the coordinate system of the first body. I am using the .SetAlign function but I get a type error. I saw online that .SetAlign takes an alignment frame, I have tried giving it a marker but it doesn't work.

TypeError: in method 'ChForce_SetAlign', argument 2 of type 'chrono::ChForce::AlignmentFrame'

Here is a snippet that is causing the problem:

        self.spring_force_2 = chrono.ChForce()
        self.spring_force_2.SetMode(chrono.ChForce.FORCE)
        self.body_2.AddForce(self.spring_force_2)
        self.spring_force_2.SetVpoint(self.marker_2.GetPos())
        self.spring_force_2.SetAlign(chrono.ChFrameD(self.marker_1))

Thanks in advance to anyone who can point me in the right direction!

Dario Mangoni

unread,
Dec 20, 2023, 8:21:25 AM12/20/23
to ProjectChrono
Hi,
as you mentioned the SetAlign accepts an AlignmentFrame type.

In C++ it would have been quite easier to spot that his definition is encapsulated in ChForce itself, so it should have been :
spring_force_2->SetAlign(chrono::ChForce::AlignmentFrame::BODY_DIR);

However, the wrapping just discarded the "AlignmentFrame" enum type, thus flattening the enum options directly inside ChForce. In short, it became:
spring_force_2.SetAlign(chrono.ChForce.BODY_DIR)

However, as you can see, SetAlign does not allow a generic frame to be used nor a marker (that would have been the proper choice), but it offers only two options: BODY_DIR or WORLD_DIR.
This means that unfortunately you cannot tell a ChForce applied to Body2 to follow Body1 with SetAlign.

Currently there is not a smooth way to use ChForce to achieve what you desire. It is probably easier to go directly to a ChLoadBodyBody.

Apart from that: I see that you named the variable spring_force... if you just need a spring I would recommend you to use ChLinkTSDA isntead!

Dario


Dash

unread,
Dec 20, 2023, 12:35:51 PM12/20/23
to ProjectChrono
Hi Dario,
Thank you for your response. That is unfortunate that is not possible to currently achieve this within chrono. But, I have developed a work around that generates and applies the matrix transformations to calculate the forces acting on body 2.

I am modeling springs (and pistons) that are fixed to a body on one end and are mounted on spherical bearings to a second body. So the spring will have lateral stiffness and lateral forces. I have looked into using TSDAs for my application but to my knowledge they always act along the shortest path between the two points they connect. Please let me know if I am mistaken!

- Dash

Dario Mangoni

unread,
Dec 23, 2023, 9:36:52 AM12/23/23
to ProjectChrono
Hi Dash,
yes, of course you can implement the behaviour manually! The ChForce class is surely something that would benefit a nice refactoring, but the TODO list is always full.

In any case I would still recommend you to use classes derived from ChLoadBodyBody (you then need to put it into a ChLoadContainer to add it to ChSystem): you might find it a little more pedantic, but it's definitely a better solution on the long run.
The ChLoadBodyBody is indeed already equipped with everything you need for a body-pair load (reference to the bodies, local/absolute coordinate switches, etc), plus you will get additional functionalities (generalized loads, etc).
I don't see a ChLoadBodyBodyForce implemented, but it should be easy to implement mirroring ChLoadBodyBodyTorque. You might want to look at the list of classes derived from ChLoadBodyBody to have a full overview.

Regards,
Dario

Dario Mangoni

unread,
Dec 24, 2023, 3:10:29 PM12/24/23
to ProjectChrono
BTW, for future readers, we added a new page about Loads in Chrono. Check it out!
Reply all
Reply to author
Forward
0 new messages