Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SegmentCharacteristics class? #245

Closed
yugiero opened this issue Nov 25, 2021 · 19 comments
Closed

SegmentCharacteristics class? #245

yugiero opened this issue Nov 25, 2021 · 19 comments

Comments

@yugiero
Copy link

yugiero commented Nov 25, 2021

Although the "SegmentCharacteristics" class is listed in the documentation, it is missing for me. I want to SET the characteristics of a segment using python by segment.SegmentCharacteristics(mass, inertia, com), not RETURN them, which I can do by segm.characteristics().
Is this method deprecated?

Here is the doc link:
https://pyomeca.github.io/Documentation/biorbd/classbiorbd_1_1rigidbody_1_1SegmentCharacteristics.html

image

@yugiero yugiero changed the title SegmentsCharacteristics class? SegmentCharacteristics class? Nov 25, 2021
@pariterre
Copy link
Member

pariterre commented Nov 25, 2021

Dear @yugiero

This snippet should help :

import biorbd  # or biorbd_casadi if you are interested in casadi backend
import numpy as np

# Load a bioMod file
m = biorbd.Model("path_to_model.bioMod")

# Printing the current center of mass of the first segment
print(m.segment(0).characteristics().CoM().to_array())  

# Change the CoM position to [1, 2, 3]
new_com = np.array([1, 2, 3])
m.segment(0).characteristics().setCoM(new_com)

# Print the new position
print(m.segment(0).characteristics().CoM().to_array())

In the code you pasted, you don't seem to have a model loaded prior, while it is not entirely impossible, I'd strongly suggest to have a bioMod constructed before

Hope this helps!

@yugiero
Copy link
Author

yugiero commented Nov 25, 2021

Thank you, but your answer doesn't explain why the class is missing.
I already have the kinematics available (as spatial transform matrices of all joint frames over time). What I want to do now is set the inertia properties for each of the segments (mass, com, inertia matrix). Even for "characteristics()" there is no set function for the inertia matrix..

@pariterre
Copy link
Member

Hi again!
I see what you mean... This can be a bit tricky. For most of the rigidbody calculation, biorbd relies on RBDL. Therefore some things in the dynamics cannot be changed once the model is constructed. The SegmentCharacteristics is one of them. It appears in the documentation as the automatically generated documentation from the C++ code, and not the Python doc per se. Since one cannot completely change a segment characteristics, it was not interface for Python.

That said, the matrix of intertia (inside a segment characteristics) just like the CoM can be changed. I actually simply forgot to add a set method to modify it. I made a PR #246 to fix this. If you compiled biorbd yourself, this will be shortly available. If you used conda to install, I will make a release shortly and let you know when you can update.

That said, the bioMod file can (and should) be used to define the CoM, inertia matrix and the mass. Unless you want to dynamically change these values (for instance optimizing them), you should define them in the bioMod file and not in the actual code. For example the following line could be copy-pasted in pendulum.bioMod and loaded using biorbd.Model("pendulum.py"):

The following file describe a pendulum that translate and rotate in 2d, with mass 1kg, com -0.0005 0.0688 -0.9542 and an inertia matrix

version 4  // This should always be 4

segment Seg1
    translations	y
    rotations	x
    mass 1
    inertia
        0.0391  0.0000	0.0000
	    0.0000	0.0335	-0.0032
	    0.0000	-0.0032	0.0090
    com  -0.0005 0.0688 -0.9542
endsegment

Does this answer your questions?

@yugiero
Copy link
Author

yugiero commented Nov 26, 2021

Hi,
Thanks a lot! I want to create the segments from my data, merge them to a model and then write it to a file with writeModel for later use. A segment.characteristics().setMass method would also be helpful, because then I can just use the RBDL Segment constructor (if it is available in python for biorbd) and specify the segment characteristics here
image

@pariterre
Copy link
Member

I see!
If you want to create a segment characterics, you can directly call the constructor then :

import biorbd
characteristics = biorbd.SegmentCharacteristics(1, biorbd.Vector3d(1, 2, 3), biorbd.Matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9))

@pariterre
Copy link
Member

it seems that it is what you were asking in the first post... What is your version of biorbd and how did you installed it?
Because the snippet I just posted should work, but I am not sure I see the difference with what you have wrote :S

@yugiero
Copy link
Author

yugiero commented Nov 26, 2021

The snippet doesn't work, unfortunately. I've installed it through conda, following the instructions on the github main page of biorbd. My version is 1.1.2

@pariterre
Copy link
Member

Yep, that is why, biorbd is now on 1.8.2..

@yugiero
Copy link
Author

yugiero commented Nov 26, 2021

Ohh! That is weird, I installed it a week ago, and never thought about updating, thanks!

@pariterre
Copy link
Member

That is probably because the environment you used to install biorbd was not clean (new) as anaconda tries to find the best version that minimize the changes of version (or even prevents incompatibilities). Doing so, it may fall back to old version, if for instance, you already installed a specific version of Python, but the current required version for biorbd is newer.

For myself, I use one simple rule : one virtual environment by project. Like that I make sure previous installation does not pollute the future ones :)

@yugiero
Copy link
Author

yugiero commented Nov 26, 2021

Ok yeah, maybe I have to clean up my virtual environment first, because when I try to update with "conda update biorbd" I get some error..
image
If I try it out, SegmentCharacteristics is still missing, so probably my env is the problem..

@pariterre
Copy link
Member

Cleaning is a good idea, otherwise, you may want to specify the biorbd version:
conda install biorbd=1.8.2 -cconda-forge

@pariterre
Copy link
Member

But this is dangerous as it won't be updated in the future (because you specified that you want this specific version and nothing else)

@yugiero
Copy link
Author

yugiero commented Nov 26, 2021

Okay I created a new env for this project and got 1.8.2. Now the SegmentCharacteristics constructor is available, thank you so much!

@yugiero yugiero closed this as completed Nov 26, 2021
@yugiero
Copy link
Author

yugiero commented Nov 27, 2021

Sorry, for reopening again but I got one more question on the Segment constructor. I specified each argument but the spatial transform "cor". What to do about it? Should I use biorbd.Matrix(4,4), but how to populate the matrix then? Or biorbd.RotoTrans? The "AddSegment" method also has this "cor" argument.
My simple question is therefore just how I can add a segment to my model, without manually editing the file.

Hi, Thanks a lot! I want to create the segments from my data, merge them to a model and then write it to a file with writeModel for later use. A segment.characteristics().setMass method would also be helpful, because then I can just use the RBDL Segment constructor (if it is available in python for biorbd) and specify the segment characteristics here image

@yugiero yugiero reopened this Nov 27, 2021
@pariterre
Copy link
Member

Hi again :)
I do not think you actually need to create a segment to add it to the model. There is a method called AddSegment which properly prepare the Segment itself and updates other variables in the process. This interface method actually expects a 4x4 homogenous matrix, called RotoTrans (that is the rotation matrix concatenated with the translation matrix with a 0 0 0 1 line at the bottom)
[R3x3 T3x1 ]
[ 0 0 0 1 ]

Since I've never created a Segment in Python (because of this interface method), I never noticed that I've left the RBDL SpatialTransform there (which is equivalent to the 4d matrix).
Please note that there are constructor of that 4d matrix that are very useful, especially this one :

    RotoTrans(
        const Vector& rotation,
        const Vector3d& translation,
        const String &rotationSequence);

@yugiero
Copy link
Author

yugiero commented Nov 27, 2021

Ok, I tried to use AddSegment, but it still doesn't work. Maybe I specified something else wrong.
Here is my code:
image

And my output:
image

@pariterre
Copy link
Member

The problem are the Ranges, they should be a list of ranges (one by dof, you declared 6 dof (xyz translations, xyz rotations), so it expects :
qrange = [biorbd.Range(-np.pi/", np.pi/2)] * 6
But in the process of using writing, I forgot to add the export of ranges which was added later, so it is ignored anyway, so you can pass an empty list. The ranges are only for the user actually, it is never used as a constraints while performing any task. It is merely used by bioviz to set the limits of the sliders. I should add them to the writer anyway at some point.

The following snippets adds two segments and export them to a bioMod:

import biorbd
import numpy as np


# Defining two identical segments for testing
name_first = "First_segment"
name_second = "Second_segment"
parent_first = "ROOT"
parent_second = "Pelvis"
translations = "xyz"
rotations = "xyz"
ranges = []
roto_trans = biorbd.RotoTrans(np.array([1, 2, 3]), np.array([4, 5, 6]), "xyz")
mass = 10
com = biorbd.Vector3d(1, 2, 3)
inertia = biorbd.Matrix3d(1, 2, 3, 4, 5, 6, 7, 8, 9)
char = biorbd.SegmentCharacteristics(mass, com, inertia)

# Create an empty model and add the two segments
lukas = biorbd.Model()
lukas.AddSegment(name_first, parent_first, translations, rotations, ranges, ranges, ranges, char, roto_trans)
lukas.AddSegment(name_second, parent_second, translations, rotations, ranges, ranges, ranges, char, roto_trans)

# Write the model and read back
biorbd.Writer().writeModel(lukas, "coucou.bioMod")
lukas_coucou = biorbd.Model("coucou.bioMod")

@yugiero
Copy link
Author

yugiero commented Nov 27, 2021

Ohhh no. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants