Skip to content

Commit

Permalink
Merge pull request #55 from Ipuch/ground_joints
Browse files Browse the repository at this point in the history
ground joints and github action
  • Loading branch information
Ipuch authored Dec 23, 2022
2 parents 70224f3 + a04ca43 commit 7aec868
Show file tree
Hide file tree
Showing 21 changed files with 800 additions and 459 deletions.
61 changes: 0 additions & 61 deletions .appveyor.yml

This file was deleted.

55 changes: 55 additions & 0 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Run the tests

on: [pull_request]
jobs:
build:
strategy:
matrix:
include:
- os: ubuntu-20.04
label: linux-64
prefix: /usr/share/miniconda3/envs/bionc
- os: macos-latest
label: osx-64
prefix: /Users/runner/miniconda3/envs/bionc
- os: windows-latest
label: win-64
prefix: C:\Miniconda3\envs\bionc
name: ${{ matrix.label }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash -l {0}
steps:
- uses: actions/checkout@v2

- name: Setup environment
uses: conda-incubator/setup-miniconda@v2
with:
miniforge-variant: Mambaforge
miniforge-version: latest
use-mamba: true
activate-environment: bionc
environment-file: environment.yml

- name: Print mamba info
run: |
mamba config --show
mamba info
mamba list
- name: Install extra dependencies
run: mamba install pytest-cov pytest pytest-cov codecov -cconda-forge

- name: Run the actual tests
run: pytest -v --color=yes --cov-report term-missing --cov=bionc tests

- name: Test installed version of bionc
run: |
python setup.py install
cd
python -c "import bionc"
- name: Upload coverage to Codecov
run: codecov
if: matrix.label == 'linux-64'
4 changes: 2 additions & 2 deletions bionc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@
from .protocols.natural_accelerations import SegmentNaturalAccelerations, NaturalAccelerations
from .protocols.homogenous_transform import HomogeneousTransform

from .utils.enums import NaturalAxis, CartesianAxis

from casadi.casadi import MX as MX_type
from numpy import ndarray

# global variable to store the type of the math interface
casadi_type = MX_type
numpy_type = ndarray

from .utils.enums import NaturalAxis
2 changes: 1 addition & 1 deletion bionc/bionc_casadi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
from .natural_marker import NaturalMarker, Marker
from .natural_segment import NaturalSegment
from .inertia_parameters import InertiaParameters
from .joint import Joint
from .joint import Joint, GroundJoint
from .natural_vector import NaturalVector
23 changes: 15 additions & 8 deletions bionc/bionc_casadi/biomechanical_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ def joint_constraints(self, Q: NaturalCoordinates) -> MX:
for joint_name, joint in self.joints.items():
idx = slice(nb_constraints, nb_constraints + joint.nb_constraints)

Q_parent = Q.vector(self.segments[joint.parent.name].index)
Q_parent = (
None if joint.parent is None else Q.vector(self.segments[joint.parent.name].index)
) # if the joint is a joint with the ground, the parent is None
Q_child = Q.vector(self.segments[joint.child.name].index)
Phi_k[idx] = joint.constraint(Q_parent, Q_child)

Expand All @@ -129,16 +131,21 @@ def joint_constraints_jacobian(self, Q: NaturalCoordinates) -> np.ndarray:
nb_constraints = 0
for joint_name, joint in self.joints.items():
idx_row = slice(nb_constraints, nb_constraints + joint.nb_constraints)
idx_col_parent = slice(
12 * self.segments[joint.parent.name].index, 12 * (self.segments[joint.parent.name].index + 1)
)

if joint.parent is not None: # If the joint is not a ground joint
idx_col_parent = slice(
12 * self.segments[joint.parent.name].index, 12 * (self.segments[joint.parent.name].index + 1)
)
Q_child = Q.vector(self.segments[joint.child.name].index)
K_k[idx_row, idx_col_parent] = joint.parent_constraint_jacobian(Q_child)

idx_col_child = slice(
12 * self.segments[joint.child.name].index, 12 * (self.segments[joint.child.name].index + 1)
)

Q_parent = Q.vector(self.segments[joint.parent.name].index)
Q_child = Q.vector(self.segments[joint.child.name].index)
K_k[idx_row, idx_col_parent], K_k[idx_row, idx_col_child] = joint.constraint_jacobian(Q_parent, Q_child)
Q_parent = (
None if joint.parent is None else Q.vector(self.segments[joint.parent.name].index)
) # if the joint is a joint with the ground, the parent is None
K_k[idx_row, idx_col_child] = joint.child_constraint_jacobian(Q_parent)

nb_constraints += self.joints[joint_name].nb_constraints

Expand Down
43 changes: 43 additions & 0 deletions bionc/bionc_casadi/cartesian_vector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from casadi import MX
import numpy as np
from ..utils.enums import CartesianAxis


class CartesianVector(MX):
"""
Class used to create a natural vector, a vector that is expressed in the natural coordinate system of a segment
"""

def __new__(cls, input_array: MX | np.ndarray | list | tuple):
"""
Create a new instance of the class.
"""

if not isinstance(input_array, (MX, np.ndarray)):
input_array = np.array(input_array)

obj = MX.__new__(cls)

if isinstance(input_array, MX):
size1 = input_array.shape[0]
size2 = input_array.shape[1]
else:
size1 = input_array.shape[0]
size2 = input_array.shape[1] if input_array.shape.__len__() == 2 else 1

if size1 != 3:
raise ValueError("The input array must have 3 elements")

if size2 != 1:
raise ValueError("The position must be a 3d vector with only one column")

return obj

@classmethod
def axis(cls, axis: CartesianAxis):
if axis == CartesianAxis.X:
return cls(np.array([1, 0, 0]))
elif axis == CartesianAxis.Y:
return cls(np.array([0, 1, 0]))
elif axis == CartesianAxis.Z:
return cls(np.array([0, 0, 1]))
Loading

0 comments on commit 7aec868

Please sign in to comment.