Skip to content

Commit aa5da40

Browse files
authored
Merge pull request #203 from pariterre/wrapping
Added cylinder in wrapping objects
2 parents d07f9f7 + cb39615 commit aa5da40

21 files changed

+514
-256
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.0")
33
cmake_policy(SET CMP0042 NEW)
44
endif()
55

6-
project(biorbd VERSION 1.4.4)
6+
project(biorbd VERSION 1.5.0)
77
set (CMAKE_CXX_STANDARD 11)
88
set (BIORBD_NAME ${PROJECT_NAME})
99

binding/biorbd_muscles.i.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "Muscles/State.h"
1818
#include "Muscles/StateDynamics.h"
1919
#include "Muscles/StateDynamicsBuchanan.h"
20+
#include "Muscles/WrappingObject.h"
21+
#include "Muscles/WrappingHalfCylinder.h"
2022
#ifdef MODULE_STATIC_OPTIM
2123
#include "Muscles/StaticOptimization.h"
2224
#endif
@@ -107,5 +109,7 @@
107109
%include "@CMAKE_SOURCE_DIR@/include/Muscles/State.h"
108110
%include "@CMAKE_SOURCE_DIR@/include/Muscles/StateDynamics.h"
109111
%include "@CMAKE_SOURCE_DIR@/include/Muscles/StateDynamicsBuchanan.h"
112+
%include "@CMAKE_SOURCE_DIR@/include/Muscles/WrappingObject.h"
113+
%include "@CMAKE_SOURCE_DIR@/include/Muscles/WrappingHalfCylinder.h"
110114
@SWIG_STATIC_OPTIMIZATION_INCLUDE_COMMAND@
111115

binding/biorbd_utils.i.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ namespace std {
5252
}
5353
}
5454

55+
%extend biorbd::utils::Vector3d{
56+
biorbd::utils::NODE_TYPE typeOfNode() const{
57+
return $self->biorbd::utils::Node::typeOfNode();
58+
}
59+
}
60+
5561
%include "@CMAKE_SOURCE_DIR@/include/Utils/UtilsEnum.h"
5662
%include "@CMAKE_SOURCE_DIR@/include/Utils/String.h"
5763
%include "@CMAKE_SOURCE_DIR@/include/Utils/Path.h"

examples/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ endif()
1414
if (MODULE_KALMAN)
1515
list(APPEND EXAMPLE_FILES "inverseKinematicsKalmanExample.cpp")
1616
endif()
17+
if (MODULE_MUSCLES)
18+
list(APPEND EXAMPLE_FILES "WrappingObjectsExample.cpp")
19+
endif()
1720

1821
foreach(FILE ${EXAMPLE_FILES})
1922
# Get the name of the current file
@@ -43,5 +46,6 @@ endforeach()
4346
file(COPY
4447
${CMAKE_CURRENT_SOURCE_DIR}/pyomecaman.bioMod
4548
${CMAKE_CURRENT_SOURCE_DIR}/arm26.bioMod
49+
${CMAKE_CURRENT_SOURCE_DIR}/WrappingObjectExample.bioMod
4650
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
4751
)

examples/Test_longueur_wrapping.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import biorbd
2+
import math
3+
4+
import matplotlib.pyplot as plt
5+
import numpy as np
6+
from mpl_toolkits.mplot3d import Axes3D
7+
8+
# functions for cylinder rotation
9+
def cyl2cart(r, theta, z):
10+
return (r*np.cos(theta), r*np.sin(theta), z)
11+
12+
13+
def roll(R, zi, zf, RT):
14+
t = np.arange(0, 2 * np.pi + 0.1, 0.1)
15+
z = np.array([zi, zf])
16+
t, z = np.meshgrid(t, z)
17+
p, q = t.shape
18+
r = R * np.ones([p, q], float)
19+
# cylindrical coordinates to Cartesian coordinate
20+
x, y, z = cyl2cart(r, t, z)
21+
22+
# Euler rotation
23+
rot = np.dot(
24+
RT.rot().to_array(),
25+
np.array([x.ravel(), y.ravel(), z.ravel()])
26+
)
27+
28+
x_rt = rot[0, :].reshape(x.shape) + RTw.trans().to_array()[0]
29+
y_rt = rot[1, :].reshape(y.shape) + RTw.trans().to_array()[1]
30+
z_rt = rot[2, :].reshape(z.shape) + RTw.trans().to_array()[2]
31+
32+
return x_rt, y_rt, z_rt,
33+
34+
# model
35+
model = biorbd.Model("WrappingObjectExample.bioMod")
36+
37+
# wrapping RT matrix
38+
RTw = biorbd.WrappingCylinder(
39+
model.muscle(0).pathModifier().object(0)).RT(model, np.array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1]))
40+
RTw_trans = RTw.transpose()
41+
42+
# Point in global base
43+
Po = [0.264534159209888, 0.08668973339838759, 0.4024172540921048]
44+
Pi = [0.24035592212771023, 0.36899416468322876, 0.8650273094461659]
45+
Pi_wrap = [0.28997869688863276, 0.34739632020407846, 0.6636920365713757]
46+
Po_wrap = [0.29330355695193333, 0.3289556960274852, 0.627410425452938]
47+
48+
# Plot the surface
49+
fig = plt.figure()
50+
ax = fig.add_subplot(111, projection='3d')
51+
x, y, z = roll(0.05, -0.2, 0.2, RTw)
52+
ax.plot_surface(x, y, z)
53+
plt.plot((Po[0], Po_wrap[0]), (Po[1], Po_wrap[1]), (Po[2], Po_wrap[2]), marker='o')
54+
plt.plot((Pi[0], Pi_wrap[0]), (Pi[1], Pi_wrap[1]), (Pi[2], Pi_wrap[2]), marker='o')
55+
56+
# To set Axe3D to (almost) equal
57+
max_range = np.array([x.max()-x.min(), y.max()-y.min(), z.max()-z.min()]).max()
58+
Xb = 0.5*max_range*np.mgrid[-1:2:2, -1:2:2, -1:2:2][0].flatten() + 0.5*(x.max()+x.min())
59+
Yb = 0.5*max_range*np.mgrid[-1:2:2, -1:2:2, -1:2:2][1].flatten() + 0.5*(y.max()+y.min())
60+
Zb = 0.5*max_range*np.mgrid[-1:2:2, -1:2:2, -1:2:2][2].flatten() + 0.5*(z.max()+z.min())
61+
for xb, yb, zb in zip(Xb, Yb, Zb):
62+
ax.plot([xb], [yb], [zb], 'w')
63+
plt.show()
64+
65+
# Compute muscle length
66+
r = biorbd.WrappingCylinder(model.muscle(0).pathModifier().object(0)).radius()
67+
l_muscle_bd = model.muscle(0).musculoTendonLength(model, np.array([0.1, 0.1, 0.1, 0.1, 0.1, 0.1]))
68+
69+
70+
l_wt_arc = np.sqrt((Po_wrap[0]-Po[0])**2 + (Po_wrap[1]-Po[1])**2 + (Po_wrap[2]-Po[2])**2) + np.sqrt((Pi_wrap[0]-Pi[0])**2 + (Pi_wrap[1]-Pi[1])**2 + (Pi_wrap[2]-Pi[2])**2)
71+
72+
# Pi_wrap and Po_wrap provide in wrapping base to compute arc length
73+
Pi_wrap = biorbd.Vector3d(0.28997869688863276, 0.34739632020407846, 0.6636920365713757)
74+
Pi_wrap.applyRT(RTw_trans)
75+
Pi_wrap = Pi_wrap.to_array()
76+
77+
Po_wrap = biorbd.Vector3d(0.29330355695193333, 0.3289556960274852, 0.627410425452938)
78+
Po_wrap.applyRT(RTw_trans)
79+
Po_wrap = Po_wrap.to_array()
80+
81+
arc = math.acos(
82+
((Po_wrap[0] * Pi_wrap[0]) + (Pi_wrap[1] * Po_wrap[1])) / (
83+
math.sqrt(((Pi_wrap[1]**2)+(Pi_wrap[0]**2)) * ((Po_wrap[1]**2) + (Po_wrap[0]**2))))) * r
84+
85+
l_arc = math.sqrt(arc**2 + (Po_wrap[2]-Pi_wrap[2])**2)
86+
87+
l_m = l_wt_arc + l_arc # l_m = 0.582246096069153
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
version 4
2+
segment Seg0
3+
rt pi/10 pi/8 pi/6 xyz 0.1 0.2 0.3
4+
rotations xyz
5+
mass 40
6+
inertia
7+
1 0 0
8+
0 1 0
9+
0 0 1
10+
com 0.05 0.1 0.15
11+
mesh 0 0 0
12+
mesh 0.1 0.2 0.3
13+
endsegment
14+
15+
// Marker 0
16+
marker marker_0
17+
parent Seg0
18+
position 0.1 0.2 0.3
19+
endmarker
20+
21+
// Seg1
22+
segment Seg1
23+
parent Seg0
24+
rt pi/10 pi/8 pi/6 xyz 0.1 0.2 0.3
25+
rotations xyz
26+
mass 1
27+
inertia
28+
1 0 0
29+
0 1 0
30+
0 0 0.1
31+
com 0.05 0.1 0.15
32+
mesh 0 0 0
33+
mesh 0.1 0.2 0.3
34+
35+
endsegment
36+
// Marker 1
37+
marker marker_1
38+
parent Seg1
39+
position 0.1 0.2 0.3
40+
endmarker
41+
42+
musclegroup Seg02seg1
43+
OriginParent Seg0
44+
InsertionParent Seg1
45+
endmusclegroup
46+
muscle line
47+
Type hill
48+
musclegroup Seg02seg1
49+
OriginPosition 0.02 -0.1 0.2
50+
InsertionPosition 0.08 0.2 0.1
51+
optimalLength 0.8
52+
maximalForce 3
53+
tendonSlackLength 0.2
54+
pennationAngle 0.43633
55+
PCSA 3.7
56+
maxVelocity 10
57+
endmuscle
58+
59+
wrapping cyl1
60+
parent Seg0
61+
type cylinder
62+
RT pi/10 pi/8 pi/6 xyz 0.1 0.2 0.3
63+
muscle line
64+
musclegroup Seg02seg1
65+
diameter 0.1
66+
length 2
67+
wrappingside 1
68+
endwrapping
69+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#include "biorbd.h"
2+
3+
///
4+
/// \brief main Get and print the generalized acceleration of a model with wrapping objects
5+
/// \return Nothing
6+
///
7+
/// This examples shows how to
8+
/// 1. Load a model with a wrapping object
9+
/// 2. Position the model at a chosen position (Q), velocity (Qdot)
10+
/// 3. Compute the generalized acceleration (Qddot) assuming a set of muscle activations
11+
/// 4. Print them to the console
12+
///
13+
/// Please note that this example will work only with the Eigen backend
14+
///
15+
int main()
16+
{
17+
// Load a predefined model
18+
biorbd::Model model("WrappingObjectExample.bioMod");
19+
20+
// Choose a position/velocity to compute dynamics from
21+
biorbd::rigidbody::GeneralizedCoordinates Q(model);
22+
biorbd::rigidbody::GeneralizedVelocity Qdot(model);
23+
Q = Q.setOnes()/10;
24+
Qdot.setZero();
25+
26+
// Set all muscles to half of their maximal activation
27+
std::vector<std::shared_ptr<biorbd::muscles::State>> states;
28+
for (unsigned int i=0; i<model.nbMuscles(); ++i){
29+
states.push_back(std::make_shared<biorbd::muscles::State>(0, 0.5));
30+
}
31+
32+
// Proceed with the computation of joint torque from the muscles
33+
auto Tau = model.muscularJointTorque(states, Q, Qdot);
34+
35+
// Compute the generalized accelerations using the Tau from muscles.
36+
// Please note that in forward dynamics setting, it is usually advised to
37+
// additionnal residual torques. You would add them here to Tau.
38+
auto Qddot = model.ForwardDynamics(Q, Qdot, Tau);
39+
40+
// Print them to the console
41+
std::cout << Qddot.transpose() << std::endl;
42+
43+
// As an extra, let's print the individual muscle forces
44+
std::cout << model.muscleForces(states, Q, Qdot).transpose() << std::endl;
45+
46+
47+
return 0;
48+
}

include/Muscles/HillThelenType.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
namespace biorbd {
88
namespace muscles {
99
///
10-
/// \brief Muscle of Hill type augmented by Thelen (https://simtk-confluence.stanford.edu/display/OpenSim/Thelen+2003+Muscle+Model)
10+
/// \brief Muscle of Hill type augmented by Thelen
11+
/// https://simtk-confluence.stanford.edu/display/OpenSim/Thelen+2003+Muscle+Model
1112
///
1213
class BIORBD_API HillThelenType : public biorbd::muscles::HillType
1314
{

include/Muscles/PathModifiers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class BIORBD_API PathModifiers
7676
const biorbd::utils::Vector3d& object(unsigned int idx) const;
7777

7878
protected:
79-
std::shared_ptr<std::vector<biorbd::utils::Vector3d>> m_obj; ///< set of objects
79+
std::shared_ptr<std::vector<std::shared_ptr<biorbd::utils::Vector3d>>> m_obj; ///< set of objects
8080
std::shared_ptr<unsigned int> m_nbWraps; ///< Number of wrapping object in the set
8181
std::shared_ptr<unsigned int> m_nbVia; ///< Number of via points in the set
8282
std::shared_ptr<unsigned int> m_totalObjects; ///< Number of total objects in the set

0 commit comments

Comments
 (0)