├── .gitattributes ├── .gitignore ├── images ├── sim1.png ├── sim2.png ├── sim3.png └── sim4.png ├── datasets ├── initSim1.mat ├── initSim2.mat ├── initSim3.mat └── initSim4.mat ├── meshes └── iRonCub_Leg.stl ├── src ├── motor-positioning │ ├── @GeneticAlgorithm │ │ ├── getDecimalNumber.m │ │ ├── updateProbabilityOfSelection.m │ │ ├── getDecimalCombination.m │ │ ├── getDecimalPopulation.m │ │ ├── getBinaryCombination.m │ │ ├── performMutation.m │ │ ├── selectParents.m │ │ ├── plotStatsFitValues.m │ │ ├── updateFitValues.m │ │ ├── performSinglePointCrossover.m │ │ ├── createPopulation.m │ │ ├── mergePopulations.m │ │ ├── getStats.m │ │ ├── runAlgorithm.m │ │ └── GeneticAlgorithm.m │ ├── @SensitivityAnalysis │ │ ├── plotStats.m │ │ ├── SensitivityAnalysis.m │ │ └── runAlgorithm.m │ └── selectMotorPositioning.m ├── setup_sim.m └── controller │ ├── @ControllerKinAbs │ ├── ControllerKinAbs.m │ └── computeCostFunctionAndConstraints.m │ └── @ControllerKinRel │ ├── ControllerKinRel.m │ └── computeCostFunctionAndConstraints.m ├── CITATION.cff ├── conda-env ├── environment-win.yml └── environment-linux.yml ├── LICENSE ├── .github └── workflows │ └── matlab_ci.yml ├── pixi.toml ├── scripts ├── test_ci.m ├── sim3.m ├── sim4.m ├── sim1.m └── sim2.m ├── README.md └── pixi.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | # GitHub syntax highlighting 2 | pixi.lock linguist-language=YAML linguist-generated=true 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # pixi environments 3 | .pixi 4 | *.egg-info 5 | # folder used by pixi to install source depenencies 6 | .pixi_ws -------------------------------------------------------------------------------- /images/sim1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ami-iit/paper_bergonti_2022_tro_kinematics-control-morphingcovers/HEAD/images/sim1.png -------------------------------------------------------------------------------- /images/sim2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ami-iit/paper_bergonti_2022_tro_kinematics-control-morphingcovers/HEAD/images/sim2.png -------------------------------------------------------------------------------- /images/sim3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ami-iit/paper_bergonti_2022_tro_kinematics-control-morphingcovers/HEAD/images/sim3.png -------------------------------------------------------------------------------- /images/sim4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ami-iit/paper_bergonti_2022_tro_kinematics-control-morphingcovers/HEAD/images/sim4.png -------------------------------------------------------------------------------- /datasets/initSim1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ami-iit/paper_bergonti_2022_tro_kinematics-control-morphingcovers/HEAD/datasets/initSim1.mat -------------------------------------------------------------------------------- /datasets/initSim2.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ami-iit/paper_bergonti_2022_tro_kinematics-control-morphingcovers/HEAD/datasets/initSim2.mat -------------------------------------------------------------------------------- /datasets/initSim3.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ami-iit/paper_bergonti_2022_tro_kinematics-control-morphingcovers/HEAD/datasets/initSim3.mat -------------------------------------------------------------------------------- /datasets/initSim4.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ami-iit/paper_bergonti_2022_tro_kinematics-control-morphingcovers/HEAD/datasets/initSim4.mat -------------------------------------------------------------------------------- /meshes/iRonCub_Leg.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ami-iit/paper_bergonti_2022_tro_kinematics-control-morphingcovers/HEAD/meshes/iRonCub_Leg.stl -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/getDecimalNumber.m: -------------------------------------------------------------------------------- 1 | function numDec = getDecimalNumber(obj,numBin) 2 | arguments 3 | obj 4 | numBin (:,1) 5 | end 6 | numDec = transpose(obj.matrixFromBinaryNumber2DecimalNumber * numBin); 7 | end 8 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/updateProbabilityOfSelection.m: -------------------------------------------------------------------------------- 1 | function updateProbabilityOfSelection(obj) 2 | 3 | sumFitValues = sum(obj.population.fitValues); 4 | 5 | obj.population.probabilityOfSelection = obj.population.fitValues/sumFitValues; 6 | 7 | end 8 | -------------------------------------------------------------------------------- /src/setup_sim.m: -------------------------------------------------------------------------------- 1 | function setup_sim() 2 | start_full_path = fileparts(mfilename('fullpath')); 3 | addpath(fullfile(start_full_path,'controller')); 4 | addpath(fullfile(start_full_path,'motor-positioning')); 5 | addpath(fullfile(start_full_path,'..','meshes')); 6 | end 7 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/getDecimalCombination.m: -------------------------------------------------------------------------------- 1 | function combinationDec = getDecimalCombination(obj,combinationBin) 2 | arguments 3 | obj 4 | combinationBin (:,1) 5 | end 6 | combinationDec = sort(transpose(obj.matrixFromCombinationBin2CombinationDec * combinationBin)); 7 | end 8 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/getDecimalPopulation.m: -------------------------------------------------------------------------------- 1 | function populationDec = getDecimalPopulation(obj,populationBin) 2 | arguments 3 | obj 4 | populationBin 5 | end 6 | populationDec = sort(transpose(obj.matrixFromCombinationBin2CombinationDec * transpose(populationBin)),2); 7 | end 8 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/getBinaryCombination.m: -------------------------------------------------------------------------------- 1 | function combinationBin = getBinaryCombination(obj,combinationDec) 2 | arguments 3 | obj 4 | combinationDec (:,1) 5 | end 6 | combinationBin = transpose(str2num(reshape(dec2bin(combinationDec,obj.combinationBinGeneLength)',[],1))); 7 | end 8 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/performMutation.m: -------------------------------------------------------------------------------- 1 | function performMutation(obj) 2 | 3 | indexesMutation = rand(obj.stgs.populationSize.children,obj.combinationBinLength) <= obj.stgs.probabilityMutation; 4 | 5 | obj.children.combinationBin(indexesMutation) = not(obj.children.combinationBin(indexesMutation)); 6 | 7 | end 8 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/selectParents.m: -------------------------------------------------------------------------------- 1 | function selectParents(obj) 2 | vectorRandomNumbers = rand(1,obj.stgs.populationSize.children); 3 | 4 | matrixDiff = vectorRandomNumbers - cumsum(obj.population.probabilityOfSelection); 5 | matrixDiff(matrixDiff>0) = -2; 6 | [~,obj.children.parentsIndexes] = max(matrixDiff); 7 | 8 | end 9 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/plotStatsFitValues.m: -------------------------------------------------------------------------------- 1 | function plotStatsFitValues(obj) 2 | figure 3 | hold on 4 | stairs(obj.stats.maxFitValues ,'linewidth',1.2) 5 | plot(obj.stats.meanFitValues,'linewidth',1.2) 6 | stairs(obj.stats.minFitValues ,'linewidth',1.2) 7 | hold off 8 | grid on 9 | set(gca, 'XScale', 'log') 10 | legend('max','mean','min') 11 | legend('location','best') 12 | xlabel('Number of generation') 13 | ylabel('Fitness value population') 14 | end 15 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/updateFitValues.m: -------------------------------------------------------------------------------- 1 | function updateFitValues(obj) 2 | 3 | 4 | obj.children.combinationDec = obj.getDecimalPopulation(obj.children.combinationBin); 5 | 6 | for i = 1 : obj.stgs.populationSize.children 7 | 8 | if all( obj.combinationDecRange(2) >= obj.children.combinationDec(i,:) ) && ... 9 | all( obj.combinationDecRange(1) <= obj.children.combinationDec(i,:) ) 10 | 11 | obj.children.fitValues(i) = obj.fitnessFunction(obj.children.combinationDec(i,:)); 12 | else 13 | obj.children.fitValues(i) = 0; 14 | end 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /src/motor-positioning/@SensitivityAnalysis/plotStats.m: -------------------------------------------------------------------------------- 1 | function plotStats(obj) 2 | figure 3 | sgtitle('stats sensitivity analsysis') 4 | subplot(1,2,1) 5 | [X Y] = meshgrid(1:obj.stgs.numberCombinations,1:2*obj.stgs.numberMotorConf); 6 | ribbon(Y,sort(abs(obj.stats.dDeterminant_dAngle),2)') 7 | zlabel('$\frac{\partial det}{\partial \theta}$','interpreter','latex') 8 | ylabel('directions') 9 | xlabel('combination') 10 | subplot(1,2,2) 11 | hold on 12 | plot(obj.stats.divergenceDeterminant) 13 | yVal = ylim; 14 | plot(obj.indexBestCandidate*ones(2,1),yVal,'--') 15 | ylabel('$\nabla \cdot det$','interpreter','latex') 16 | yyaxis right 17 | plot(abs(obj.stats.determinant_iniConf)) 18 | ylabel('$det$','interpreter','latex') 19 | end 20 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | message: "If you use this material, please cite it as below." 3 | url: "https://github.com/ami-iit/paper_bergonti_2022_tro_kinematics-control-morphingcovers" 4 | preferred-citation: 5 | type: article 6 | authors: 7 | - family-names: "Bergonti" 8 | given-names: "Fabio" 9 | orcid: "https://orcid.org/0000-0003-3455-8056" 10 | - family-names: "Nava" 11 | given-names: "Gabriele" 12 | orcid: "https://orcid.org/0000-0001-8965-2934" 13 | - family-names: "Fiorio" 14 | given-names: "Luca" 15 | orcid: "https://orcid.org/0000-0001-8965-2934" 16 | - family-names: "L'Erario" 17 | given-names: "Giuseppe" 18 | orcid: "https://orcid.org/0000-0001-6042-3222" 19 | - family-names: "Pucci" 20 | given-names: "Daniele" 21 | orcid: "https://orcid.org/0000-0002-7600-3203" 22 | doi: "10.1109/TRO.2022.3170281" 23 | journal: "IEEE Transactions on Robotics" 24 | month: 10 25 | start: 3300 # First page number 26 | end: 3313 # Last page number 27 | title: "Modeling and Control of Morphing Covers for the Adaptive Morphology of Humanoid Robots" 28 | issue: 5 29 | volume: 38 30 | year: 2022 31 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/performSinglePointCrossover.m: -------------------------------------------------------------------------------- 1 | function performSinglePointCrossover(obj) 2 | 3 | indexCrossover = randi([1 obj.combinationBinLength-1],1,obj.stgs.populationSize.children/2); 4 | probCrossover = rand(obj.stgs.populationSize.children/2,1); 5 | 6 | % p1=[0 0 1 | 0 0 0 1] 7 | % p2=[0 1 0 | 1 0 1 1] 8 | % x 9 | % 10 | % indexCrossover = 3 11 | % 12 | % c1=[0 0 1 | 1 0 1 1] 13 | % c2=[0 1 0 | 0 0 0 1] 14 | 15 | indexParents = reshape(obj.children.parentsIndexes,[],2); 16 | parent1 = obj.population.combinationBin(indexParents(:,1),:); 17 | parent2 = obj.population.combinationBin(indexParents(:,2),:); 18 | 19 | B = zeros(size(parent1)); 20 | % Perform crossover 21 | B(sub2ind(size(parent1),1:size(parent1,1),indexCrossover)) = 1; 22 | B = cumsum(B,2); 23 | B = (B == 0); 24 | % No crossover => the children are equal to the parents 25 | B(obj.stgs.probabilityCrossover < probCrossover,:) = 1; 26 | 27 | obj.children.combinationBin = [parent1.*B + parent2.*not(B);... 28 | parent1.*not(B) + parent2.*B]; 29 | 30 | end 31 | -------------------------------------------------------------------------------- /conda-env/environment-win.yml: -------------------------------------------------------------------------------- 1 | name: imorph 2 | channels: 3 | - robotology 4 | - conda-forge 5 | dependencies: 6 | - bzip2=1.0.8=h8ffe710_4 7 | - ca-certificates=2022.5.18.1=h5b45459_0 8 | - casadi=3.5.5=py310h2d2b175_9 9 | - casadi-matlab-bindings=3.5.5.2=h0e60522_53 10 | - ipopt=3.14.6=hf6be2e5_0 11 | - libblas=3.9.0=14_win64_openblas 12 | - libcblas=3.9.0=14_win64_openblas 13 | - libffi=3.4.2=h8ffe710_5 14 | - libflang=5.0.0=h6538335_20180525 15 | - liblapack=3.9.0=14_win64_openblas 16 | - libopenblas=0.3.20=pthreads_hc469a61_0 17 | - libosqp=0.6.2=h0e60522_3 18 | - libzlib=1.2.12=h8ffe710_0 19 | - llvm-meta=5.0.0=0 20 | - metis=5.1.0=h0e60522_1006 21 | - mumps-seq=5.2.1=hb3f9cae_11 22 | - numpy=1.22.4=py310hed7ac4c_0 23 | - openmp=5.0.0=vc14_1 24 | - openssl=3.0.3=h8ffe710_0 25 | - pip=22.1.2=pyhd8ed1ab_0 26 | - python=3.10.4=hcf16a7b_0_cpython 27 | - python_abi=3.10=2_cp310 28 | - setuptools=62.3.2=py310h5588dad_0 29 | - sqlite=3.38.5=h8ffe710_0 30 | - tk=8.6.12=h8ffe710_0 31 | - tzdata=2022a=h191b570_0 32 | - ucrt=10.0.20348.0=h57928b3_0 33 | - vc=14.2=hb210afc_6 34 | - vs2015_runtime=14.29.30037=h902a5da_6 35 | - wheel=0.37.1=pyhd8ed1ab_0 36 | - xz=5.2.5=h62dcd97_1 37 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/createPopulation.m: -------------------------------------------------------------------------------- 1 | function createPopulation(obj) 2 | 3 | for i = 1 : obj.stgs.populationSize.parents 4 | obj.population.combinationDec(i,:) = sort(randi(obj.combinationDecRange,1,obj.combinationDecLength)); 5 | obj.population.combinationBin(i,:) = obj.getBinaryCombination(obj.population.combinationDec(i,:)); 6 | obj.population.fitValues(i) = obj.fitnessFunction(obj.population.combinationDec(i,:)); 7 | end 8 | 9 | if isempty(obj.initialGuessDec) == 0 10 | 11 | obj.initialGuessDec(any( obj.initialGuessDec > obj.combinationDecRange(2) ,2 ),:) = []; 12 | obj.initialGuessDec(any( obj.initialGuessDec < obj.combinationDecRange(1) ,2 ),:) = []; 13 | 14 | nGuess = size(obj.initialGuessDec,1); 15 | if nGuess > 0 16 | initialGuess.combinationDec = obj.initialGuessDec; 17 | initialGuess.combinationBin = zeros(nGuess,obj.combinationBinLength); 18 | initialGuess.fitValues = zeros(nGuess,1); 19 | 20 | for i = 1 : nGuess 21 | initialGuess.combinationBin(i,:) = obj.getBinaryCombination(initialGuess.combinationDec(i,:)); 22 | initialGuess.fitValues(i) = obj.fitnessFunction(initialGuess.combinationDec(i,:)); 23 | end 24 | 25 | obj.mergePopulations(obj.population,initialGuess) 26 | end 27 | end 28 | 29 | obj.updateProbabilityOfSelection(); 30 | 31 | end 32 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/mergePopulations.m: -------------------------------------------------------------------------------- 1 | function mergePopulations(obj,pop1,pop2) 2 | %UPDATEPOPULATION Summary of this function goes here 3 | % Detailed explanation goes here 4 | 5 | popMerge.combinationDec = [pop1.combinationDec ; pop2.combinationDec]; 6 | popMerge.combinationBin = [pop1.combinationBin ; pop2.combinationBin]; 7 | popMerge.fitValues = [pop1.fitValues ; pop2.fitValues ]; 8 | 9 | if obj.stgs.populationWithDuplicates == 0 10 | boolDuplicates = ones(size(popMerge.combinationDec,1),1); 11 | [~,indexesUnique,~] = unique(popMerge.combinationDec,'rows','stable'); 12 | boolDuplicates(indexesUnique)=0; 13 | boolDuplicates = (boolDuplicates==1); 14 | 15 | popMerge.fitValues(boolDuplicates) = 0; 16 | end 17 | 18 | [~,order] = sort(popMerge.fitValues,'descend'); 19 | 20 | selIndexes = order(1:obj.stgs.populationSize.parents); 21 | 22 | populationCDbeforeMerge = obj.population.combinationDec; 23 | 24 | obj.population.combinationBin = popMerge.combinationBin(selIndexes,:); 25 | obj.population.combinationDec = popMerge.combinationDec(selIndexes,:); 26 | obj.population.fitValues = popMerge.fitValues(selIndexes,:); 27 | 28 | populationCDafterMerge = obj.population.combinationDec; 29 | 30 | obj.updateProbabilityOfSelection(); 31 | 32 | if sum(abs(populationCDbeforeMerge-populationCDafterMerge),'all') == 0 33 | obj.counterConstantPopulation = obj.counterConstantPopulation + 1; 34 | else 35 | obj.counterConstantPopulation = 0; 36 | end 37 | 38 | end 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2022, Artificial and Mechanical Intelligence 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /conda-env/environment-linux.yml: -------------------------------------------------------------------------------- 1 | name: imorph 2 | channels: 3 | - robotology 4 | - conda-forge 5 | dependencies: 6 | - _libgcc_mutex=0.1=conda_forge 7 | - _openmp_mutex=4.5=2_gnu 8 | - ampl-mp=3.1.0=h2cc385e_1006 9 | - bzip2=1.0.8=h7f98852_4 10 | - ca-certificates=2022.5.18.1=ha878542_0 11 | - casadi=3.5.5=py310h597d7ca_9 12 | - casadi-matlab-bindings=3.5.5.2=h27087fc_53 13 | - ipopt=3.14.6=h630875f_0 14 | - ld_impl_linux-64=2.36.1=hea4e1c9_2 15 | - libblas=3.9.0=14_linux64_openblas 16 | - libcblas=3.9.0=14_linux64_openblas 17 | - libedit=3.1.20191231=he28a2e2_2 18 | - libffi=3.4.2=h7f98852_5 19 | - libgcc-ng=12.1.0=h8d9b700_16 20 | - libgfortran-ng=12.1.0=h69a702a_16 21 | - libgfortran5=12.1.0=hdcd56e2_16 22 | - libgomp=12.1.0=h8d9b700_16 23 | - libiconv=1.16=h516909a_0 24 | - liblapack=3.9.0=14_linux64_openblas 25 | - libnsl=2.0.0=h7f98852_0 26 | - libopenblas=0.3.20=pthreads_h78a6416_0 27 | - libosqp=0.6.2=h9c3ff4c_3 28 | - libstdcxx-ng=12.1.0=ha89aaad_16 29 | - libuuid=2.32.1=h7f98852_1000 30 | - libzlib=1.2.12=h166bdaf_0 31 | - metis=5.1.0=h58526e2_1006 32 | - mumps-include=5.2.1=ha770c72_11 33 | - mumps-seq=5.2.1=h2104b81_11 34 | - ncurses=6.3=h27087fc_1 35 | - numpy=1.22.4=py310h4ef5377_0 36 | - openssl=3.0.3=h166bdaf_0 37 | - pip=22.1.2=pyhd8ed1ab_0 38 | - python=3.10.4=h2660328_0_cpython 39 | - python_abi=3.10=2_cp310 40 | - readline=8.1=h46c0cb4_0 41 | - scotch=6.0.9=hb2e6521_2 42 | - setuptools=62.3.2=py310hff52083_0 43 | - sqlite=3.38.5=h4ff8645_0 44 | - tk=8.6.12=h27826a3_0 45 | - tzdata=2022a=h191b570_0 46 | - unixodbc=2.3.10=h583eb01_0 47 | - wheel=0.37.1=pyhd8ed1ab_0 48 | - xz=5.2.5=h516909a_1 49 | - zlib=1.2.12=h166bdaf_0 50 | -------------------------------------------------------------------------------- /.github/workflows/matlab_ci.yml: -------------------------------------------------------------------------------- 1 | name: MATLAB tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | 13 | run-matlab-test: 14 | 15 | name: Install dependencies and run MATLAB tests 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | os: [ubuntu-latest, windows-latest, macos-13] 20 | matlab_version: [R2021a, R2021b, R2022a] 21 | runs-on: ${{ matrix.os }} 22 | 23 | steps: 24 | 25 | - name: Check out repository 26 | uses: actions/checkout@v2 27 | 28 | - name: Install MATLAB 29 | uses: matlab-actions/setup-matlab@v1 30 | with: 31 | release: ${{ matrix.matlab_version }} 32 | 33 | - name: Clone mystica 34 | run: | 35 | cd .. 36 | cd .. 37 | git clone https://github.com/ami-iit/mystica.git --branch v2022.06.0 38 | # mystica is cloned in this location to avoid a too long PREFIX (see https://github.com/robotology/robotology-superbuild/pull/1145) 39 | 40 | - name: Install mystica 41 | uses: matlab-actions/run-command@v1 42 | with: 43 | command: | 44 | cd .. 45 | cd .. 46 | cd mystica 47 | install('env_name','imorph') 48 | 49 | # workaround for https://github.com/robotology/robotology-superbuild/issues/64 and https://github.com/ami-iit/mystica/issues/6 50 | - name: Do not use MATLAB's stdc++ to avoid incompatibilities with other libraries 51 | if: contains(matrix.os, 'ubuntu') 52 | run: 53 | echo "LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6" >> $GITHUB_ENV 54 | 55 | - name: Run MATLAB tests 56 | uses: matlab-actions/run-command@v1 57 | with: 58 | command: | 59 | run(fullfile('..','..','mystica','deps','setup')) 60 | run(fullfile('scripts','test_ci')) 61 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/getStats.m: -------------------------------------------------------------------------------- 1 | function getStats(obj,phase) 2 | 3 | switch phase 4 | case 'config' 5 | obj.stats.time( obj.endCondition.limitGenerationNumber) = 0; 6 | obj.stats.maxFitValues( obj.endCondition.limitGenerationNumber) = 0; 7 | obj.stats.minFitValues( obj.endCondition.limitGenerationNumber) = 0; 8 | obj.stats.meanFitValues( obj.endCondition.limitGenerationNumber) = 0; 9 | obj.stats.medianFitValues(obj.endCondition.limitGenerationNumber) = 0; 10 | obj.stats.stdFitValues( obj.endCondition.limitGenerationNumber) = 0; 11 | case 'update' 12 | obj.stats.time( obj.indexGen) = toc( obj.time); 13 | obj.stats.maxFitValues( obj.indexGen) = max( obj.population.fitValues); 14 | obj.stats.minFitValues( obj.indexGen) = min( obj.population.fitValues); 15 | obj.stats.meanFitValues( obj.indexGen) = mean( obj.population.fitValues); 16 | obj.stats.medianFitValues(obj.indexGen) = median(obj.population.fitValues); 17 | obj.stats.stdFitValues( obj.indexGen) = std( obj.population.fitValues); 18 | case 'delete' 19 | obj.stats.time( obj.indexGen+1:end) = []; 20 | obj.stats.maxFitValues( obj.indexGen+1:end) = []; 21 | obj.stats.minFitValues( obj.indexGen+1:end) = []; 22 | obj.stats.meanFitValues( obj.indexGen+1:end) = []; 23 | obj.stats.medianFitValues(obj.indexGen+1:end) = []; 24 | obj.stats.stdFitValues( obj.indexGen+1:end) = []; 25 | case 'print' 26 | fprintf('GA | Final Population fitValues \n | max : %g \n | min : %g \n | mean: %g\n',... 27 | obj.stats.maxFitValues( obj.indexGen),... 28 | obj.stats.minFitValues( obj.indexGen),... 29 | obj.stats.meanFitValues(obj.indexGen)) 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /src/controller/@ControllerKinAbs/ControllerKinAbs.m: -------------------------------------------------------------------------------- 1 | classdef ControllerKinAbs < mystica.controller.Base 2 | 3 | properties (SetAccess=protected,GetAccess=public) 4 | mBodyTwist_0 5 | end 6 | 7 | methods 8 | function obj = ControllerKinAbs(input) 9 | arguments 10 | input.model 11 | input.stateKinMBody 12 | input.stgsController 13 | input.stgsDesiredShape 14 | input.time 15 | input.controller_dt 16 | end 17 | 18 | obj@mystica.controller.Base(... 19 | 'model',input.model,... 20 | 'state',input.stateKinMBody,... 21 | 'stgsController',input.stgsController,... 22 | 'stgsDesiredShape',input.stgsDesiredShape,... 23 | 'time',input.time,... 24 | 'controller_dt',input.controller_dt); 25 | 26 | obj.computeCostFunctionAndConstraints('model',input.model,'stateKinMBody',input.stateKinMBody); 27 | obj.mBodyTwist_0 = zeros(input.model.constants.mBodyTwist,1); 28 | 29 | end 30 | 31 | function mBodyTwist_0 = solve(obj,input) 32 | arguments 33 | obj 34 | input.time 35 | input.stateKinMBody 36 | input.model 37 | end 38 | obj.opti.set_initial(obj.csdSy.mBodyTwist_0,obj.mBodyTwist_0); 39 | obj.opti.set_value(obj.csdSy.mBodyPosQuat_0,input.stateKinMBody.mBodyPosQuat_0); 40 | obj.opti.set_value(obj.csdSy.time,input.time); 41 | obj.opti.set_value(obj.csdSy.mBodyTwist_0_lastSol,obj.mBodyTwist_0); 42 | try 43 | sol = obj.opti.solve(); 44 | obj.mBodyTwist_0 = sol.value(obj.csdSy.mBodyTwist_0); 45 | catch 46 | warning('QP failed') 47 | end 48 | mBodyTwist_0 = obj.mBodyTwist_0; 49 | end 50 | 51 | end 52 | methods (Access=protected) 53 | computeCostFunctionAndConstraints(obj) 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/runAlgorithm.m: -------------------------------------------------------------------------------- 1 | function runAlgorithm(obj,input) 2 | arguments 3 | obj 4 | input.limitGenerationNumber = obj.endCondition.limitGenerationNumber 5 | input.limitCounterConstantPopulation = obj.endCondition.limitCounterConstantPopulation 6 | end 7 | 8 | obj.endCondition.limitGenerationNumber = input.limitGenerationNumber; 9 | 10 | continueWhileLoop = 0; 11 | 12 | if obj.indexGen < obj.endCondition.limitGenerationNumber 13 | obj.getStats('config') 14 | continueWhileLoop = 1; 15 | end 16 | 17 | if obj.indexGen == 1 18 | obj.getStats('update') 19 | end 20 | 21 | nameTTF = []; 22 | 23 | while continueWhileLoop 24 | obj.indexGen = obj.indexGen + 1; 25 | 26 | obj.selectParents() 27 | obj.performSinglePointCrossover() 28 | obj.performMutation() 29 | obj.updateFitValues() 30 | obj.mergePopulations(obj.population,obj.children) 31 | 32 | obj.getStats('update') 33 | 34 | if mod(obj.indexGen,round(obj.endCondition.limitGenerationNumber/100)) == 0 35 | fprintf('GA | Percentage of completion: %.0f%%\n',(obj.indexGen/obj.endCondition.limitGenerationNumber)*100); 36 | nameTTF = mystica.utils.createTimeTrackerFile(nameTTF,'GA',(obj.indexGen/obj.endCondition.limitGenerationNumber)*100,100); 37 | end 38 | 39 | if (obj.counterConstantPopulation > obj.endCondition.limitCounterConstantPopulation) && ... 40 | obj.stats.minFitValues(obj.indexGen) > obj.endCondition.thresholdFitValues 41 | continueWhileLoop = 0; 42 | fprintf('GA | Algorithm converged after %i generations (time %is)\n',obj.indexGen,round(toc(obj.time))); 43 | end 44 | 45 | if obj.indexGen >= obj.endCondition.limitGenerationNumber 46 | continueWhileLoop = 0; 47 | fprintf('GA | Algorithm terminaned after %i generations (time %is)\n',obj.endCondition.limitGenerationNumber,round(toc(obj.time))); 48 | end 49 | 50 | end 51 | 52 | if obj.indexGen < obj.endCondition.limitGenerationNumber 53 | obj.getStats('delete') 54 | end 55 | obj.getStats('print') 56 | delete(nameTTF) 57 | 58 | end 59 | -------------------------------------------------------------------------------- /src/controller/@ControllerKinRel/ControllerKinRel.m: -------------------------------------------------------------------------------- 1 | classdef ControllerKinRel < mystica.controller.Base 2 | 3 | properties (SetAccess=protected,GetAccess=public) 4 | motorsAngVel 5 | end 6 | 7 | methods 8 | function obj = ControllerKinRel(input) 9 | arguments 10 | input.model 11 | input.stateKinMBody 12 | input.stgsController 13 | input.stgsDesiredShape 14 | input.time 15 | input.controller_dt 16 | end 17 | 18 | obj@mystica.controller.Base(... 19 | 'model',input.model,... 20 | 'state',input.stateKinMBody,... 21 | 'stgsController',input.stgsController,... 22 | 'stgsDesiredShape',input.stgsDesiredShape,... 23 | 'time',input.time,... 24 | 'controller_dt',input.controller_dt); 25 | 26 | obj.computeCostFunctionAndConstraints('model',input.model,'stateKinMBody',input.stateKinMBody); 27 | obj.motorsAngVel = zeros(input.model.constants.motorsAngVel,1); 28 | 29 | end 30 | 31 | function motorsAngVel = solve(obj,input) 32 | arguments 33 | obj 34 | input.time 35 | input.stateKinMBody 36 | input.model 37 | end 38 | 39 | Zact = input.stateKinMBody.getZact('model',input.model); 40 | invZact = mystica.utils.pinvDamped(Zact,obj.stgsController.regTermDampPInv); 41 | 42 | obj.opti.set_initial(obj.csdSy.motorsAngVel,obj.motorsAngVel); 43 | obj.opti.set_value(obj.csdSy.mBodyPosQuat_0,input.stateKinMBody.mBodyPosQuat_0); 44 | obj.opti.set_value(obj.csdSy.time,input.time); 45 | obj.opti.set_value(obj.csdSy.motorsAngVel_lastSol,obj.motorsAngVel); 46 | obj.opti.set_value(obj.csdSy.nullJc_mBodyTwist_0,input.stateKinMBody.nullJc_mBodyTwist_0); 47 | obj.opti.set_value(obj.csdSy.invZact,invZact); 48 | try 49 | sol = obj.opti.solve(); 50 | obj.motorsAngVel = sol.value(obj.csdSy.motorsAngVel); 51 | catch 52 | warning('QP failed') 53 | obj.motorsAngVel = obj.motorsAngVel; 54 | end 55 | motorsAngVel = obj.motorsAngVel; 56 | 57 | end 58 | 59 | end 60 | 61 | methods (Access=protected) 62 | computeCostFunctionAndConstraints(obj) 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /pixi.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | authors = ["Fabio Bergonti "] 3 | # robotology channel is necessary as casadi-matlab-bindings are only available in the robotology channel, 4 | # conda-forge does not host matlab libraries 5 | channels = ["conda-forge", "robotology"] 6 | description = "Add a short description here" 7 | name = "paper_bergonti_2022_tro_kinematics-control-morphingcovers" 8 | platforms = ["win-64", "linux-64"] 9 | version = "0.0.0" 10 | 11 | [target.win.activation.env] 12 | CMAKE_INSTALL_PREFIX = "%CONDA_PREFIX%\\Library" 13 | # We need to add also the mystica mesh folder to MATLABPATH 14 | # See https://github.com/ami-iit/mystica/pull/4 15 | MATLABPATH = "%MATLABPATH%;%CONDA_PREFIX%\\Library\\mex\\+mystica\\meshes" 16 | 17 | [target.unix.activation.env] 18 | CMAKE_INSTALL_PREFIX = "$CONDA_PREFIX" 19 | # We need to add also the mystica mesh folder to MATLABPATH 20 | # See https://github.com/ami-iit/mystica/pull/4 21 | MATLABPATH = "$MATLABPATH;$CONDA_PREFIX/mex/+mystica/meshes" 22 | 23 | [tasks] 24 | # Download and install src deps (in this case a pure MATLAB library, mystica) 25 | download_src_deps = {cmd = "echo Download src deps && git lfs install && mkdir -p ./.pixi_ws/src && git clone https://github.com/ami-iit/mystica.git --branch v2022.06.0 ./.pixi_ws/src/mystica", outputs=[".pixi_ws/src/mystica/README.md"]} 26 | # We copy the +mystica MATLAB package to $CMAKE_INSTALL_PREFIX/mex as this directory is already part of MATLABPATH thanks to casadi-matlab-bindings activation scripts 27 | install_src_deps = {cmd = "echo Install src deps && cp -r ./.pixi_ws/src/mystica/+mystica $CMAKE_INSTALL_PREFIX/mex/+mystica && cp -r ./.pixi_ws/src/mystica/meshes $CMAKE_INSTALL_PREFIX/mex/+mystica/meshes", depends-on = "download_src_deps" } 28 | # If there is any problem, run uninstall_src_deps to uninstall the source dependencies 29 | cleanup_src_deps = {cmd = "echo Uninstall src deps && rm -rf $CMAKE_INSTALL_PREFIX/mex/+mystica && rm -rf ./.pixi_ws/src"} 30 | run_scripts = { cmd = "echo test", depends-on = "install_src_deps"} 31 | sim1 = {cmd = "matlab -nosplash -nodesktop -batch \"run('./scripts/sim1.m')\"", depends-on = "install_src_deps"} 32 | sim2 = {cmd = "matlab -nosplash -nodesktop -batch \"run('./scripts/sim2.m')\"", depends-on = "install_src_deps"} 33 | sim3 = {cmd = "matlab -nosplash -nodesktop -batch \"run('./scripts/sim3.m')\"", depends-on = "install_src_deps"} 34 | sim4 = {cmd = "matlab -nosplash -nodesktop -batch \"run('./scripts/sim4.m')\"", depends-on = "install_src_deps"} 35 | 36 | [dependencies] 37 | # The version of mystica installed is only compatible with casadi 3.5.* 38 | casadi-matlab-bindings = "3.5.*" 39 | # Ensure that we have git and git lfs as mystica uses git-lfs 40 | git = "*" 41 | git-lfs = "*" 42 | -------------------------------------------------------------------------------- /src/motor-positioning/@SensitivityAnalysis/SensitivityAnalysis.m: -------------------------------------------------------------------------------- 1 | classdef SensitivityAnalysis < handle 2 | %SENSITIVITYANALYSIS Summary of this class goes here 3 | % Detailed explanation goes here 4 | 5 | properties (SetAccess=protected,GetAccess=protected) 6 | stateKinMBody_iniConf 7 | stateKinMBody_endConf 8 | model 9 | population 10 | indexBestCandidate 11 | end 12 | properties (SetAccess=protected,GetAccess=public) 13 | stgs 14 | stats 15 | result 16 | end 17 | 18 | methods 19 | function obj = SensitivityAnalysis(input) 20 | arguments 21 | input.stateKinMBody 22 | input.model 23 | input.population 24 | input.desAngleVariation = 5*pi/180 25 | input.timeIncrement = 0.01 26 | input.kBaum = 0 27 | input.regTermDampPInv = 0 28 | end 29 | 30 | obj.model = copy(input.model); 31 | obj.population = input.population; 32 | 33 | obj.stateKinMBody_iniConf = copy(input.stateKinMBody); 34 | obj.stateKinMBody_endConf = copy(input.stateKinMBody); 35 | 36 | obj.stgs.desAngleVariation = input.desAngleVariation; 37 | obj.stgs.timeIncrement = input.timeIncrement; 38 | obj.stgs.desMotorsAngVel = obj.stgs.desAngleVariation/obj.stgs.timeIncrement; 39 | 40 | obj.stgs.numberCombinations = size(obj.population,1); 41 | obj.stgs.numberMotorConf = size(obj.population,2); 42 | 43 | obj.stgs.kBaum = input.kBaum; 44 | obj.stgs.regTermDampPInv = input.regTermDampPInv; 45 | 46 | obj.stgs.unitMeas = obj.model.unitMeas; 47 | 48 | obj.stats.dDeterminant_dAngle = zeros(obj.stgs.numberCombinations,2*obj.stgs.numberMotorConf); 49 | obj.stats.divergenceDeterminant = sum(abs(obj.stats.dDeterminant_dAngle),2); 50 | obj.stats.determinant_iniConf = zeros(obj.stgs.numberCombinations,1); 51 | end 52 | 53 | function clearProperties(obj) 54 | obj.stateKinMBody_iniConf = []; 55 | obj.stateKinMBody_endConf = []; 56 | obj.model = []; 57 | obj.population = []; 58 | obj.indexBestCandidate = []; 59 | end 60 | 61 | end 62 | 63 | methods (Static,Access=protected) 64 | function detA = getDeterminant(A) 65 | if size(A,1) == size(A,2) 66 | detA = det(A); 67 | else 68 | detA = 0; 69 | end 70 | end 71 | end 72 | 73 | end 74 | -------------------------------------------------------------------------------- /src/motor-positioning/@SensitivityAnalysis/runAlgorithm.m: -------------------------------------------------------------------------------- 1 | function runAlgorithm(obj) 2 | arguments 3 | obj 4 | end 5 | 6 | nameTTF = []; 7 | 8 | for indexCombination = 1 : obj.stgs.numberCombinations 9 | 10 | booleanActuatedJointAngVel = zeros(obj.model.constants.jointsAngVel,1); 11 | booleanActuatedJointAngVel(obj.population(indexCombination,:)) = 1; 12 | booleanActuatedJointAngVel = reshape(booleanActuatedJointAngVel,obj.model.constants.linkEul,[]); 13 | for j = 1:obj.model.nJoint 14 | obj.model.actuateJoint('jointIndex',j,'axesActuated',booleanActuatedJointAngVel(:,j),'byPassWarning',1); 15 | end 16 | 17 | Zact_iniConf = obj.stateKinMBody_iniConf.getZact('model',obj.model); 18 | obj.stats.determinant_iniConf(indexCombination,1) = obj.getDeterminant(Zact_iniConf); 19 | 20 | for indexDirection = 1 : 2*obj.stgs.numberMotorConf 21 | motorAngVel = zeros(obj.stgs.numberMotorConf,1); 22 | if indexDirection <= obj.stgs.numberMotorConf 23 | indexActuatedMotor = indexDirection; 24 | motorAngVel(indexActuatedMotor) = obj.stgs.desMotorsAngVel; 25 | else 26 | indexActuatedMotor=indexDirection-obj.stgs.numberMotorConf; 27 | motorAngVel(indexActuatedMotor) = -obj.stgs.desMotorsAngVel; 28 | end 29 | 30 | mBodyVelQuat_0 = obj.stateKinMBody_iniConf.get_mBodyVelQuat0_from_motorsAngVel(... 31 | 'motorsAngVel',motorAngVel,'model',obj.model,'kBaum',obj.stgs.kBaum,'regTermDampPInv',obj.stgs.regTermDampPInv); 32 | 33 | obj.stateKinMBody_endConf.setMBodyPosQuat('model',obj.model,... 34 | 'mBodyPosQuat_0',obj.stateKinMBody_iniConf.mBodyPosQuat_0 + mBodyVelQuat_0 * obj.stgs.timeIncrement) 35 | 36 | Zact_endConf = obj.stateKinMBody_endConf.getZact('model',obj.model); 37 | determinant_endConf = obj.getDeterminant(Zact_endConf); 38 | 39 | if obj.stats.determinant_iniConf(indexCombination,1) == 0 && determinant_endConf == 0 40 | obj.stats.dDeterminant_dAngle(indexCombination,indexDirection) = 1e5; 41 | else 42 | obj.stats.dDeterminant_dAngle(indexCombination,indexDirection) = (determinant_endConf - obj.stats.determinant_iniConf(indexCombination,1))/obj.stgs.desAngleVariation; 43 | end 44 | 45 | end 46 | if mod(indexCombination,round(obj.stgs.numberCombinations/100)) == 0 47 | fprintf('SA | Percentage of completion: %.0f%%\n',(indexCombination/obj.stgs.numberCombinations)*100); 48 | nameTTF = mystica.utils.createTimeTrackerFile(nameTTF,'SA',(indexCombination/obj.stgs.numberCombinations)*100,100); 49 | end 50 | end 51 | 52 | obj.stats.divergenceDeterminant = sum(abs(obj.stats.dDeterminant_dAngle),2); 53 | 54 | [~,obj.indexBestCandidate]=min(obj.stats.divergenceDeterminant); 55 | obj.result = obj.population(obj.indexBestCandidate,:); 56 | 57 | end 58 | -------------------------------------------------------------------------------- /src/controller/@ControllerKinAbs/computeCostFunctionAndConstraints.m: -------------------------------------------------------------------------------- 1 | function computeCostFunctionAndConstraints(obj,input) 2 | arguments 3 | obj 4 | input.model 5 | input.stateKinMBody 6 | end 7 | 8 | obj.csdSy.mBodyTwist_0 = obj.opti.variable(input.model.constants.mBodyTwist,1); 9 | obj.csdSy.mBodyTwist_0_lastSol = obj.opti.parameter(input.model.constants.mBodyTwist,1); 10 | 11 | Jc = input.stateKinMBody.csdFn.Jc(obj.csdSy.mBodyPosQuat_0); 12 | rC_from_mBodyTwist0_2_jointsAngVelPJ = input.stateKinMBody.csdFn.rC_from_mBodyTwist0_2_jointsAngVelPJ(obj.csdSy.mBodyPosQuat_0); 13 | 14 | mBodyAngVel_0 = input.model.selector.matrix_mBodyAngVel_from_mBodyTwist * obj.csdSy.mBodyTwist_0; 15 | jointsAngVel_pj = rC_from_mBodyTwist0_2_jointsAngVelPJ * obj.csdSy.mBodyTwist_0; 16 | 17 | %% Cost Function 18 | 19 | E1 = mBodyAngVel_0 - obj.csdFn.mBodyAngVelStar(obj.csdSy.mBodyPosQuat_0,obj.csdSy.time); 20 | 21 | E2 = obj.csdSy.mBodyTwist_0 - obj.csdSy.mBodyTwist_0_lastSol; 22 | 23 | obj.opti.minimize(transpose(E1)*E1*obj.stgsController.costFunction.weightTaskOrientation + ... 24 | transpose(E2)*E2*obj.stgsController.costFunction.weightTaskMinVariation); 25 | 26 | %% Jacobian of Constraints 27 | 28 | obj.opti.subject_to( Jc * obj.csdSy.mBodyTwist_0 == 0); 29 | 30 | %% Limit Angular velocity 31 | 32 | for j = 1 : input.model.nJoint 33 | vectorJointsAngVelLimit(input.model.joints{j}.selector.indexes_jAngVel_from_jointsAngVel,1) = input.model.joints{j}.limitJointVel; 34 | end 35 | 36 | obj.opti.subject_to(-vectorJointsAngVelLimit <= jointsAngVel_pj <= vectorJointsAngVelLimit) 37 | 38 | %% Limit Range of Motion 39 | 40 | contraintRoM.bLow = zeros(input.model.nJoint,1); 41 | contraintRoM.bUpp = zeros(input.model.nJoint,1); 42 | contraintRoM.versorsProduct = {}; 43 | 44 | e = [1;0;0]; 45 | 46 | for j = 1 : input.model.nJoint 47 | 48 | index = input.model.joints{j}.getJointConnectionDetails(); 49 | 50 | tform_0_p = input.stateKinMBody.linksState{index.parent}.csdFn.tform_0_b(obj.csdSy.mBodyPosQuat_0); 51 | tform_p_pj = input.model.linksAttributes{index.parent}.tform_b_j{index.cPointParent}; 52 | tform_0_pj = tform_0_p * tform_p_pj; 53 | tform_0_c = input.stateKinMBody.linksState{index.child }.csdFn.tform_0_b(obj.csdSy.mBodyPosQuat_0); 54 | tform_c_cj = input.model.linksAttributes{index.child }.tform_b_j{index.cPointChild }; 55 | tform_0_cj = tform_0_c * tform_c_cj; 56 | tform_pj_cj = transpose(tform_0_pj) * tform_0_cj; 57 | rotm_pj_cj = mystica.rbm.getRotmGivenTform(tform_pj_cj); 58 | 59 | indexes_jAngVel = input.model.joints{j}.selector.indexes_jAngVel_from_jointsAngVel; 60 | 61 | contraintRoM.versorsProduct{end+1} = transpose(e)*rotm_pj_cj*e - transpose(e)*mystica.utils.skew(rotm_pj_cj*e*obj.dt)*jointsAngVel_pj(indexes_jAngVel); 62 | 63 | contraintRoM.bLow(j) = -1; 64 | contraintRoM.bUpp(j) = -cos(input.model.joints{j}.limitRoM); 65 | 66 | end 67 | 68 | contraintRoM.versorsProduct = vertcat(contraintRoM.versorsProduct{:}); 69 | 70 | obj.opti.subject_to(contraintRoM.versorsProduct <= contraintRoM.bUpp) 71 | 72 | end 73 | -------------------------------------------------------------------------------- /scripts/test_ci.m: -------------------------------------------------------------------------------- 1 | %% Test CI - Mesh 3x3 2 | % 3 | % file: test_ci 4 | % authors: Fabio Bergonti 5 | % license: BSD 3-Clause 6 | 7 | %% Clear Workspace + MATLABPATH Configuration 8 | 9 | clear 10 | clc 11 | close all 12 | fclose('all'); 13 | 14 | src_full_path = fullfile(fileparts(mfilename('fullpath')),'..','src'); 15 | datasets_full_path = fullfile(fileparts(mfilename('fullpath')),'..','datasets'); 16 | run(fullfile(src_full_path,'setup_sim.m')) 17 | 18 | %% Prepare Morphing Cover Model with Motors and its Initial Configuration 19 | fprintf(' ========= script TEST_CI ========= \n') 20 | fprintf('- script TEST_CI: start\n') 21 | 22 | % 1) create model. 23 | fprintf('- script TEST_CI: creating model\n') 24 | model = mystica.model.getModelCoverSquareLinks('n',3,'m',3,'restConfiguration','flat','linkDimension',0.0482); 25 | % 2) evaluate morphing cover initial configuration. 26 | % initial configuration is computed running a controlled simulation starting from flat configuration. `mBodyTwist_0` is the control variable. 27 | fprintf('- script TEST_CI: evaluating initial configuration\n') 28 | stgs = mystica.stgs.getDefaultSettingsSimKinAbs(model,'stgs_integrator_limitMaximumTime',4); 29 | stgs.desiredShape.fun = @(x,y,t) -5*x.^2 -5*y.^2; 30 | [data,stateKin] = mystica.runSimKinAbs('model',model,'mBodyPosQuat_0',model.getMBodyPosQuatRestConfiguration,'stgs',stgs,'nameControllerClass','ControllerKinAbs'); 31 | % 3) solve the motors placement problem. 32 | fprintf('- script TEST_CI: solving motors placement problem\n') 33 | [model,sensitivity,genAlgrthm] = selectMotorPositioning('model',model,'state',stateKin,'stgs',stgs); 34 | mBodyPosQuat_0 = data.mBodyPosQuat_0(:,end); 35 | 36 | % Verify result motors placement problem 37 | assert(abs(det(stateKin.getZact('model',model)))>1e-5,'selected motor placement doesn''t guarantee full actuation locally') 38 | 39 | %% Simulation 40 | 41 | fprintf('- script TEST_CI: simulating the kinematics\n') 42 | 43 | % stgs: get default values 44 | stgs = mystica.stgs.getDefaultSettingsSimKinRel(model,'startFile',stgs.saving.workspace.name,'stgs_integrator_limitMaximumTime',6); 45 | % stgs: controller parameters 46 | stgs.controller.costFunction.weightTaskOrientation = 1; 47 | stgs.controller.costFunction.weightTaskMinVariation = 0; 48 | stgs.controller.costFunction.weightTaskMinOptiVar = 0; 49 | stgs.controller.costFunction.gainLinkAngVelStarAligned = 30; 50 | stgs.controller.costFunction.gainLinkAngVelStarOpposite = 100; 51 | stgs.controller.costFunction.useFeedForwardTermLinkAngVelStar = 1; 52 | stgs.controller.constraints.limitPassiveAngVel = 5*pi/180; % [rad/s] it can be set up to model limit (i.e. 20*180/pi). 53 | stgs.controller.constraints.limitMotorVel = 5*pi/180; % [rad/s] it can be set up to model limit (i.e. 20*180/pi). 54 | stgs.controller.constraints.limitRoM = 50*pi/180; % [rad] it can be set up to model limit (i.e. 50*180/pi). 55 | % stgs: desired Shape 56 | stgs.desiredShape.fun = @(x,y,t) 5.*x.*y.*cos(y/2); 57 | 58 | % run simulation 59 | data = mystica.runSimKinRel('model',model,'stgs',stgs,'mBodyPosQuat_0',mBodyPosQuat_0,'nameControllerClass','ControllerKinRel'); 60 | 61 | % Verify results kinematic simulation 62 | assert(max(abs(data.errorPositionNormals(:,end)))<1e-2,'errorPositionNormals is bigger than expected') 63 | assert(max(abs(data.errorOrientationNormals(:,end)))<10,'errorOrientationNormals is bigger than expected') 64 | 65 | fprintf(' ========= TEST_CI ended ========= \n') 66 | -------------------------------------------------------------------------------- /src/motor-positioning/selectMotorPositioning.m: -------------------------------------------------------------------------------- 1 | function [model,sensitivity,genAlgrthm] = selectMotorPositioning(input) 2 | arguments 3 | input.model mystica.model.Model 4 | input.state 5 | input.stgs 6 | input.GA_probabilityMutation (1,1) double = 0.01 7 | input.GA_probabilityCrossover (1,1) double = 0.6 8 | input.GA_populationSize (1,1) double = 100 9 | input.GA_populationRatioChildrenOverParents (1,1) double = 1 10 | input.GA_limitGenerationNumber (1,1) double = 1e5 11 | input.GA_limitCounterConstantPopulation (1,1) double = 1e3 12 | input.GA_thresholdFitValues (1,1) logical = true 13 | input.GA_populationWithDuplicates (1,1) logical = false 14 | input.SA_desAngleVariation (1,1) double = 5*pi/180; 15 | input.SA_timeIncrement (1,1) double = 0.01; 16 | end 17 | 18 | model = input.model; 19 | stateKin = copy(input.state); 20 | stgs = input.stgs; 21 | 22 | %% GA 23 | 24 | candidateApproachQR.combination = mystica.utils.findLinearIndipendentRows_algorithmQR(stateKin.nullJc_jointsAngVel_PJ,size(stateKin.nullJc_jointsAngVel_PJ,2)); 25 | candidateApproachQR.determinant = abs(det(stateKin.nullJc_jointsAngVel_PJ(candidateApproachQR.combination,:))); 26 | 27 | % Fitness Function 28 | 29 | fitnessFunction = @(x) abs(det(stateKin.nullJc_jointsAngVel_PJ(x,:))) + eps + ... 30 | (abs(det(stateKin.nullJc_jointsAngVel_PJ(x,:))) > candidateApproachQR.determinant/10) * ... 31 | (sum(diff(ceil(x/model.constants.linkAngVel))==0)+1)^-1; 32 | 33 | % Settings 34 | 35 | genAlgrthm = GeneticAlgorithm(... 36 | 'probabilityMutation',input.GA_probabilityMutation,... 37 | 'probabilityCrossover',input.GA_probabilityCrossover,... 38 | 'populationSize',input.GA_populationSize,... 39 | 'populationRatioChildrenOverParents',input.GA_populationRatioChildrenOverParents,... 40 | 'limitGenerationNumber',input.GA_limitGenerationNumber,... 41 | 'limitCounterConstantPopulation',input.GA_limitCounterConstantPopulation,... 42 | 'thresholdFitValues',input.GA_thresholdFitValues,... 43 | 'fitnessFunction',fitnessFunction,... 44 | 'populationWithDuplicates',input.GA_populationWithDuplicates,... 45 | 'initialGuessDec',candidateApproachQR.combination,... 46 | 'combinationDecLength',size(stateKin.nullJc_jointsAngVel_PJ,2),... 47 | 'combinationDecRange',[1 size(stateKin.nullJc_jointsAngVel_PJ,1)]); 48 | 49 | genAlgrthm.runAlgorithm() 50 | 51 | %% Sensitivity Analysis 52 | 53 | sensitivity = SensitivityAnalysis(... 54 | 'desAngleVariation',input.SA_desAngleVariation,... 55 | 'timeIncrement',input.SA_timeIncrement,... 56 | 'model',model,... 57 | 'stateKinMBody',stateKin,... 58 | 'population',genAlgrthm.population.combinationDec,... 59 | 'kBaum',stgs.integrator.dxdtParam.baumgarteIntegralCoefficient,... 60 | 'regTermDampPInv',0); 61 | 62 | sensitivity.runAlgorithm() 63 | 64 | %% Update model 65 | 66 | booleanActuatedJointAngVel = zeros(model.constants.jointsAngVel,1); 67 | booleanActuatedJointAngVel(sensitivity.result) = 1; 68 | booleanActuatedJointAngVel = reshape(booleanActuatedJointAngVel,model.constants.linkEul,[]); 69 | for j = 1:model.nJoint 70 | model.actuateJoint('jointIndex',j,'axesActuated',booleanActuatedJointAngVel(:,j),'byPassWarning',1); 71 | end 72 | 73 | %% Saving 74 | 75 | if stgs.saving.workspace.clearCasadi 76 | stateKin.clearProperties(); 77 | end 78 | sensitivity.clearProperties(); 79 | if stgs.saving.workspace.run 80 | stgs.saving.workspace.name = [stgs.saving.workspace.name(1:end-4),'_motorPos.mat']; 81 | save(stgs.saving.workspace.name) 82 | end 83 | 84 | end 85 | -------------------------------------------------------------------------------- /scripts/sim3.m: -------------------------------------------------------------------------------- 1 | %% Simulation 3 - Mesh 20x20 2 | % 3 | % file: sim3 4 | % authors: Fabio Bergonti 5 | % license: BSD 3-Clause 6 | 7 | %% Clear Workspace + MATLABPATH Configuration 8 | 9 | clear 10 | clc 11 | close all 12 | fclose('all'); 13 | 14 | src_full_path = fullfile(fileparts(mfilename('fullpath')),'..','src'); 15 | datasets_full_path = fullfile(fileparts(mfilename('fullpath')),'..','datasets'); 16 | run(fullfile(src_full_path,'setup_sim.m')) 17 | 18 | %% User Parameters 19 | 20 | % config.run_only_controller 21 | % - true => load model with motors and its initial configuration. 22 | % WARNING! if this option is true, the running time is ~2h with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB. 23 | % - false => create model, evaluate the initial configuration, and solve the motors placement problem. 24 | % WARNING! if this option is false, the running time is ~25h with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB. 25 | config.run_only_controller = true; 26 | 27 | %% Prepare Morphing Cover Model with Motors and its Initial Configuration 28 | fprintf(' ========= script SIM3 ========= \n') 29 | 30 | if config.run_only_controller 31 | fprintf('- script SIM3: start (running time is ~2h with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB)\n') 32 | % load model with motors and morphing cover initial configuration. 33 | fprintf('- script SIM3: loading model\n') 34 | load(fullfile(datasets_full_path,'initSim3.mat'),'model','mBodyPosQuat_0') 35 | stgs.saving.workspace.name = 'initSim3'; 36 | else 37 | fprintf('- script SIM3: start (running time is ~25h with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB)\n') 38 | % 1) create model. 39 | fprintf('- script SIM3: creating model\n') 40 | model = mystica.model.getModelCoverSquareLinks('n',20,'m',20,'restConfiguration','flat','linkDimension',0.0482); 41 | % 2) evaluate morphing cover initial configuration. 42 | % initial configuration is computed running a controlled simulation starting from flat configuration. `mBodyTwist_0` is the control variable. 43 | fprintf('- script SIM3: evaluating initial configuration\n') 44 | stgs = mystica.stgs.getDefaultSettingsSimKinAbs(model,'stgs_integrator_limitMaximumTime',4); 45 | stgs.desiredShape.fun = @(x,y,t) 2*(x-23/50).^2-529/1250; 46 | [data,stateKin] = mystica.runSimKinAbs('model',model,'mBodyPosQuat_0',model.getMBodyPosQuatRestConfiguration,'stgs',stgs,'nameControllerClass','ControllerKinAbs'); 47 | if stgs.visualizer.run 48 | mystica.viz.visualizeKinAbs('model',model,'data',data,'stgs',stgs); 49 | end 50 | % 3) solve the motors placement problem. 51 | fprintf('- script SIM3: solving motors placement problem\n') 52 | [model,sensitivity,genAlgrthm] = selectMotorPositioning('model',model,'state',stateKin,'stgs',stgs,'GA_limitGenerationNumber',1e7); 53 | mBodyPosQuat_0 = data.mBodyPosQuat_0(:,end); 54 | end 55 | 56 | %% Simulation 57 | 58 | fprintf('- script SIM3: simulating the kinematics\n') 59 | 60 | % stgs: get default values 61 | stgs = mystica.stgs.getDefaultSettingsSimKinRel(model,'startFile',stgs.saving.workspace.name,'stgs_integrator_limitMaximumTime',20); 62 | % stgs: controller parameters 63 | stgs.controller.costFunction.weightTaskOrientation = 1; 64 | stgs.controller.costFunction.weightTaskMinVariation = 0; 65 | stgs.controller.costFunction.weightTaskMinOptiVar = 0; 66 | stgs.controller.costFunction.gainLinkAngVelStarAligned = 30; 67 | stgs.controller.costFunction.gainLinkAngVelStarOpposite = 100; 68 | stgs.controller.costFunction.useFeedForwardTermLinkAngVelStar = 1; 69 | stgs.controller.constraints.limitPassiveAngVel = 5*pi/180; % [rad/s] it can be set up to model limit (i.e. 20*180/pi). 70 | stgs.controller.constraints.limitMotorVel = 5*pi/180; % [rad/s] it can be set up to model limit (i.e. 20*180/pi). 71 | stgs.controller.constraints.limitRoM = 50*pi/180; % [rad] it can be set up to model limit (i.e. 50*180/pi). 72 | % stgs: desired Shape 73 | stgs.desiredShape.fun = @(x,y,t) (y/sqrt(2)-x/sqrt(2)+23/50).^2/2 - (x/sqrt(2)+y/sqrt(2)+23/50).^2/2; 74 | 75 | % stgs: visualizer 76 | stgs.visualizer.origin.dimCSYS = 0.01; 77 | stgs.visualizer.cameraView.mBodySimulation.values = [230,40]; 78 | stgs.visualizer.cameraView.initialRotation.run = 1; 79 | stgs.visualizer.cameraView.initialRotation.values = [180,90]; 80 | stgs.visualizer.cameraView.finalRotation.run = 1; 81 | stgs.visualizer.cameraView.finalRotation.values = [-37.5,30]; 82 | 83 | % run simulation 84 | data = mystica.runSimKinRel('model',model,'stgs',stgs,'mBodyPosQuat_0',mBodyPosQuat_0,'nameControllerClass','ControllerKinRel'); 85 | 86 | % visualize simulation 87 | if stgs.visualizer.run 88 | fprintf('- script SIM3: running visualizer\n') 89 | mystica.viz.visualizeKinRel('model',model,'data',data,'stgs',stgs); 90 | end 91 | 92 | fprintf(' ========= SIM3 ended ========= \n') 93 | -------------------------------------------------------------------------------- /src/controller/@ControllerKinRel/computeCostFunctionAndConstraints.m: -------------------------------------------------------------------------------- 1 | function computeCostFunctionAndConstraints(obj,input) 2 | arguments 3 | obj 4 | input.model 5 | input.stateKinMBody 6 | end 7 | 8 | obj.csdSy.motorsAngVel = obj.opti.variable( input.model.constants.motorsAngVel,1); 9 | obj.csdSy.motorsAngVel_lastSol = obj.opti.parameter(input.model.constants.motorsAngVel,1); 10 | 11 | obj.csdSy.nullJc_mBodyTwist_0 = obj.opti.parameter(input.model.constants.mBodyTwist,input.model.constants.motorsAngVel); 12 | obj.csdSy.invZact = obj.opti.parameter(input.model.constants.motorsAngVel,input.model.constants.motorsAngVel); 13 | 14 | rC_from_mBodyTwist0_2_jointsAngVelPJ = input.stateKinMBody.csdFn.rC_from_mBodyTwist0_2_jointsAngVelPJ(obj.csdSy.mBodyPosQuat_0); 15 | 16 | nullJc_jointsAngVel_PJ = rC_from_mBodyTwist0_2_jointsAngVelPJ * obj.csdSy.nullJc_mBodyTwist_0; 17 | 18 | mBodyTwist_0 = obj.csdSy.nullJc_mBodyTwist_0 * obj.csdSy.invZact * obj.csdSy.motorsAngVel; 19 | jointsAngVel_pj = nullJc_jointsAngVel_PJ * obj.csdSy.invZact * obj.csdSy.motorsAngVel; 20 | mBodyAngVel_0 = input.model.selector.matrix_mBodyAngVel_from_mBodyTwist * mBodyTwist_0; 21 | passiveAngVel_pj = jointsAngVel_pj(input.model.selector.indexes_passiveAngVel_from_jointsAngVel); 22 | 23 | %% Cost Function 24 | 25 | E1 = mBodyAngVel_0 - obj.csdFn.mBodyAngVelStar(obj.csdSy.mBodyPosQuat_0,obj.csdSy.time); 26 | 27 | E2 = obj.csdSy.motorsAngVel - obj.csdSy.motorsAngVel_lastSol; 28 | 29 | E3 = transpose(obj.csdSy.motorsAngVel)*obj.csdSy.motorsAngVel; 30 | 31 | obj.opti.minimize(... 32 | transpose(E1)*E1 * obj.stgsController.costFunction.weightTaskOrientation + ... 33 | transpose(E2)*E2 * obj.stgsController.costFunction.weightTaskMinVariation + ... 34 | transpose(E3)*E3 * obj.stgsController.costFunction.weightTaskMinOptiVar); 35 | 36 | %% Limit Angular velocity 37 | 38 | if obj.stgsController.constraints.byPassModelLimits 39 | kModelLimit = inf; 40 | else 41 | kModelLimit = 1; 42 | end 43 | 44 | for j = 1 : input.model.nJoint 45 | vectorJointsAngVelLimit(input.model.joints{j}.selector.indexes_jAngVel_from_jointsAngVel,1) = min(... 46 | input.model.joints{j}.limitJointVel*kModelLimit , ... 47 | obj.stgsController.constraints.limitMotorVel * input.model.joints{j}.axesActuated + ... 48 | obj.stgsController.constraints.limitPassiveAngVel * (input.model.joints{j}.axesRotation & ~input.model.joints{j}.axesActuated)); 49 | end 50 | 51 | vectorMotorsAngVelLimit = vectorJointsAngVelLimit(input.model.selector.indexes_motorsAngVel_from_jointsAngVel); 52 | obj.opti.subject_to(-vectorMotorsAngVelLimit <= obj.csdSy.motorsAngVel <= vectorMotorsAngVelLimit) 53 | 54 | vectorPassiveAngVelLimit = vectorJointsAngVelLimit(input.model.selector.indexes_passiveAngVel_from_jointsAngVel); 55 | if size(passiveAngVel_pj,1)>0 56 | obj.opti.subject_to(-vectorPassiveAngVelLimit <= passiveAngVel_pj <= vectorPassiveAngVelLimit) 57 | else 58 | warning('no passive joint') 59 | end 60 | 61 | %% Limit Range of Motion 62 | 63 | contraintRoM.bLow = zeros(input.model.nJoint,1); 64 | contraintRoM.bUpp = zeros(input.model.nJoint,1); 65 | contraintRoM.versorsProduct = {}; 66 | 67 | e = [1;0;0]; 68 | 69 | for j = 1 : input.model.nJoint 70 | 71 | limitRoM = min(input.model.joints{j}.limitRoM*kModelLimit , obj.stgsController.constraints.limitRoM); 72 | 73 | index = input.model.joints{j}.getJointConnectionDetails(); 74 | 75 | tform_0_p = input.stateKinMBody.linksState{index.parent}.csdFn.tform_0_b(obj.csdSy.mBodyPosQuat_0); 76 | tform_p_pj = input.model.linksAttributes{index.parent}.tform_b_j{index.cPointParent}; 77 | tform_0_pj = tform_0_p * tform_p_pj; 78 | tform_0_c = input.stateKinMBody.linksState{index.child }.csdFn.tform_0_b(obj.csdSy.mBodyPosQuat_0); 79 | tform_c_cj = input.model.linksAttributes{index.child }.tform_b_j{index.cPointChild }; 80 | tform_0_cj = tform_0_c * tform_c_cj; 81 | tform_pj_cj = transpose(tform_0_pj) * tform_0_cj; 82 | rotm_pj_cj = mystica.rbm.getRotmGivenTform(tform_pj_cj); 83 | 84 | indexes_jAngVel = input.model.joints{j}.selector.indexes_jAngVel_from_jointsAngVel; 85 | 86 | contraintRoM.versorsProduct{end+1} = transpose(e)*rotm_pj_cj*e - transpose(e)*mystica.utils.skew(rotm_pj_cj*e*obj.dt)*jointsAngVel_pj(indexes_jAngVel); 87 | 88 | contraintRoM.bLow(j) = -1; 89 | contraintRoM.bUpp(j) = -cos(limitRoM); 90 | 91 | end 92 | 93 | contraintRoM.versorsProduct = vertcat(contraintRoM.versorsProduct{:}); 94 | 95 | 96 | obj.opti.subject_to(contraintRoM.versorsProduct <= contraintRoM.bUpp) 97 | 98 | end 99 | -------------------------------------------------------------------------------- /src/motor-positioning/@GeneticAlgorithm/GeneticAlgorithm.m: -------------------------------------------------------------------------------- 1 | classdef GeneticAlgorithm < handle 2 | %GENETICALGORITHM Summary of this class goes here 3 | % Detailed explanation goes here 4 | 5 | properties (SetAccess=immutable,GetAccess=public) 6 | stgs 7 | combinationDecLength 8 | combinationDecRange 9 | fitnessFunction 10 | end 11 | properties (SetAccess=protected,GetAccess=public) 12 | population 13 | stats 14 | indexGen = 1 15 | endCondition 16 | end 17 | properties (SetAccess=protected,GetAccess=protected) 18 | children 19 | combinationBinGeneLength 20 | combinationBinLength 21 | initialGuessDec 22 | counterConstantPopulation = 0 23 | time 24 | end 25 | properties (SetAccess=private,GetAccess=private) 26 | matrixFromBinaryNumber2DecimalNumber 27 | matrixFromCombinationBin2CombinationDec 28 | end 29 | 30 | methods 31 | function obj = GeneticAlgorithm(input) 32 | arguments 33 | input.probabilityCrossover = 0.6 34 | input.probabilityMutation = 0.01 35 | input.populationWithDuplicates logical = 0 36 | input.limitGenerationNumber = 1e2 37 | input.limitCounterConstantPopulation = 5e1 38 | input.thresholdFitValues 39 | input.populationSize = 10 40 | input.populationRatioChildrenOverParents = 1 41 | input.combinationDecLength 42 | input.combinationDecRange (2,1) double 43 | input.fitnessFunction 44 | input.initialGuessDec = [] 45 | end 46 | 47 | obj.time = tic; 48 | 49 | obj.stgs.probabilityCrossover = input.probabilityCrossover; 50 | obj.stgs.probabilityMutation = input.probabilityMutation; 51 | obj.stgs.populationWithDuplicates = input.populationWithDuplicates; 52 | obj.stgs.populationSize.parents = input.populationSize; 53 | obj.stgs.populationSize.children = floor(input.populationSize*input.populationRatioChildrenOverParents/2)*2; 54 | 55 | obj.endCondition.limitGenerationNumber = input.limitGenerationNumber; 56 | obj.endCondition.limitCounterConstantPopulation = input.limitCounterConstantPopulation; 57 | obj.endCondition.thresholdFitValues = input.thresholdFitValues; 58 | 59 | obj.combinationDecLength = input.combinationDecLength; 60 | obj.combinationDecRange = sort(input.combinationDecRange); 61 | obj.fitnessFunction = input.fitnessFunction; 62 | obj.initialGuessDec = input.initialGuessDec; 63 | 64 | obj.combinationBinGeneLength = ceil(log2(obj.combinationDecRange(2))); 65 | obj.combinationBinLength = obj.combinationBinGeneLength * obj.combinationDecLength; 66 | 67 | obj.matrixFromBinaryNumber2DecimalNumber = 2.^((obj.combinationBinGeneLength - 1) : -1 : 0); 68 | 69 | obj.matrixFromCombinationBin2CombinationDec = zeros(obj.combinationDecLength,obj.combinationBinLength); 70 | for i = 1 : obj.combinationDecLength 71 | obj.matrixFromCombinationBin2CombinationDec(i,(1:obj.combinationBinGeneLength)+(i-1)*obj.combinationBinGeneLength) = obj.matrixFromBinaryNumber2DecimalNumber; 72 | end 73 | 74 | obj.population.combinationBin = zeros(obj.stgs.populationSize.parents,obj.combinationBinLength); 75 | obj.population.combinationDec = zeros(obj.stgs.populationSize.parents,obj.combinationDecLength); 76 | obj.population.fitValues = zeros(obj.stgs.populationSize.parents,1); 77 | obj.population.probabilityOfSelection = zeros(obj.stgs.populationSize.parents,1); 78 | 79 | obj.children.combinationBin = zeros(obj.stgs.populationSize.children,obj.combinationBinLength); 80 | obj.children.combinationDec = zeros(obj.stgs.populationSize.children,obj.combinationDecLength); 81 | obj.children.parentsIndexes = zeros(obj.stgs.populationSize.children,1); 82 | obj.children.fitValues = zeros(obj.stgs.populationSize.children,1); 83 | 84 | obj.createPopulation(); 85 | 86 | end 87 | 88 | runAlgorithm(obj,input) 89 | plotStatsFitValues(obj) 90 | end 91 | 92 | methods (Access=protected) 93 | 94 | numDec = getDecimalNumber(obj,numBin); 95 | combinationDec = getDecimalCombination(obj,combinationBin); 96 | combinationBin = getBinaryCombination(obj,combinationDec); 97 | populationDec = getDecimalPopulation(obj,populationBin); 98 | 99 | mergePopulations(obj,pop1,pop2) 100 | createPopulation(obj) 101 | updateProbabilityOfSelection(obj) 102 | selectParents(obj) 103 | performSinglePointCrossover(obj) 104 | performMutation(obj) 105 | updateFitValues(obj) 106 | getStats(obj,phase) 107 | 108 | end 109 | end 110 | -------------------------------------------------------------------------------- /scripts/sim4.m: -------------------------------------------------------------------------------- 1 | %% Simulation 4 - Mesh 4x8 2 | % 3 | % file: sim4 4 | % authors: Fabio Bergonti 5 | % license: BSD 3-Clause 6 | 7 | %% Clear Workspace + MATLABPATH Configuration 8 | 9 | clear 10 | clc 11 | close all 12 | fclose('all'); 13 | 14 | src_full_path = fullfile(fileparts(mfilename('fullpath')),'..','src'); 15 | datasets_full_path = fullfile(fileparts(mfilename('fullpath')),'..','datasets'); 16 | run(fullfile(src_full_path,'setup_sim.m')) 17 | 18 | %% User Parameters 19 | 20 | % config.run_only_controller 21 | % - true => load model with motors and its initial configuration. 22 | % if this option is true, the running time is ~1min with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB. 23 | % - false => create model, evaluate the initial configuration, and solve the motors placement problem. 24 | % if this option is false, the running time is ~3min with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB. 25 | config.run_only_controller = false; 26 | 27 | %% Prepare Morphing Cover Model with Motors and its Initial Configuration 28 | fprintf(' ========= script SIM4 ========= \n') 29 | fprintf('- script SIM4: start\n') 30 | 31 | if config.run_only_controller 32 | % load model with motors and morphing cover initial configuration. 33 | fprintf('- script SIM4: loading model\n') 34 | load(fullfile(datasets_full_path,'initSim4.mat'),'model','mBodyPosQuat_0') 35 | stgs.saving.workspace.name = 'initSim4'; 36 | else 37 | % 1) create model and state object. 38 | fprintf('- script SIM4: creating model\n') 39 | model = mystica.model.getModelCoverSquareLinks('n',4,'m',8,'restConfiguration','cylinder','linkDimension',0.0460,'baseIndex',5,'fixedLinksIndexes',[5,13,21,29],'tform_0_bBase',mystica.rbm.getTformGivenPosRotm([0 0 0.0555]',mystica.rbm.getRotmGivenEul('rz',pi/2))); 40 | % 2) evaluate morphing cover initial configuration. 41 | fprintf('- script SIM4: evaluating initial configuration\n') 42 | stgs = mystica.stgs.getDefaultSettingsSimKinAbs(model,'stgs_integrator_limitMaximumTime',0.02); 43 | stgs.desiredShape.fun = @(x,y,t) 2*x.^2 + 2*y.^2; 44 | [data,stateKin] = mystica.runSimKinAbs('model',model,'mBodyPosQuat_0',model.getMBodyPosQuatRestConfiguration,'stgs',stgs,'nameControllerClass','ControllerKinAbs'); 45 | % 3) solve the motors placement problem. 46 | fprintf('- script SIM4: solving motors placement problem\n') 47 | [model,sensitivity,genAlgrthm] = selectMotorPositioning('model',model,'state',stateKin,'stgs',stgs); 48 | mBodyPosQuat_0 = data.mBodyPosQuat_0(:,end); 49 | end 50 | 51 | %% Simulation 52 | 53 | fprintf('- script SIM4: simulating the kinematics\n') 54 | 55 | % stgs: get default values 56 | stgs = mystica.stgs.getDefaultSettingsSimKinRel(model,'startFile',stgs.saving.workspace.name,'stgs_integrator_limitMaximumTime',35); 57 | % stgs: controller parameters 58 | stgs.controller.costFunction.weightTaskOrientation = 1; 59 | stgs.controller.costFunction.weightTaskMinVariation = 500; 60 | stgs.controller.costFunction.weightTaskMinOptiVar = 0; 61 | stgs.controller.costFunction.gainLinkAngVelStarAligned = 30; 62 | stgs.controller.costFunction.gainLinkAngVelStarOpposite = 100; 63 | stgs.controller.costFunction.useFeedForwardTermLinkAngVelStar = 1; 64 | stgs.controller.constraints.limitPassiveAngVel = 5*pi/180; % [rad/s] it can be set up to model limit (i.e. 20*180/pi). 65 | stgs.controller.constraints.limitMotorVel = 5*pi/180; % [rad/s] it can be set up to model limit (i.e. 20*180/pi). 66 | stgs.controller.constraints.limitRoM = 50*pi/180; % [rad] it can be set up 67 | % stgs: desired Shape 68 | f1 = @(x,y) 3*(x-0.07).^2-3*(y).^2; t1 = 10; 69 | f2 = @(x,y) 7*(x-0.07).^2; t2 = 15; 70 | f3 = @(x,y) 3*(y.^2); t3 = 25; 71 | f4 = @(x,y) -3.5*(y.^2); 72 | stgs.desiredShape.fun = @(x,y,t) (t<=t1)*f1(x,y) + (t>t1 & t<=t2)*f2(x,y) + (t>t2 & t<=t3)*f3(x,y) + (t>t3)*f4(x,y); 73 | stgs.desiredShape.fun = @(x,y,t) stgs.desiredShape.fun(x,y,t)-stgs.desiredShape.fun(0,0,t)+0.055; clear f1 f2 f3 f4 t1 t2 t3; 74 | % stgs: visualizer 75 | stgs.visualizer.origin.dimCSYS = 0.01; 76 | stgs.visualizer.cameraView.mBodySimulation.values = [230,40]; 77 | stgs.visualizer.cameraView.initialRotation.run = 1; 78 | stgs.visualizer.cameraView.initialRotation.values = [0,90]; 79 | stgs.visualizer.cameraView.finalRotation.run = 1; 80 | stgs.visualizer.cameraView.finalRotation.values = [90,0]; 81 | stgs.visualizer.background{1}.stlName = 'iRonCub_Leg.stl'; 82 | stgs.visualizer.background{1}.tform_0_originSTL = mystica.rbm.getTformGivenPosRotm(zeros(3,1),mystica.rbm.getRotmGivenEul('rx',0)); 83 | stgs.visualizer.background{1}.scale = [1 1 1]/1e3; 84 | stgs.visualizer.background{1}.FaceColor = [0.7 0.7 0.7]; 85 | stgs.visualizer.background{1}.EdgeColor = 'none'; 86 | stgs.visualizer.background{1}.FaceAlpha = 0.3; 87 | 88 | % run simulation 89 | data = mystica.runSimKinRel('model',model,'stgs',stgs,'mBodyPosQuat_0',mBodyPosQuat_0,'nameControllerClass','ControllerKinRel'); 90 | 91 | % visualize simulation 92 | if stgs.visualizer.run 93 | fprintf('- script SIM4: running visualizer\n') 94 | mystica.viz.visualizeKinRel('model',model,'data',data,'stgs',stgs); 95 | end 96 | 97 | fprintf(' ========= SIM4 ended ========= \n') 98 | -------------------------------------------------------------------------------- /scripts/sim1.m: -------------------------------------------------------------------------------- 1 | %% Simulation 1 - Mesh 3x3 2 | % 3 | % file: sim1 4 | % authors: Fabio Bergonti 5 | % license: BSD 3-Clause 6 | 7 | %% Clear Workspace + MATLABPATH Configuration 8 | 9 | clear 10 | clc 11 | close all 12 | fclose('all'); 13 | 14 | src_full_path = fullfile(fileparts(mfilename('fullpath')),'..','src'); 15 | datasets_full_path = fullfile(fileparts(mfilename('fullpath')),'..','datasets'); 16 | run(fullfile(src_full_path,'setup_sim.m')) 17 | 18 | %% User Parameters 19 | 20 | % config.simulation_with_noise 21 | % - true => simulation with Gaussian noise to motor velocity 22 | % - false => ideal simulation 23 | config.simulation_with_noise = false; 24 | 25 | % config.run_only_controller 26 | % - true => load model with motors and its initial configuration. 27 | % if this option is true, the running time is ~10s with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB. 28 | % - false => create model, evaluate the initial configuration, and solve the motors placement problem. 29 | % if this option is false, the running time is ~30s with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB. 30 | config.run_only_controller = false; 31 | 32 | %% Prepare Morphing Cover Model with Motors and its Initial Configuration 33 | fprintf(' ========= script SIM1 ========= \n') 34 | fprintf('- script SIM1: start\n') 35 | 36 | if config.run_only_controller 37 | % load model with motors and morphing cover initial configuration. 38 | fprintf('- script SIM1: loading model\n') 39 | load(fullfile(datasets_full_path,'initSim1.mat'),'model','mBodyPosQuat_0') 40 | stgs.saving.workspace.name = 'initSim1'; 41 | else 42 | % 1) create model. 43 | fprintf('- script SIM1: creating model\n') 44 | model = mystica.model.getModelCoverSquareLinks('n',3,'m',3,'restConfiguration','flat','linkDimension',0.0482); 45 | % 2) evaluate morphing cover initial configuration. 46 | % initial configuration is computed running a controlled simulation starting from flat configuration. `mBodyTwist_0` is the control variable. 47 | fprintf('- script SIM1: evaluating initial configuration\n') 48 | stgs = mystica.stgs.getDefaultSettingsSimKinAbs(model,'stgs_integrator_limitMaximumTime',4); 49 | stgs.desiredShape.fun = @(x,y,t) -5*x.^2 -5*y.^2; 50 | [data,stateKin] = mystica.runSimKinAbs('model',model,'mBodyPosQuat_0',model.getMBodyPosQuatRestConfiguration,'stgs',stgs,'nameControllerClass','ControllerKinAbs'); 51 | if stgs.visualizer.run 52 | mystica.viz.visualizeKinAbs('model',model,'data',data,'stgs',stgs); 53 | end 54 | % 3) solve the motors placement problem. 55 | fprintf('- script SIM1: solving motors placement problem\n') 56 | [model,sensitivity,genAlgrthm] = selectMotorPositioning('model',model,'state',stateKin,'stgs',stgs); 57 | mBodyPosQuat_0 = data.mBodyPosQuat_0(:,end); 58 | end 59 | 60 | %% Simulation 61 | 62 | fprintf('- script SIM1: simulating the kinematics\n') 63 | 64 | % stgs: get default values 65 | stgs = mystica.stgs.getDefaultSettingsSimKinRel(model,'startFile',stgs.saving.workspace.name,'stgs_integrator_limitMaximumTime',8); 66 | % stgs: controller parameters 67 | stgs.controller.costFunction.weightTaskOrientation = 1; 68 | stgs.controller.costFunction.weightTaskMinVariation = 0; 69 | stgs.controller.costFunction.weightTaskMinOptiVar = 0; 70 | stgs.controller.costFunction.gainLinkAngVelStarAligned = 30; 71 | stgs.controller.costFunction.gainLinkAngVelStarOpposite = 100; 72 | stgs.controller.costFunction.useFeedForwardTermLinkAngVelStar = 1; 73 | stgs.controller.constraints.limitPassiveAngVel = 5*pi/180; % [rad/s] it can be set up to model limit (i.e. 20*180/pi). 74 | stgs.controller.constraints.limitMotorVel = 5*pi/180; % [rad/s] it can be set up to model limit (i.e. 20*180/pi). 75 | stgs.controller.constraints.limitRoM = 50*pi/180; % [rad] it can be set up to model limit (i.e. 50*180/pi). 76 | % stgs: desired Shape 77 | stgs.desiredShape.fun = @(x,y,t) 5.*x.*y.*cos(y/2); 78 | % stgs: integrator/state/noise 79 | stgs.noise.inputCompression.bool = config.simulation_with_noise; 80 | stgs.noise.inputCompression.maxValue = 0.2; 81 | stgs.noise.inputCompression.probMaxValue = 0.1; 82 | % stgs: visualizer 83 | stgs.visualizer.origin.dimCSYS = 0.01; 84 | stgs.visualizer.mBody.bodyCSYS.show = 1; 85 | stgs.visualizer.mBody.bodyCSYS.dim = 0.025; 86 | stgs.visualizer.desiredShape.normal.show = 1; 87 | stgs.visualizer.desiredShape.normal.color = [0.5, 0.7, 0.9]; 88 | stgs.visualizer.desiredShape.normal.dim = 0.016; 89 | stgs.visualizer.cameraView.mBodySimulation.values = [-37.5,30]; 90 | stgs.visualizer.cameraView.initialRotation.run = 1; 91 | stgs.visualizer.cameraView.initialRotation.values = [0,90]; 92 | stgs.visualizer.cameraView.finalRotation.run = 1; 93 | stgs.visualizer.cameraView.finalRotation.values = [45,20]; 94 | 95 | % run simulation 96 | data = mystica.runSimKinRel('model',model,'stgs',stgs,'mBodyPosQuat_0',mBodyPosQuat_0,'nameControllerClass','ControllerKinRel'); 97 | 98 | % visualize simulation 99 | if stgs.visualizer.run 100 | fprintf('- script SIM1: running visualizer\n') 101 | mystica.viz.visualizeKinRel('model',model,'data',data,'stgs',stgs); 102 | end 103 | 104 | fprintf(' ========= SIM1 ended ========= \n') 105 | -------------------------------------------------------------------------------- /scripts/sim2.m: -------------------------------------------------------------------------------- 1 | %% Simulation 2 - Mesh 8x8 2 | % 3 | % file: sim2 4 | % authors: Fabio Bergonti 5 | % license: BSD 3-Clause 6 | 7 | %% Clear Workspace + MATLABPATH Configuration 8 | 9 | clear 10 | clc 11 | close all 12 | fclose('all'); 13 | 14 | src_full_path = fullfile(fileparts(mfilename('fullpath')),'..','src'); 15 | datasets_full_path = fullfile(fileparts(mfilename('fullpath')),'..','datasets'); 16 | run(fullfile(src_full_path,'setup_sim.m')) 17 | 18 | %% User Parameters 19 | 20 | % config.simulation_with_noise 21 | % - true => simulation with Gaussian noise in the estimated state used by the controller. 22 | % - false => ideal simulation 23 | config.simulation_with_noise = false; 24 | 25 | % config.run_only_controller 26 | % - true => load model with motors and its initial configuration. 27 | % if this option is true, the running time is ~5min with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB. 28 | % - false => create model, evaluate the initial configuration, and solve the motors placement problem. 29 | % if this option is false, the running time is ~10min with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB. 30 | config.run_only_controller = true; 31 | 32 | %% Prepare Morphing Cover Model with Motors and its Initial Configuration 33 | fprintf(' ========= script SIM2 ========= \n') 34 | 35 | if config.run_only_controller 36 | fprintf('- script SIM2: start (running time is ~5min with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB)\n') 37 | % load model with motors and morphing cover initial configuration. 38 | fprintf('- script SIM2: loading model\n') 39 | load(fullfile(datasets_full_path,'initSim2.mat'),'model','mBodyPosQuat_0') 40 | stgs.saving.workspace.name = 'initSim2'; 41 | else 42 | fprintf('- script SIM2: start (running time is ~10min with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB)\n') 43 | % 1) create model. 44 | fprintf('- script SIM2: creating model\n') 45 | model = mystica.model.getModelCoverSquareLinks('n',8,'m',8,'restConfiguration','flat','linkDimension',0.0482); 46 | % 2) evaluate morphing cover initial configuration. 47 | % initial configuration is computed running a controlled simulation starting from flat configuration. `mBodyTwist_0` is the control variable. 48 | fprintf('- script SIM2: evaluating initial configuration\n') 49 | stgs = mystica.stgs.getDefaultSettingsSimKinAbs(model,'stgs_integrator_limitMaximumTime',4); 50 | stgs.desiredShape.fun = @(x,y,t) -2*x.^2 -2*y.^2; 51 | [data,stateKin] = mystica.runSimKinAbs('model',model,'mBodyPosQuat_0',model.getMBodyPosQuatRestConfiguration,'stgs',stgs,'nameControllerClass','ControllerKinAbs'); 52 | if stgs.visualizer.run 53 | mystica.viz.visualizeKinAbs('model',model,'data',data,'stgs',stgs); 54 | end 55 | % 3) solve the motors placement problem. 56 | fprintf('- script SIM2: solving motors placement problem\n') 57 | [model,sensitivity,genAlgrthm] = selectMotorPositioning('model',model,'state',stateKin,'stgs',stgs); 58 | mBodyPosQuat_0 = data.mBodyPosQuat_0(:,end); 59 | end 60 | 61 | %% Simulation 62 | 63 | fprintf('- script SIM2: simulating the kinematics\n') 64 | 65 | % stgs: get default values 66 | stgs = mystica.stgs.getDefaultSettingsSimKinRel(model,'startFile',stgs.saving.workspace.name,'stgs_integrator_limitMaximumTime',40); 67 | % stgs: controller parameters 68 | stgs.controller.costFunction.weightTaskOrientation = 1; 69 | stgs.controller.costFunction.weightTaskMinVariation = 0; 70 | stgs.controller.costFunction.weightTaskMinOptiVar = 0; 71 | stgs.controller.costFunction.gainLinkAngVelStarAligned = 30; 72 | stgs.controller.costFunction.gainLinkAngVelStarOpposite = 100; 73 | stgs.controller.costFunction.useFeedForwardTermLinkAngVelStar = 1; 74 | stgs.controller.constraints.limitPassiveAngVel = 5*pi/180; % [rad/s] it can be set up to model limit (i.e. 20*180/pi). 75 | stgs.controller.constraints.limitMotorVel = 5*pi/180; % [rad/s] it can be set up to model limit (i.e. 20*180/pi). 76 | stgs.controller.constraints.limitRoM = 50*pi/180; % [rad] it can be set up to model limit (i.e. 50*180/pi). 77 | % stgs: desired Shape 78 | stgs.desiredShape.fun = @(x,y,t) cos(t/8 + 10*x - 20*y)/40 - cos(t/8)/40 + cos(t/8 - 10*x + 2)/40 - cos(t/8 + 2)/40; 79 | % stgs: integrator/state/noise 80 | stgs.noise.errorStateEstimation.bool = config.simulation_with_noise; 81 | stgs.noise.errorStateEstimation.maxValue = 0.05/stgs.integrator.maxTimeStep*pi/180; 82 | stgs.noise.errorStateEstimation.probMaxValue = 0.05; 83 | % stgs: visualizer 84 | stgs.visualizer.origin.dimCSYS = 0.01; 85 | stgs.visualizer.cameraView.mBodySimulation.values = [-37.5,30]; 86 | stgs.visualizer.cameraView.initialRotation.run = 1; 87 | stgs.visualizer.cameraView.initialRotation.values = [0,90]; 88 | stgs.visualizer.cameraView.finalRotation.run = 1; 89 | stgs.visualizer.cameraView.finalRotation.values = [45,20]; 90 | 91 | % run simulation 92 | data = mystica.runSimKinRel('model',model,'stgs',stgs,'mBodyPosQuat_0',mBodyPosQuat_0,'nameControllerClass','ControllerKinRel'); 93 | 94 | % visualize simulation 95 | if stgs.visualizer.run 96 | fprintf('- script SIM2: running visualizer\n') 97 | mystica.viz.visualizeKinRel('model',model,'data',data,'stgs',stgs); 98 | end 99 | 100 | fprintf(' ========= SIM2 ended ========= \n') 101 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | Modeling and Control of Morphing Covers for the Adaptive Morphology of Humanoid Robots 3 |

4 | 5 | 6 |
7 | 8 | 9 | _F. Bergonti, G. Nava, L. Fiorio, G. L'Erario, D. Pucci "Modeling and Control of Morphing Covers for the Adaptive Morphology of Humanoid Robots" in 10 | IEEE Transactions on Robotics, vol. 38, no. 5, pp. 3300-3313, October 2022, doi: 10.1109/TRO.2022.3170281_ 11 | 12 |
13 | 14 |

15 | 16 | https://user-images.githubusercontent.com/38210073/169066254-753c29e0-2e25-4599-a52d-9dca5fe05105.mp4 17 | 18 |

19 | 20 |
21 | IEEE Transactions on Robotics 22 |
23 | 24 |
25 | Installation | 26 | Paper | 27 | arXiv | 28 | Video 29 |
30 | 31 | ## Abstract 32 | 33 | This article takes a step to provide humanoid robots with adaptive morphology abilities. We present a systematic approach for enabling robotic covers to morph their shape, with an overall size fitting the anthropometric dimensions of a humanoid robot. More precisely, we present a cover concept consisting of two main components: a skeleton, which is a repetition of a basic element called node, and a soft membrane, which encloses the cover and deforms with its motion. This article focuses on the cover skeleton and addresses the challenging problems of node design, system modeling, motor positioning, and control design of the morphing system. The cover modeling focuses on kinematics, and a systematic approach for defining the system kinematic constraints is presented. Then, we apply genetic algorithms to find the motor locations so that the morphing cover is fully actuated. Finally, we present control algorithms that allow the cover to morph into a time-varying shape. The entire approach is validated by performing kinematic simulations with four different covers of square dimensions and having 3x3, 4x8, 8x8, and 20x20 nodes, respectively. For each cover, we apply the genetic algorithms to choose the motor locations and perform simulations for tracking a desired shape. The simulation results show that the presented approach ensures the covers to track a desired shape with good tracking performances. 34 | 35 | ## MATLAB 36 | 37 | The code in this repo requires MATLAB and the MATLAB's Curve Fitting Toolbox, make sure that you have them installed on your machine. 38 | 39 | To quickly install those dependencies with [`mpm`](https://www.mathworks.com/help/install/ug/get-mpm-os-command-line.html), you can run: 40 | 41 | ~~~ 42 | mpm install --release=R2024b --products=MATLAB Curve_Fitting_Toolbox 43 | ~~~ 44 | 45 | ## Installation 46 | 47 | To install the software in this repo, follow the instructions in either the "Traditional Installation" or the "Pixi installation" section. 48 | 49 | ### Traditional Installation 50 | 51 | 1. Clone the repository and [`mystica`](https://github.com/ami-iit/mystica/): 52 | ```bash 53 | git clone https://github.com/ami-iit/paper_bergonti_2022_tro_kinematics-control-morphingcovers.git 54 | git clone https://github.com/ami-iit/mystica.git --branch v2022.06.0 55 | ``` 56 | [mystica](https://github.com/ami-iit/mystica/) is a matlab library to simulate the kinematics and dynamics of multibody systems. 57 | 58 | 2. Run in **matlab** the function [`install()`](https://github.com/ami-iit/mystica/blob/main/install.m) stored in [`mystica`](https://github.com/ami-iit/mystica/): 59 | ``` matlab 60 | install() 61 | ``` 62 | The function [`install()`](https://github.com/ami-iit/mystica/blob/main/install.m) downloads [`mambaforge`](https://github.com/conda-forge/miniforge#mambaforge). [`mambaforge`](https://github.com/conda-forge/miniforge#mambaforge) is a package manager that downloads and configures our dependencies in conda enviroment called `mystica`. 63 | 64 | ### Pixi Installation 65 | 66 | If you already have [pixi](https://pixi.sh/) installed in your machine, just run `pixi run matlab` from inside the repo: 67 | 68 | ~~~bash 69 | cd paper_bergonti_2022_tro_kinematics-control-morphingcovers 70 | pixi run matlab 71 | ~~~ 72 | 73 | This will install all required dependencies, and launch matlab with the dependencies added in the path. 74 | 75 | To launch one of experiments of the paper, you can also just run: 76 | 77 | ~~~bash 78 | cd paper_bergonti_2022_tro_kinematics-control-morphingcovers 79 | pixi run sim1 80 | ~~~ 81 | 82 | where in place of `sim1` you can also run `sim2`, `sim3` or `sim4` depending on the experiment you want to run. 83 | 84 | ## Usage 85 | 86 | This repository stores: 87 | - the algorithm for evaluating an optimal motor positioning for structures with closed kinematic loops (see Sec.IV of the [paper](https://ieeexplore.ieee.org/document/9793615)); 88 | - the instantaneous controller that evaluates motors speed to make the cover skeleton moves toward the desired shape (see Sec.V of the [paper](https://ieeexplore.ieee.org/document/9793615)); 89 | - the scripts for reproducing the simulations described in Sec.VI of the [paper](https://ieeexplore.ieee.org/document/9793615). 90 | 91 | **Reproducing simulations results** 92 | 93 | 1. If you have completed the [installation procedure](#installation) successfully, a file `setup.m` is generated in `mystica\deps`. You have to open Matlab and run the script `setup.m` to configure MATLABPATH. 94 | 95 | 2. Run one of the four scripts stored in [this folder](./scripts). For example, to reproduce the result of the first scenario you have to run: 96 | ``` matlab 97 | cd paper_bergonti_2022_tro_kinematics-control-morphingcovers 98 | cd scripts 99 | run('sim1') 100 | ``` 101 | 102 | If you open the script, you can modify the `config.simulation_with_noise` parameter deciding whether to apply noise. Instead, the parameter `config.run_only_controller` allows you to choose if you want to run only the controller without evaluating a new motor placement. 103 | 104 | | # | mesh | script | pixi command | $t_{run}$* | result | 105 | | - | - | - | - | - | - | 106 | | 1 | 3x3 | [sim1.m](./scripts/sim1.m) | `pixi run sim1` | 30s | | 107 | | 2 | 8x8 | [sim2.m](./scripts/sim2.m) | `pixi run sim2` | 5min | | 108 | | 3 | 20x20 | [sim3.m](./scripts/sim3.m) | `pixi run sim3` | 2h | | 109 | | 4 | 4x8 | [sim4.m](./scripts/sim4.m) | `pixi run sim4` | 3min | | 110 | 111 | \* $t_{run}$ is the script running time evaluated with a PC with Intel Xeon Gold 6128 3.40GHz and RAM 128GB. 112 | 113 | ## Citing this work 114 | 115 | If you find the work useful, please consider citing: 116 | 117 | ```bibtex 118 | @ARTICLE{9793615, 119 | author={Bergonti, Fabio and Nava, Gabriele and Fiorio, Luca and L’Erario, Giuseppe and Pucci, Daniele}, 120 | journal={IEEE Transactions on Robotics}, 121 | title={Modeling and Control of Morphing Covers for the Adaptive Morphology of Humanoid Robots}, 122 | year={2022}, 123 | volume={38}, 124 | number={5}, 125 | pages={3300-3313}, 126 | doi={10.1109/TRO.2022.3170281}} 127 | ``` 128 | 129 | ### Maintainer 130 | 131 | This repository is maintained by: 132 | 133 | | | | 134 | |:---:|:---:| 135 | | [](https://github.com/FabioBergonti) | [@FabioBergonti](https://github.com/FabioBergonti) | 136 | 137 |

138 | Size 139 | CI 140 |

141 | -------------------------------------------------------------------------------- /pixi.lock: -------------------------------------------------------------------------------- 1 | version: 5 2 | environments: 3 | default: 4 | channels: 5 | - url: https://conda.anaconda.org/conda-forge/ 6 | - url: https://conda.anaconda.org/robotology/ 7 | packages: 8 | linux-64: 9 | - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 10 | - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 11 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ampl-mp-3.1.0-h2cc385e_1006.tar.bz2 12 | - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda 13 | - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.3-heb4867d_0.conda 14 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.8.30-hbcca054_0.conda 15 | - conda: https://conda.anaconda.org/conda-forge/linux-64/casadi-3.5.5-py39h19f53c4_3.tar.bz2 16 | - conda: https://conda.anaconda.org/robotology/linux-64/casadi-matlab-bindings-3.5.5.2-ha7f347e_83.tar.bz2 17 | - conda: https://conda.anaconda.org/conda-forge/linux-64/git-2.47.0-pl5321h59d505e_0.conda 18 | - conda: https://conda.anaconda.org/conda-forge/linux-64/git-lfs-3.5.1-h647637d_1.conda 19 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ipopt-3.13.3-he21f442_1.tar.bz2 20 | - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 21 | - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda 22 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_2.conda 23 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-25_linux64_openblas.conda 24 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-25_linux64_openblas.conda 25 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.10.1-hbbe4b11_0.conda 26 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2 27 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda 28 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.4-h5888daf_0.conda 29 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 30 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h77fa898_1.conda 31 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_1.conda 32 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-7.5.0-h14aa051_20.tar.bz2 33 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran4-7.5.0-h14aa051_20.tar.bz2 34 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hd5240d6_1.conda 35 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h77fa898_1.conda 36 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_2.conda 37 | - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-25_linux64_openblas.conda 38 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda 39 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda 40 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.28-pthreads_h94d23a6_0.conda 41 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.47.0-hadc24fc_1.conda 42 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda 43 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-hc0a3c3a_1.conda 44 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.2.0-h4852527_1.conda 45 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda 46 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda 47 | - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda 48 | - conda: https://conda.anaconda.org/conda-forge/linux-64/metis-5.1.0-hd0bcaf9_1007.conda 49 | - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda 50 | - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-1.26.4-py39h474f0d3_0.conda 51 | - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda 52 | - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hba22ea6_2.conda 53 | - conda: https://conda.anaconda.org/conda-forge/linux-64/perl-5.32.1-7_hd590300_perl5.conda 54 | - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.9.20-h13acc7a_1_cpython.conda 55 | - conda: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.9-5_cp39.conda 56 | - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda 57 | - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda 58 | - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda 59 | - conda: https://conda.anaconda.org/conda-forge/linux-64/unixodbc-2.3.12-h661eb56_0.conda 60 | - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 61 | - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.6-ha6fb4c9_0.conda 62 | win-64: 63 | - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda 64 | - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.8.30-h56e8100_0.conda 65 | - conda: https://conda.anaconda.org/conda-forge/win-64/casadi-3.5.5-py311he26517d_18.conda 66 | - conda: https://conda.anaconda.org/robotology/win-64/casadi-matlab-bindings-3.5.5.2-hc351297_83.tar.bz2 67 | - conda: https://conda.anaconda.org/conda-forge/win-64/git-2.47.0-h57928b3_0.conda 68 | - conda: https://conda.anaconda.org/conda-forge/win-64/git-lfs-3.5.1-h50ec22b_1.conda 69 | - conda: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.2.1-h57928b3_1083.conda 70 | - conda: https://conda.anaconda.org/conda-forge/win-64/ipopt-3.14.11-ha9547d1_0.conda 71 | - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-25_win64_mkl.conda 72 | - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-25_win64_mkl.conda 73 | - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.6.4-he0c23c2_0.conda 74 | - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 75 | - conda: https://conda.anaconda.org/conda-forge/win-64/libflang-5.0.0-h6538335_20180525.tar.bz2 76 | - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.11.1-default_h8125262_1000.conda 77 | - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.17-hcfcfb64_2.conda 78 | - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-25_win64_mkl.conda 79 | - conda: https://conda.anaconda.org/conda-forge/win-64/libosqp-0.6.2-h63175ca_4.conda 80 | - conda: https://conda.anaconda.org/conda-forge/win-64/libqdldl-0.1.5-h63175ca_1.tar.bz2 81 | - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.47.0-h2466b09_1.conda 82 | - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.5-h442d1da_0.conda 83 | - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda 84 | - conda: https://conda.anaconda.org/conda-forge/noarch/llvm-meta-5.0.0-0.tar.bz2 85 | - conda: https://conda.anaconda.org/conda-forge/win-64/metis-5.1.0-h17e2fc9_1007.conda 86 | - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.2.2-h66d3029_14.conda 87 | - conda: https://conda.anaconda.org/conda-forge/win-64/mumps-seq-5.2.1-h1f49738_14.conda 88 | - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-1.26.4-py311h0b4df5a_0.conda 89 | - conda: https://conda.anaconda.org/conda-forge/win-64/openmp-5.0.0-vc14_1.tar.bz2 90 | - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda 91 | - conda: https://conda.anaconda.org/conda-forge/win-64/pthreads-win32-2.9.1-h2466b09_4.conda 92 | - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.10-hce54a09_3_cpython.conda 93 | - conda: https://conda.anaconda.org/conda-forge/win-64/python_abi-3.11-5_cp311.conda 94 | - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.13.0-hc790b64_0.conda 95 | - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda 96 | - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda 97 | - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda 98 | - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_22.conda 99 | - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.40.33810-hcc2c482_22.conda 100 | - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.40.33810-h3bf8584_22.conda 101 | - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 102 | packages: 103 | - kind: conda 104 | name: _libgcc_mutex 105 | version: '0.1' 106 | build: conda_forge 107 | subdir: linux-64 108 | url: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 109 | sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 110 | md5: d7c89558ba9fa0495403155b64376d81 111 | license: None 112 | size: 2562 113 | timestamp: 1578324546067 114 | - kind: conda 115 | name: _openmp_mutex 116 | version: '4.5' 117 | build: 2_gnu 118 | build_number: 16 119 | subdir: linux-64 120 | url: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 121 | sha256: fbe2c5e56a653bebb982eda4876a9178aedfc2b545f25d0ce9c4c0b508253d22 122 | md5: 73aaf86a425cc6e73fcf236a5a46396d 123 | depends: 124 | - _libgcc_mutex 0.1 conda_forge 125 | - libgomp >=7.5.0 126 | constrains: 127 | - openmp_impl 9999 128 | license: BSD-3-Clause 129 | license_family: BSD 130 | size: 23621 131 | timestamp: 1650670423406 132 | - kind: conda 133 | name: ampl-mp 134 | version: 3.1.0 135 | build: h2cc385e_1006 136 | build_number: 1006 137 | subdir: linux-64 138 | url: https://conda.anaconda.org/conda-forge/linux-64/ampl-mp-3.1.0-h2cc385e_1006.tar.bz2 139 | sha256: ff6e942d6490496d98d670f783275078d2a30c694202304ecd49fb759b93c07f 140 | md5: 6c2f16f5650a7c66ffdfee57b890ea06 141 | depends: 142 | - libgcc-ng >=9.4.0 143 | - libgfortran-ng 144 | - libgfortran5 >=9.4.0 145 | - libstdcxx-ng >=9.4.0 146 | - unixodbc >=2.3.9,<2.4.0a0 147 | license: HPND 148 | size: 1137486 149 | timestamp: 1645057516176 150 | - kind: conda 151 | name: bzip2 152 | version: 1.0.8 153 | build: h2466b09_7 154 | build_number: 7 155 | subdir: win-64 156 | url: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda 157 | sha256: 35a5dad92e88fdd7fc405e864ec239486f4f31eec229e31686e61a140a8e573b 158 | md5: 276e7ffe9ffe39688abc665ef0f45596 159 | depends: 160 | - ucrt >=10.0.20348.0 161 | - vc >=14.2,<15 162 | - vc14_runtime >=14.29.30139 163 | license: bzip2-1.0.6 164 | license_family: BSD 165 | size: 54927 166 | timestamp: 1720974860185 167 | - kind: conda 168 | name: bzip2 169 | version: 1.0.8 170 | build: h4bc722e_7 171 | build_number: 7 172 | subdir: linux-64 173 | url: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda 174 | sha256: 5ced96500d945fb286c9c838e54fa759aa04a7129c59800f0846b4335cee770d 175 | md5: 62ee74e96c5ebb0af99386de58cf9553 176 | depends: 177 | - __glibc >=2.17,<3.0.a0 178 | - libgcc-ng >=12 179 | license: bzip2-1.0.6 180 | license_family: BSD 181 | size: 252783 182 | timestamp: 1720974456583 183 | - kind: conda 184 | name: c-ares 185 | version: 1.34.3 186 | build: heb4867d_0 187 | subdir: linux-64 188 | url: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.3-heb4867d_0.conda 189 | sha256: 1015d731c05ef7de298834833d680b08dea58980b907f644345bd457f9498c99 190 | md5: 09a6c610d002e54e18353c06ef61a253 191 | depends: 192 | - __glibc >=2.28,<3.0.a0 193 | - libgcc >=13 194 | license: MIT 195 | license_family: MIT 196 | size: 205575 197 | timestamp: 1731181837907 198 | - kind: conda 199 | name: ca-certificates 200 | version: 2024.8.30 201 | build: h56e8100_0 202 | subdir: win-64 203 | url: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.8.30-h56e8100_0.conda 204 | sha256: 0fcac3a7ffcc556649e034a1802aedf795e64227eaa7194d207b01eaf26454c4 205 | md5: 4c4fd67c18619be5aa65dc5b6c72e490 206 | license: ISC 207 | size: 158773 208 | timestamp: 1725019107649 209 | - kind: conda 210 | name: ca-certificates 211 | version: 2024.8.30 212 | build: hbcca054_0 213 | subdir: linux-64 214 | url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.8.30-hbcca054_0.conda 215 | sha256: afee721baa6d988e27fef1832f68d6f32ac8cc99cdf6015732224c2841a09cea 216 | md5: c27d1c142233b5bc9ca570c6e2e0c244 217 | license: ISC 218 | size: 159003 219 | timestamp: 1725018903918 220 | - kind: conda 221 | name: casadi 222 | version: 3.5.5 223 | build: py311he26517d_18 224 | build_number: 18 225 | subdir: win-64 226 | url: https://conda.anaconda.org/conda-forge/win-64/casadi-3.5.5-py311he26517d_18.conda 227 | sha256: c4cd5622cac86dbb01ab508ac7599120d89f0b1a88913fd9a56d6cfd530c7366 228 | md5: e72242d7b1c2961a8876c5cb3e172b74 229 | depends: 230 | - ipopt >=3.14.11,<3.14.12.0a0 231 | - libblas >=3.9.0,<4.0a0 232 | - libcblas >=3.9.0,<4.0a0 233 | - libflang >=5.0.0,<6.0.0.a0 234 | - libosqp >=0.6.2,<0.6.3.0a0 235 | - numpy >=1.23.5,<2.0a0 236 | - python >=3.11,<3.12.0a0 237 | - python_abi 3.11.* *_cp311 238 | - ucrt >=10.0.20348.0 239 | - vc >=14.2,<15 240 | - vs2015_runtime >=14.29.30139 241 | license: LGPL-3.0-or-later 242 | license_family: LGPL 243 | size: 3451971 244 | timestamp: 1675806004035 245 | - kind: conda 246 | name: casadi 247 | version: 3.5.5 248 | build: py39h19f53c4_3 249 | build_number: 3 250 | subdir: linux-64 251 | url: https://conda.anaconda.org/conda-forge/linux-64/casadi-3.5.5-py39h19f53c4_3.tar.bz2 252 | sha256: c4a64d54a7c691324d18418e572e9bc4639b810eb669eb53463f74df33bf66e3 253 | md5: 2f0f5557d84167443aa59f73ffbcb3ee 254 | depends: 255 | - ipopt >=3.13.3,<3.13.4.0a0 256 | - libblas >=3.8.0,<4.0a0 257 | - libcblas >=3.8.0,<4.0a0 258 | - libgcc-ng >=9.3.0 259 | - libgfortran-ng 260 | - libgfortran5 >=9.3.0 261 | - libstdcxx-ng >=9.3.0 262 | - numpy >=1.19.5,<2.0a0 263 | - python >=3.9,<3.10.0a0 264 | - python_abi 3.9.* *_cp39 265 | license: LGPL-3.0-or-later 266 | license_family: LGPL 267 | size: 5234061 268 | timestamp: 1612746963528 269 | - kind: conda 270 | name: casadi-matlab-bindings 271 | version: 3.5.5.2 272 | build: ha7f347e_83 273 | build_number: 83 274 | subdir: linux-64 275 | url: https://conda.anaconda.org/robotology/linux-64/casadi-matlab-bindings-3.5.5.2-ha7f347e_83.tar.bz2 276 | sha256: ec06c199975ba273f6b6e165cc6b6446d46efa3bd745d7b7ff62bd20150b3161 277 | md5: 3be9e81419d649ae8b60f4359e6f77d3 278 | depends: 279 | - casadi >=3.5.5,<3.6.0a0 280 | - libgcc-ng >=12 281 | - libstdcxx-ng >=12 282 | arch: x86_64 283 | platform: linux 284 | size: 1114244 285 | timestamp: 1680811984614 286 | - kind: conda 287 | name: casadi-matlab-bindings 288 | version: 3.5.5.2 289 | build: hc351297_83 290 | build_number: 83 291 | subdir: win-64 292 | url: https://conda.anaconda.org/robotology/win-64/casadi-matlab-bindings-3.5.5.2-hc351297_83.tar.bz2 293 | sha256: 303d209a8565747f2b8d7ea906b7019d816e7b9c26cc0376231f60d91bacbdd9 294 | md5: a090250015f215f0916de25d01c65973 295 | depends: 296 | - casadi >=3.5.5,<3.6.0a0 297 | - ucrt >=10.0.20348.0 298 | - vc >=14.2,<15 299 | - vs2015_runtime >=14.29.30139 300 | arch: x86_64 301 | platform: win 302 | size: 968400 303 | timestamp: 1680817227635 304 | - kind: conda 305 | name: git 306 | version: 2.47.0 307 | build: h57928b3_0 308 | subdir: win-64 309 | url: https://conda.anaconda.org/conda-forge/win-64/git-2.47.0-h57928b3_0.conda 310 | sha256: 21ee8885842d12d91b79d9eb40480423c2b1472073197ddd101c758e8a7669fb 311 | md5: 69d4c5c9c03b7cbfc042b2a9db4963b9 312 | license: GPL-2.0-or-later and LGPL-2.1-or-later 313 | size: 122567948 314 | timestamp: 1728492005102 315 | - kind: conda 316 | name: git 317 | version: 2.47.0 318 | build: pl5321h59d505e_0 319 | subdir: linux-64 320 | url: https://conda.anaconda.org/conda-forge/linux-64/git-2.47.0-pl5321h59d505e_0.conda 321 | sha256: ec0e20ae0aa8146895a107adf7ef9949759942617f5cbecb783284528df6b06c 322 | md5: 5cb49c00a7aa5f400b70e95b84d90595 323 | depends: 324 | - __glibc >=2.17,<3.0.a0 325 | - libcurl >=8.10.1,<9.0a0 326 | - libexpat >=2.6.3,<3.0a0 327 | - libgcc >=13 328 | - libiconv >=1.17,<2.0a0 329 | - libzlib >=1.3.1,<2.0a0 330 | - openssl >=3.3.2,<4.0a0 331 | - pcre2 >=10.44,<10.45.0a0 332 | - perl 5.* 333 | license: GPL-2.0-or-later and LGPL-2.1-or-later 334 | size: 10510958 335 | timestamp: 1728491333125 336 | - kind: conda 337 | name: git-lfs 338 | version: 3.5.1 339 | build: h50ec22b_1 340 | build_number: 1 341 | subdir: win-64 342 | url: https://conda.anaconda.org/conda-forge/win-64/git-lfs-3.5.1-h50ec22b_1.conda 343 | sha256: 8261e8975a48030d9aff745cc454db73784d7514ce42bce65fa77772116094a7 344 | md5: 8389e50ae247ba0a1d470cc30ef726da 345 | license: MIT 346 | license_family: MIT 347 | size: 3927291 348 | timestamp: 1730911445048 349 | - kind: conda 350 | name: git-lfs 351 | version: 3.5.1 352 | build: h647637d_1 353 | build_number: 1 354 | subdir: linux-64 355 | url: https://conda.anaconda.org/conda-forge/linux-64/git-lfs-3.5.1-h647637d_1.conda 356 | sha256: 082b4b1e59ac7c3a15dfc61d077b6b2b36c82ab15a268d0facfdc82737b983d5 357 | md5: 6dfad56d8b8f5f72f615b60f0baf1dea 358 | license: MIT 359 | license_family: MIT 360 | size: 4043713 361 | timestamp: 1730911305948 362 | - kind: conda 363 | name: intel-openmp 364 | version: 2024.2.1 365 | build: h57928b3_1083 366 | build_number: 1083 367 | subdir: win-64 368 | url: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.2.1-h57928b3_1083.conda 369 | sha256: 0fd2b0b84c854029041b0ede8f4c2369242ee92acc0092f8407b1fe9238a8209 370 | md5: 2d89243bfb53652c182a7c73182cce4f 371 | license: LicenseRef-IntelSimplifiedSoftwareOct2022 372 | license_family: Proprietary 373 | size: 1852356 374 | timestamp: 1723739573141 375 | - kind: conda 376 | name: ipopt 377 | version: 3.13.3 378 | build: he21f442_1 379 | build_number: 1 380 | subdir: linux-64 381 | url: https://conda.anaconda.org/conda-forge/linux-64/ipopt-3.13.3-he21f442_1.tar.bz2 382 | sha256: da1ac774cf98cf0c50a2e12c962c58483a8fb190d94943e9830e1db530af5e52 383 | md5: c2fe798306f0166cea2c13667cda5987 384 | depends: 385 | - ampl-mp >=3.1.0,<3.2.0a0 386 | - libblas >=3.8.0,<4.0a0 387 | - libgcc-ng >=7.5.0 388 | - libgfortran-ng 389 | - libgfortran4 >=7.5.0 390 | - liblapack >=3.8.0,<4.0a0 391 | - libstdcxx-ng >=7.5.0 392 | - metis >=5.1.0,<5.1.1.0a0 393 | license: EPL-1.0 394 | size: 1736329 395 | timestamp: 1604317728065 396 | - kind: conda 397 | name: ipopt 398 | version: 3.14.11 399 | build: ha9547d1_0 400 | subdir: win-64 401 | url: https://conda.anaconda.org/conda-forge/win-64/ipopt-3.14.11-ha9547d1_0.conda 402 | sha256: bac9c5bc8d133699897480b00d5474c2742cb3cc4b227ea0219fe95125987fc1 403 | md5: 034ed5d17e12975b2fa621df1a505b1e 404 | depends: 405 | - libblas >=3.9.0,<4.0a0 406 | - libflang >=5.0.0,<6.0.0.a0 407 | - liblapack >=3.9.0,<4.0a0 408 | - metis >=5.1.0,<5.1.1.0a0 409 | - mumps-seq >=5.2.1,<5.2.2.0a0 410 | - ucrt >=10.0.20348.0 411 | - vc >=14.2,<15 412 | - vs2015_runtime >=14.29.30139 413 | license: EPL-1.0 414 | size: 897742 415 | timestamp: 1675755407691 416 | - kind: conda 417 | name: keyutils 418 | version: 1.6.1 419 | build: h166bdaf_0 420 | subdir: linux-64 421 | url: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 422 | sha256: 150c05a6e538610ca7c43beb3a40d65c90537497a4f6a5f4d15ec0451b6f5ebb 423 | md5: 30186d27e2c9fa62b45fb1476b7200e3 424 | depends: 425 | - libgcc-ng >=10.3.0 426 | license: LGPL-2.1-or-later 427 | size: 117831 428 | timestamp: 1646151697040 429 | - kind: conda 430 | name: krb5 431 | version: 1.21.3 432 | build: h659f571_0 433 | subdir: linux-64 434 | url: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda 435 | sha256: 99df692f7a8a5c27cd14b5fb1374ee55e756631b9c3d659ed3ee60830249b238 436 | md5: 3f43953b7d3fb3aaa1d0d0723d91e368 437 | depends: 438 | - keyutils >=1.6.1,<2.0a0 439 | - libedit >=3.1.20191231,<3.2.0a0 440 | - libedit >=3.1.20191231,<4.0a0 441 | - libgcc-ng >=12 442 | - libstdcxx-ng >=12 443 | - openssl >=3.3.1,<4.0a0 444 | license: MIT 445 | license_family: MIT 446 | size: 1370023 447 | timestamp: 1719463201255 448 | - kind: conda 449 | name: ld_impl_linux-64 450 | version: '2.43' 451 | build: h712a8e2_2 452 | build_number: 2 453 | subdir: linux-64 454 | url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_2.conda 455 | sha256: 7c91cea91b13f4314d125d1bedb9d03a29ebbd5080ccdea70260363424646dbe 456 | md5: 048b02e3962f066da18efe3a21b77672 457 | depends: 458 | - __glibc >=2.17,<3.0.a0 459 | constrains: 460 | - binutils_impl_linux-64 2.43 461 | license: GPL-3.0-only 462 | license_family: GPL 463 | size: 669211 464 | timestamp: 1729655358674 465 | - kind: conda 466 | name: libblas 467 | version: 3.9.0 468 | build: 25_linux64_openblas 469 | build_number: 25 470 | subdir: linux-64 471 | url: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-25_linux64_openblas.conda 472 | sha256: d6d12dc437d060f838820e9e61bf73baab651f91935ac594cf10beb9ef1b4450 473 | md5: 8ea26d42ca88ec5258802715fe1ee10b 474 | depends: 475 | - libopenblas >=0.3.28,<0.3.29.0a0 476 | - libopenblas >=0.3.28,<1.0a0 477 | constrains: 478 | - liblapack 3.9.0 25_linux64_openblas 479 | - libcblas 3.9.0 25_linux64_openblas 480 | - blas * openblas 481 | - liblapacke 3.9.0 25_linux64_openblas 482 | license: BSD-3-Clause 483 | license_family: BSD 484 | size: 15677 485 | timestamp: 1729642900350 486 | - kind: conda 487 | name: libblas 488 | version: 3.9.0 489 | build: 25_win64_mkl 490 | build_number: 25 491 | subdir: win-64 492 | url: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-25_win64_mkl.conda 493 | sha256: 5468bb91c44b41ce060bbd997c797b2f91e2b7ce91a7cbf4ddf7e7b734a8dc98 494 | md5: 499208e81242efb6e5abc7366c91c816 495 | depends: 496 | - mkl 2024.2.2 h66d3029_14 497 | constrains: 498 | - blas * mkl 499 | - libcblas 3.9.0 25_win64_mkl 500 | - liblapack 3.9.0 25_win64_mkl 501 | - liblapacke 3.9.0 25_win64_mkl 502 | license: BSD-3-Clause 503 | license_family: BSD 504 | size: 3736641 505 | timestamp: 1729643534444 506 | - kind: conda 507 | name: libcblas 508 | version: 3.9.0 509 | build: 25_linux64_openblas 510 | build_number: 25 511 | subdir: linux-64 512 | url: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-25_linux64_openblas.conda 513 | sha256: ab87b0477078837c91d9cda62a9faca18fba7c57cc77aa779ae24b3ac783b5dd 514 | md5: 5dbd1b0fc0d01ec5e0e1fbe667281a11 515 | depends: 516 | - libblas 3.9.0 25_linux64_openblas 517 | constrains: 518 | - liblapack 3.9.0 25_linux64_openblas 519 | - blas * openblas 520 | - liblapacke 3.9.0 25_linux64_openblas 521 | license: BSD-3-Clause 522 | license_family: BSD 523 | size: 15613 524 | timestamp: 1729642905619 525 | - kind: conda 526 | name: libcblas 527 | version: 3.9.0 528 | build: 25_win64_mkl 529 | build_number: 25 530 | subdir: win-64 531 | url: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-25_win64_mkl.conda 532 | sha256: 21528cdfe67dafdb2d21925515a167f13963e002c2b6d06d68984767f731850c 533 | md5: 3ed189ba03a9888a8013aaee0d67c49d 534 | depends: 535 | - libblas 3.9.0 25_win64_mkl 536 | constrains: 537 | - blas * mkl 538 | - liblapack 3.9.0 25_win64_mkl 539 | - liblapacke 3.9.0 25_win64_mkl 540 | license: BSD-3-Clause 541 | license_family: BSD 542 | size: 3732258 543 | timestamp: 1729643561581 544 | - kind: conda 545 | name: libcurl 546 | version: 8.10.1 547 | build: hbbe4b11_0 548 | subdir: linux-64 549 | url: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.10.1-hbbe4b11_0.conda 550 | sha256: 54e6114dfce566c3a22ad3b7b309657e3600cdb668398e95f1301360d5d52c99 551 | md5: 6e801c50a40301f6978c53976917b277 552 | depends: 553 | - __glibc >=2.17,<3.0.a0 554 | - krb5 >=1.21.3,<1.22.0a0 555 | - libgcc >=13 556 | - libnghttp2 >=1.58.0,<2.0a0 557 | - libssh2 >=1.11.0,<2.0a0 558 | - libzlib >=1.3.1,<2.0a0 559 | - openssl >=3.3.2,<4.0a0 560 | - zstd >=1.5.6,<1.6.0a0 561 | license: curl 562 | license_family: MIT 563 | size: 424900 564 | timestamp: 1726659794676 565 | - kind: conda 566 | name: libedit 567 | version: 3.1.20191231 568 | build: he28a2e2_2 569 | build_number: 2 570 | subdir: linux-64 571 | url: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2 572 | sha256: a57d37c236d8f7c886e01656f4949d9dcca131d2a0728609c6f7fa338b65f1cf 573 | md5: 4d331e44109e3f0e19b4cb8f9b82f3e1 574 | depends: 575 | - libgcc-ng >=7.5.0 576 | - ncurses >=6.2,<7.0.0a0 577 | license: BSD-2-Clause 578 | license_family: BSD 579 | size: 123878 580 | timestamp: 1597616541093 581 | - kind: conda 582 | name: libev 583 | version: '4.33' 584 | build: hd590300_2 585 | build_number: 2 586 | subdir: linux-64 587 | url: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda 588 | sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 589 | md5: 172bf1cd1ff8629f2b1179945ed45055 590 | depends: 591 | - libgcc-ng >=12 592 | license: BSD-2-Clause 593 | license_family: BSD 594 | size: 112766 595 | timestamp: 1702146165126 596 | - kind: conda 597 | name: libexpat 598 | version: 2.6.4 599 | build: h5888daf_0 600 | subdir: linux-64 601 | url: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.4-h5888daf_0.conda 602 | sha256: 56541b98447b58e52d824bd59d6382d609e11de1f8adf20b23143e353d2b8d26 603 | md5: db833e03127376d461e1e13e76f09b6c 604 | depends: 605 | - __glibc >=2.17,<3.0.a0 606 | - libgcc >=13 607 | constrains: 608 | - expat 2.6.4.* 609 | license: MIT 610 | license_family: MIT 611 | size: 73304 612 | timestamp: 1730967041968 613 | - kind: conda 614 | name: libexpat 615 | version: 2.6.4 616 | build: he0c23c2_0 617 | subdir: win-64 618 | url: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.6.4-he0c23c2_0.conda 619 | sha256: 0c0447bf20d1013d5603499de93a16b6faa92d7ead870d96305c0f065b6a5a12 620 | md5: eb383771c680aa792feb529eaf9df82f 621 | depends: 622 | - ucrt >=10.0.20348.0 623 | - vc >=14.2,<15 624 | - vc14_runtime >=14.29.30139 625 | constrains: 626 | - expat 2.6.4.* 627 | license: MIT 628 | license_family: MIT 629 | size: 139068 630 | timestamp: 1730967442102 631 | - kind: conda 632 | name: libffi 633 | version: 3.4.2 634 | build: h7f98852_5 635 | build_number: 5 636 | subdir: linux-64 637 | url: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 638 | sha256: ab6e9856c21709b7b517e940ae7028ae0737546122f83c2aa5d692860c3b149e 639 | md5: d645c6d2ac96843a2bfaccd2d62b3ac3 640 | depends: 641 | - libgcc-ng >=9.4.0 642 | license: MIT 643 | license_family: MIT 644 | size: 58292 645 | timestamp: 1636488182923 646 | - kind: conda 647 | name: libffi 648 | version: 3.4.2 649 | build: h8ffe710_5 650 | build_number: 5 651 | subdir: win-64 652 | url: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 653 | sha256: 1951ab740f80660e9bc07d2ed3aefb874d78c107264fd810f24a1a6211d4b1a5 654 | md5: 2c96d1b6915b408893f9472569dee135 655 | depends: 656 | - vc >=14.1,<15.0a0 657 | - vs2015_runtime >=14.16.27012 658 | license: MIT 659 | license_family: MIT 660 | size: 42063 661 | timestamp: 1636489106777 662 | - kind: conda 663 | name: libflang 664 | version: 5.0.0 665 | build: h6538335_20180525 666 | build_number: 20180525 667 | subdir: win-64 668 | url: https://conda.anaconda.org/conda-forge/win-64/libflang-5.0.0-h6538335_20180525.tar.bz2 669 | sha256: 0b893b511190332320f4a3e3d6424fbd350271ffbca34eb25b5cd8bc451f1a05 670 | md5: 9f473a344e18668e99a93f7e21a54b69 671 | depends: 672 | - openmp 5.0.0 673 | - vc >=14,<15.0a0 674 | arch: x86_64 675 | platform: win 676 | track_features: 677 | - flang 678 | license: Apache 2.0 679 | size: 531143 680 | timestamp: 1527899216421 681 | - kind: conda 682 | name: libgcc 683 | version: 14.2.0 684 | build: h77fa898_1 685 | build_number: 1 686 | subdir: linux-64 687 | url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h77fa898_1.conda 688 | sha256: 53eb8a79365e58849e7b1a068d31f4f9e718dc938d6f2c03e960345739a03569 689 | md5: 3cb76c3f10d3bc7f1105b2fc9db984df 690 | depends: 691 | - _libgcc_mutex 0.1 conda_forge 692 | - _openmp_mutex >=4.5 693 | constrains: 694 | - libgomp 14.2.0 h77fa898_1 695 | - libgcc-ng ==14.2.0=*_1 696 | license: GPL-3.0-only WITH GCC-exception-3.1 697 | license_family: GPL 698 | size: 848745 699 | timestamp: 1729027721139 700 | - kind: conda 701 | name: libgcc-ng 702 | version: 14.2.0 703 | build: h69a702a_1 704 | build_number: 1 705 | subdir: linux-64 706 | url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_1.conda 707 | sha256: 3a76969c80e9af8b6e7a55090088bc41da4cffcde9e2c71b17f44d37b7cb87f7 708 | md5: e39480b9ca41323497b05492a63bc35b 709 | depends: 710 | - libgcc 14.2.0 h77fa898_1 711 | license: GPL-3.0-only WITH GCC-exception-3.1 712 | license_family: GPL 713 | size: 54142 714 | timestamp: 1729027726517 715 | - kind: conda 716 | name: libgfortran-ng 717 | version: 7.5.0 718 | build: h14aa051_20 719 | build_number: 20 720 | subdir: linux-64 721 | url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-7.5.0-h14aa051_20.tar.bz2 722 | sha256: 7347a7a57f992d3d4fdb1bf98582ec0963d45b16d9dfb3efe2045ff2cb157527 723 | md5: c3b2ad091c043c08689e64b10741484b 724 | depends: 725 | - libgfortran4 7.5.0.* 726 | license: GPL-3.0-only WITH GCC-exception-3.1 727 | license_family: GPL 728 | size: 23435 729 | timestamp: 1644093859248 730 | - kind: conda 731 | name: libgfortran4 732 | version: 7.5.0 733 | build: h14aa051_20 734 | build_number: 20 735 | subdir: linux-64 736 | url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran4-7.5.0-h14aa051_20.tar.bz2 737 | sha256: a8f3ae8e6c9fbe52f7403bfb2e00bf0c5169ab0702a4a5f3ad88494867e03427 738 | md5: a072eab836c3a9578ce72b5640ce592d 739 | constrains: 740 | - libgfortran-ng 7.5.0 *_20 741 | license: GPL-3.0-only WITH GCC-exception-3.1 742 | license_family: GPL 743 | size: 1309697 744 | timestamp: 1644093800802 745 | - kind: conda 746 | name: libgfortran5 747 | version: 14.2.0 748 | build: hd5240d6_1 749 | build_number: 1 750 | subdir: linux-64 751 | url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hd5240d6_1.conda 752 | sha256: d149a37ca73611e425041f33b9d8dbed6e52ec506fe8cc1fc0ee054bddeb6d5d 753 | md5: 9822b874ea29af082e5d36098d25427d 754 | depends: 755 | - libgcc >=14.2.0 756 | constrains: 757 | - libgfortran 14.2.0 758 | license: GPL-3.0-only WITH GCC-exception-3.1 759 | license_family: GPL 760 | size: 1462645 761 | timestamp: 1729027735353 762 | - kind: conda 763 | name: libgomp 764 | version: 14.2.0 765 | build: h77fa898_1 766 | build_number: 1 767 | subdir: linux-64 768 | url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h77fa898_1.conda 769 | sha256: 1911c29975ec99b6b906904040c855772ccb265a1c79d5d75c8ceec4ed89cd63 770 | md5: cc3573974587f12dda90d96e3e55a702 771 | depends: 772 | - _libgcc_mutex 0.1 conda_forge 773 | license: GPL-3.0-only WITH GCC-exception-3.1 774 | license_family: GPL 775 | size: 460992 776 | timestamp: 1729027639220 777 | - kind: conda 778 | name: libhwloc 779 | version: 2.11.1 780 | build: default_h8125262_1000 781 | build_number: 1000 782 | subdir: win-64 783 | url: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.11.1-default_h8125262_1000.conda 784 | sha256: 92728e292640186759d6dddae3334a1bc0b139740b736ffaeccb825fb8c07a2e 785 | md5: 933bad6e4658157f1aec9b171374fde2 786 | depends: 787 | - libxml2 >=2.12.7,<3.0a0 788 | - pthreads-win32 789 | - ucrt >=10.0.20348.0 790 | - vc >=14.2,<15 791 | - vc14_runtime >=14.29.30139 792 | license: BSD-3-Clause 793 | license_family: BSD 794 | size: 2379689 795 | timestamp: 1720461835526 796 | - kind: conda 797 | name: libiconv 798 | version: '1.17' 799 | build: hcfcfb64_2 800 | build_number: 2 801 | subdir: win-64 802 | url: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.17-hcfcfb64_2.conda 803 | sha256: 5f844dd19b046d43174ad80c6ea75b5d504020e3b63cfbc4ace97b8730d35c7b 804 | md5: e1eb10b1cca179f2baa3601e4efc8712 805 | depends: 806 | - ucrt >=10.0.20348.0 807 | - vc >=14.2,<15 808 | - vc14_runtime >=14.29.30139 809 | license: LGPL-2.1-only 810 | size: 636146 811 | timestamp: 1702682547199 812 | - kind: conda 813 | name: libiconv 814 | version: '1.17' 815 | build: hd590300_2 816 | build_number: 2 817 | subdir: linux-64 818 | url: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.17-hd590300_2.conda 819 | sha256: 8ac2f6a9f186e76539439e50505d98581472fedb347a20e7d1f36429849f05c9 820 | md5: d66573916ffcf376178462f1b61c941e 821 | depends: 822 | - libgcc-ng >=12 823 | license: LGPL-2.1-only 824 | size: 705775 825 | timestamp: 1702682170569 826 | - kind: conda 827 | name: liblapack 828 | version: 3.9.0 829 | build: 25_linux64_openblas 830 | build_number: 25 831 | subdir: linux-64 832 | url: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-25_linux64_openblas.conda 833 | sha256: 9d1ff017714edb2d84868f0f931a4a0e7c289a971062b2ac66cfc8145df7e20e 834 | md5: 4dc03a53fc69371a6158d0ed37214cd3 835 | depends: 836 | - libblas 3.9.0 25_linux64_openblas 837 | constrains: 838 | - liblapacke 3.9.0 25_linux64_openblas 839 | - libcblas 3.9.0 25_linux64_openblas 840 | - blas * openblas 841 | license: BSD-3-Clause 842 | license_family: BSD 843 | size: 15608 844 | timestamp: 1729642910812 845 | - kind: conda 846 | name: liblapack 847 | version: 3.9.0 848 | build: 25_win64_mkl 849 | build_number: 25 850 | subdir: win-64 851 | url: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-25_win64_mkl.conda 852 | sha256: 98c13a28596389539abe3f608c6fbd2826df47671f77c58a331df878c6140c53 853 | md5: f716ef84564c574e8e74ae725f5d5f93 854 | depends: 855 | - libblas 3.9.0 25_win64_mkl 856 | constrains: 857 | - blas * mkl 858 | - libcblas 3.9.0 25_win64_mkl 859 | - liblapacke 3.9.0 25_win64_mkl 860 | license: BSD-3-Clause 861 | license_family: BSD 862 | size: 3736560 863 | timestamp: 1729643588182 864 | - kind: conda 865 | name: libnghttp2 866 | version: 1.64.0 867 | build: h161d5f1_0 868 | subdir: linux-64 869 | url: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda 870 | sha256: b0f2b3695b13a989f75d8fd7f4778e1c7aabe3b36db83f0fe80b2cd812c0e975 871 | md5: 19e57602824042dfd0446292ef90488b 872 | depends: 873 | - __glibc >=2.17,<3.0.a0 874 | - c-ares >=1.32.3,<2.0a0 875 | - libev >=4.33,<4.34.0a0 876 | - libev >=4.33,<5.0a0 877 | - libgcc >=13 878 | - libstdcxx >=13 879 | - libzlib >=1.3.1,<2.0a0 880 | - openssl >=3.3.2,<4.0a0 881 | license: MIT 882 | license_family: MIT 883 | size: 647599 884 | timestamp: 1729571887612 885 | - kind: conda 886 | name: libnsl 887 | version: 2.0.1 888 | build: hd590300_0 889 | subdir: linux-64 890 | url: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda 891 | sha256: 26d77a3bb4dceeedc2a41bd688564fe71bf2d149fdcf117049970bc02ff1add6 892 | md5: 30fd6e37fe21f86f4bd26d6ee73eeec7 893 | depends: 894 | - libgcc-ng >=12 895 | license: LGPL-2.1-only 896 | license_family: GPL 897 | size: 33408 898 | timestamp: 1697359010159 899 | - kind: conda 900 | name: libopenblas 901 | version: 0.3.28 902 | build: pthreads_h94d23a6_0 903 | subdir: linux-64 904 | url: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.28-pthreads_h94d23a6_0.conda 905 | sha256: 1e41a6d63e07be996238a1e840a426f86068956a45e0c0bb24e49a8dad9874c1 906 | md5: 9ebc9aedafaa2515ab247ff6bb509458 907 | depends: 908 | - __glibc >=2.17,<3.0.a0 909 | - libgcc-ng >=14 910 | - libgfortran-ng 911 | - libgfortran5 >=14.1.0 912 | constrains: 913 | - openblas >=0.3.28,<0.3.29.0a0 914 | license: BSD-3-Clause 915 | license_family: BSD 916 | size: 5572213 917 | timestamp: 1723932528810 918 | - kind: conda 919 | name: libosqp 920 | version: 0.6.2 921 | build: h63175ca_4 922 | build_number: 4 923 | subdir: win-64 924 | url: https://conda.anaconda.org/conda-forge/win-64/libosqp-0.6.2-h63175ca_4.conda 925 | sha256: 7b1bd40712b792de49c3541788bfc80b8d362a99fbd6f48f74cfd645a3335354 926 | md5: 3bc7345cec066e85b38bd54b4a0d5bb1 927 | depends: 928 | - libqdldl >=0.1.5,<0.1.6.0a0 929 | - ucrt >=10.0.20348.0 930 | - vc >=14.2,<15 931 | - vs2015_runtime >=14.29.30139 932 | license: Apache-2.0 933 | license_family: APACHE 934 | size: 72974 935 | timestamp: 1672824232941 936 | - kind: conda 937 | name: libqdldl 938 | version: 0.1.5 939 | build: h63175ca_1 940 | build_number: 1 941 | subdir: win-64 942 | url: https://conda.anaconda.org/conda-forge/win-64/libqdldl-0.1.5-h63175ca_1.tar.bz2 943 | sha256: 5d2050ea36f32b009712accc9eeb34d731a56f2d5dd27eb40f64870eb0f9d901 944 | md5: 6a8beb414077e9aa543c0897541f69ad 945 | depends: 946 | - ucrt >=10.0.20348.0 947 | - vc >=14.2,<15 948 | - vs2015_runtime >=14.29.30139 949 | license: Apache-2.0 950 | license_family: APACHE 951 | size: 20960 952 | timestamp: 1667007089765 953 | - kind: conda 954 | name: libsqlite 955 | version: 3.47.0 956 | build: h2466b09_1 957 | build_number: 1 958 | subdir: win-64 959 | url: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.47.0-h2466b09_1.conda 960 | sha256: 3342d6fe787f5830f7e8466d9c65c914bfd8d67220fb5673041b338cbba47afe 961 | md5: 5b1f36012cc3d09c4eb9f24ad0e2c379 962 | depends: 963 | - ucrt >=10.0.20348.0 964 | - vc >=14.2,<15 965 | - vc14_runtime >=14.29.30139 966 | license: Unlicense 967 | size: 892175 968 | timestamp: 1730208431651 969 | - kind: conda 970 | name: libsqlite 971 | version: 3.47.0 972 | build: hadc24fc_1 973 | build_number: 1 974 | subdir: linux-64 975 | url: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.47.0-hadc24fc_1.conda 976 | sha256: 8a9aadf996a2399f65b679c6e7f29139d5059f699c63e6d7b50e20db10c00508 977 | md5: b6f02b52a174e612e89548f4663ce56a 978 | depends: 979 | - __glibc >=2.17,<3.0.a0 980 | - libgcc >=13 981 | - libzlib >=1.3.1,<2.0a0 982 | license: Unlicense 983 | size: 875349 984 | timestamp: 1730208050020 985 | - kind: conda 986 | name: libssh2 987 | version: 1.11.0 988 | build: h0841786_0 989 | subdir: linux-64 990 | url: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda 991 | sha256: 50e47fd9c4f7bf841a11647ae7486f65220cfc988ec422a4475fe8d5a823824d 992 | md5: 1f5a58e686b13bcfde88b93f547d23fe 993 | depends: 994 | - libgcc-ng >=12 995 | - libzlib >=1.2.13,<2.0.0a0 996 | - openssl >=3.1.1,<4.0a0 997 | license: BSD-3-Clause 998 | license_family: BSD 999 | size: 271133 1000 | timestamp: 1685837707056 1001 | - kind: conda 1002 | name: libstdcxx 1003 | version: 14.2.0 1004 | build: hc0a3c3a_1 1005 | build_number: 1 1006 | subdir: linux-64 1007 | url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-hc0a3c3a_1.conda 1008 | sha256: 4661af0eb9bdcbb5fb33e5d0023b001ad4be828fccdcc56500059d56f9869462 1009 | md5: 234a5554c53625688d51062645337328 1010 | depends: 1011 | - libgcc 14.2.0 h77fa898_1 1012 | license: GPL-3.0-only WITH GCC-exception-3.1 1013 | license_family: GPL 1014 | size: 3893695 1015 | timestamp: 1729027746910 1016 | - kind: conda 1017 | name: libstdcxx-ng 1018 | version: 14.2.0 1019 | build: h4852527_1 1020 | build_number: 1 1021 | subdir: linux-64 1022 | url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.2.0-h4852527_1.conda 1023 | sha256: 25bb30b827d4f6d6f0522cc0579e431695503822f144043b93c50237017fffd8 1024 | md5: 8371ac6457591af2cf6159439c1fd051 1025 | depends: 1026 | - libstdcxx 14.2.0 hc0a3c3a_1 1027 | license: GPL-3.0-only WITH GCC-exception-3.1 1028 | license_family: GPL 1029 | size: 54105 1030 | timestamp: 1729027780628 1031 | - kind: conda 1032 | name: libuuid 1033 | version: 2.38.1 1034 | build: h0b41bf4_0 1035 | subdir: linux-64 1036 | url: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda 1037 | sha256: 787eb542f055a2b3de553614b25f09eefb0a0931b0c87dbcce6efdfd92f04f18 1038 | md5: 40b61aab5c7ba9ff276c41cfffe6b80b 1039 | depends: 1040 | - libgcc-ng >=12 1041 | license: BSD-3-Clause 1042 | license_family: BSD 1043 | size: 33601 1044 | timestamp: 1680112270483 1045 | - kind: conda 1046 | name: libxcrypt 1047 | version: 4.4.36 1048 | build: hd590300_1 1049 | build_number: 1 1050 | subdir: linux-64 1051 | url: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda 1052 | sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c 1053 | md5: 5aa797f8787fe7a17d1b0821485b5adc 1054 | depends: 1055 | - libgcc-ng >=12 1056 | license: LGPL-2.1-or-later 1057 | size: 100393 1058 | timestamp: 1702724383534 1059 | - kind: conda 1060 | name: libxml2 1061 | version: 2.13.5 1062 | build: h442d1da_0 1063 | subdir: win-64 1064 | url: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.5-h442d1da_0.conda 1065 | sha256: 020466b17c143190bd5a6540be2ceef4c1f8d514408bd5f0adaafcd9d0057b5c 1066 | md5: 1fbabbec60a3c7c519a5973b06c3b2f4 1067 | depends: 1068 | - libiconv >=1.17,<2.0a0 1069 | - libzlib >=1.3.1,<2.0a0 1070 | - ucrt >=10.0.20348.0 1071 | - vc >=14.2,<15 1072 | - vc14_runtime >=14.29.30139 1073 | license: MIT 1074 | license_family: MIT 1075 | size: 1511585 1076 | timestamp: 1731489892312 1077 | - kind: conda 1078 | name: libzlib 1079 | version: 1.3.1 1080 | build: h2466b09_2 1081 | build_number: 2 1082 | subdir: win-64 1083 | url: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda 1084 | sha256: ba945c6493449bed0e6e29883c4943817f7c79cbff52b83360f7b341277c6402 1085 | md5: 41fbfac52c601159df6c01f875de31b9 1086 | depends: 1087 | - ucrt >=10.0.20348.0 1088 | - vc >=14.2,<15 1089 | - vc14_runtime >=14.29.30139 1090 | constrains: 1091 | - zlib 1.3.1 *_2 1092 | license: Zlib 1093 | license_family: Other 1094 | size: 55476 1095 | timestamp: 1727963768015 1096 | - kind: conda 1097 | name: libzlib 1098 | version: 1.3.1 1099 | build: hb9d3cd8_2 1100 | build_number: 2 1101 | subdir: linux-64 1102 | url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda 1103 | sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 1104 | md5: edb0dca6bc32e4f4789199455a1dbeb8 1105 | depends: 1106 | - __glibc >=2.17,<3.0.a0 1107 | - libgcc >=13 1108 | constrains: 1109 | - zlib 1.3.1 *_2 1110 | license: Zlib 1111 | license_family: Other 1112 | size: 60963 1113 | timestamp: 1727963148474 1114 | - kind: conda 1115 | name: llvm-meta 1116 | version: 5.0.0 1117 | build: '0' 1118 | subdir: noarch 1119 | noarch: generic 1120 | url: https://conda.anaconda.org/conda-forge/noarch/llvm-meta-5.0.0-0.tar.bz2 1121 | sha256: 090bbeacc3297ff579b53f55ad184f05c30e316fe9d5d7df63df1d2ad4578b79 1122 | md5: 213b5b5ad34008147a824460e50a691c 1123 | license: BSD-3-Clause 1124 | license_family: BSD 1125 | size: 2667 1126 | - kind: conda 1127 | name: metis 1128 | version: 5.1.0 1129 | build: h17e2fc9_1007 1130 | build_number: 1007 1131 | subdir: win-64 1132 | url: https://conda.anaconda.org/conda-forge/win-64/metis-5.1.0-h17e2fc9_1007.conda 1133 | sha256: 4c1dff710c59bb42a7a5d3e77f1772585c56df9fd62744b53b554bbdb682e2a8 1134 | md5: b1885dc9fc4136aba77ca8ac6c3c307a 1135 | depends: 1136 | - ucrt >=10.0.20348.0 1137 | - vc >=14.2,<15 1138 | - vc14_runtime >=14.29.30139 1139 | license: Apache-2.0 1140 | license_family: APACHE 1141 | size: 4139214 1142 | timestamp: 1728064718935 1143 | - kind: conda 1144 | name: metis 1145 | version: 5.1.0 1146 | build: hd0bcaf9_1007 1147 | build_number: 1007 1148 | subdir: linux-64 1149 | url: https://conda.anaconda.org/conda-forge/linux-64/metis-5.1.0-hd0bcaf9_1007.conda 1150 | sha256: e8a00971e6d00bd49f375c5d8d005b37a9abba0b1768533aed0f90a422bf5cc7 1151 | md5: 28eb714416de4eb83e2cbc47e99a1b45 1152 | depends: 1153 | - __glibc >=2.17,<3.0.a0 1154 | - libgcc >=13 1155 | - libstdcxx >=13 1156 | license: Apache-2.0 1157 | license_family: APACHE 1158 | size: 3923560 1159 | timestamp: 1728064567817 1160 | - kind: conda 1161 | name: mkl 1162 | version: 2024.2.2 1163 | build: h66d3029_14 1164 | build_number: 14 1165 | subdir: win-64 1166 | url: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.2.2-h66d3029_14.conda 1167 | sha256: 098ba4a3cb82f627bc79dc0ab1111b44859c9ef4aaa8d75ce043bce107770cb3 1168 | md5: f011e7cc21918dc9d1efe0209e27fa16 1169 | depends: 1170 | - intel-openmp 2024.* 1171 | - tbb 2021.* 1172 | license: LicenseRef-IntelSimplifiedSoftwareOct2022 1173 | license_family: Proprietary 1174 | size: 103019089 1175 | timestamp: 1727378392081 1176 | - kind: conda 1177 | name: mumps-seq 1178 | version: 5.2.1 1179 | build: h1f49738_14 1180 | build_number: 14 1181 | subdir: win-64 1182 | url: https://conda.anaconda.org/conda-forge/win-64/mumps-seq-5.2.1-h1f49738_14.conda 1183 | sha256: 718bc0a54a34f6dcf2221bcd6557b706f16d43e2fbe31e79e6f557534e5bc4b6 1184 | md5: 793026cd946ca04c37a6903fefeef62b 1185 | depends: 1186 | - libblas >=3.9.0,<4.0a0 1187 | - libflang >=5.0.0,<6.0.0.a0 1188 | - liblapack >=3.9.0,<4.0a0 1189 | - ucrt >=10.0.20348.0 1190 | - vc >=14.2,<15 1191 | - vc14_runtime >=14.29.30139 1192 | license: CECILL-C 1193 | size: 2765952 1194 | timestamp: 1702304778125 1195 | - kind: conda 1196 | name: ncurses 1197 | version: '6.5' 1198 | build: he02047a_1 1199 | build_number: 1 1200 | subdir: linux-64 1201 | url: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-he02047a_1.conda 1202 | sha256: 6a1d5d8634c1a07913f1c525db6455918cbc589d745fac46d9d6e30340c8731a 1203 | md5: 70caf8bb6cf39a0b6b7efc885f51c0fe 1204 | depends: 1205 | - __glibc >=2.17,<3.0.a0 1206 | - libgcc-ng >=12 1207 | license: X11 AND BSD-3-Clause 1208 | size: 889086 1209 | timestamp: 1724658547447 1210 | - kind: conda 1211 | name: numpy 1212 | version: 1.26.4 1213 | build: py311h0b4df5a_0 1214 | subdir: win-64 1215 | url: https://conda.anaconda.org/conda-forge/win-64/numpy-1.26.4-py311h0b4df5a_0.conda 1216 | sha256: 14116e72107de3089cc58119a5ce5905c22abf9a715c9fe41f8ac14db0992326 1217 | md5: 7b240edd44fd7a0991aa409b07cee776 1218 | depends: 1219 | - libblas >=3.9.0,<4.0a0 1220 | - libcblas >=3.9.0,<4.0a0 1221 | - liblapack >=3.9.0,<4.0a0 1222 | - python >=3.11,<3.12.0a0 1223 | - python_abi 3.11.* *_cp311 1224 | - ucrt >=10.0.20348.0 1225 | - vc >=14.2,<15 1226 | - vc14_runtime >=14.29.30139 1227 | constrains: 1228 | - numpy-base <0a0 1229 | license: BSD-3-Clause 1230 | license_family: BSD 1231 | size: 7104093 1232 | timestamp: 1707226459646 1233 | - kind: conda 1234 | name: numpy 1235 | version: 1.26.4 1236 | build: py39h474f0d3_0 1237 | subdir: linux-64 1238 | url: https://conda.anaconda.org/conda-forge/linux-64/numpy-1.26.4-py39h474f0d3_0.conda 1239 | sha256: fa792c330e1d18854e4ca1ea8bf90ffae6787c133ebdc331f1ba6f565d28b599 1240 | md5: aa265f5697237aa13cc10f53fa8acc4f 1241 | depends: 1242 | - libblas >=3.9.0,<4.0a0 1243 | - libcblas >=3.9.0,<4.0a0 1244 | - libgcc-ng >=12 1245 | - liblapack >=3.9.0,<4.0a0 1246 | - libstdcxx-ng >=12 1247 | - python >=3.9,<3.10.0a0 1248 | - python_abi 3.9.* *_cp39 1249 | constrains: 1250 | - numpy-base <0a0 1251 | license: BSD-3-Clause 1252 | license_family: BSD 1253 | size: 7039431 1254 | timestamp: 1707225726227 1255 | - kind: conda 1256 | name: openmp 1257 | version: 5.0.0 1258 | build: vc14_1 1259 | build_number: 1 1260 | subdir: win-64 1261 | url: https://conda.anaconda.org/conda-forge/win-64/openmp-5.0.0-vc14_1.tar.bz2 1262 | sha256: 05c19170938b589f59049679d4e0679c98160fecc6fd1bf721b0f4980bd235dd 1263 | md5: 8284c925330fa53668ade00db3c9e787 1264 | depends: 1265 | - llvm-meta 5.0.0|5.0.0.* 1266 | - vc 14.* 1267 | arch: x86_64 1268 | platform: win 1269 | license: NCSA 1270 | size: 590466 1271 | - kind: conda 1272 | name: openssl 1273 | version: 3.4.0 1274 | build: h2466b09_0 1275 | subdir: win-64 1276 | url: https://conda.anaconda.org/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda 1277 | sha256: e03045a0837e01ff5c75e9273a572553e7522290799807f918c917a9826a6484 1278 | md5: d0d805d9b5524a14efb51b3bff965e83 1279 | depends: 1280 | - ca-certificates 1281 | - ucrt >=10.0.20348.0 1282 | - vc >=14.2,<15 1283 | - vc14_runtime >=14.29.30139 1284 | license: Apache-2.0 1285 | license_family: Apache 1286 | size: 8491156 1287 | timestamp: 1731379715927 1288 | - kind: conda 1289 | name: openssl 1290 | version: 3.4.0 1291 | build: hb9d3cd8_0 1292 | subdir: linux-64 1293 | url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda 1294 | sha256: 814b9dff1847b132c676ee6cc1a8cb2d427320779b93e1b6d76552275c128705 1295 | md5: 23cc74f77eb99315c0360ec3533147a9 1296 | depends: 1297 | - __glibc >=2.17,<3.0.a0 1298 | - ca-certificates 1299 | - libgcc >=13 1300 | license: Apache-2.0 1301 | license_family: Apache 1302 | size: 2947466 1303 | timestamp: 1731377666602 1304 | - kind: conda 1305 | name: pcre2 1306 | version: '10.44' 1307 | build: hba22ea6_2 1308 | build_number: 2 1309 | subdir: linux-64 1310 | url: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hba22ea6_2.conda 1311 | sha256: 1087716b399dab91cc9511d6499036ccdc53eb29a288bebcb19cf465c51d7c0d 1312 | md5: df359c09c41cd186fffb93a2d87aa6f5 1313 | depends: 1314 | - __glibc >=2.17,<3.0.a0 1315 | - bzip2 >=1.0.8,<2.0a0 1316 | - libgcc-ng >=12 1317 | - libzlib >=1.3.1,<2.0a0 1318 | license: BSD-3-Clause 1319 | license_family: BSD 1320 | size: 952308 1321 | timestamp: 1723488734144 1322 | - kind: conda 1323 | name: perl 1324 | version: 5.32.1 1325 | build: 7_hd590300_perl5 1326 | build_number: 7 1327 | subdir: linux-64 1328 | url: https://conda.anaconda.org/conda-forge/linux-64/perl-5.32.1-7_hd590300_perl5.conda 1329 | sha256: 9ec32b6936b0e37bcb0ed34f22ec3116e75b3c0964f9f50ecea5f58734ed6ce9 1330 | md5: f2cfec9406850991f4e3d960cc9e3321 1331 | depends: 1332 | - libgcc-ng >=12 1333 | - libxcrypt >=4.4.36 1334 | license: GPL-1.0-or-later OR Artistic-1.0-Perl 1335 | size: 13344463 1336 | timestamp: 1703310653947 1337 | - kind: conda 1338 | name: pthreads-win32 1339 | version: 2.9.1 1340 | build: h2466b09_4 1341 | build_number: 4 1342 | subdir: win-64 1343 | url: https://conda.anaconda.org/conda-forge/win-64/pthreads-win32-2.9.1-h2466b09_4.conda 1344 | sha256: b989bdcf0a22ba05a238adac1ad3452c11871681f565e509f629e225a26b7d45 1345 | md5: cf98a67a1ec8040b42455002a24f0b0b 1346 | depends: 1347 | - ucrt >=10.0.20348.0 1348 | - vc >=14.2,<15 1349 | - vc14_runtime >=14.29.30139 1350 | license: LGPL-2.1-or-later 1351 | size: 265827 1352 | timestamp: 1728400965968 1353 | - kind: conda 1354 | name: python 1355 | version: 3.9.20 1356 | build: h13acc7a_1_cpython 1357 | build_number: 1 1358 | subdir: linux-64 1359 | url: https://conda.anaconda.org/conda-forge/linux-64/python-3.9.20-h13acc7a_1_cpython.conda 1360 | sha256: 6a30aa8df1745eded1e5c24d167cb10e6f379e75d2f2fa2a212e6dab76030698 1361 | md5: 951cff166a5f170e27908811917165f8 1362 | depends: 1363 | - __glibc >=2.17,<3.0.a0 1364 | - bzip2 >=1.0.8,<2.0a0 1365 | - ld_impl_linux-64 >=2.36.1 1366 | - libffi >=3.4,<4.0a0 1367 | - libgcc >=13 1368 | - libnsl >=2.0.1,<2.1.0a0 1369 | - libsqlite >=3.46.1,<4.0a0 1370 | - libuuid >=2.38.1,<3.0a0 1371 | - libxcrypt >=4.4.36 1372 | - libzlib >=1.3.1,<2.0a0 1373 | - ncurses >=6.5,<7.0a0 1374 | - openssl >=3.3.2,<4.0a0 1375 | - readline >=8.2,<9.0a0 1376 | - tk >=8.6.13,<8.7.0a0 1377 | - tzdata 1378 | - xz >=5.2.6,<6.0a0 1379 | constrains: 1380 | - python_abi 3.9.* *_cp39 1381 | license: Python-2.0 1382 | size: 23684398 1383 | timestamp: 1727719528404 1384 | - kind: conda 1385 | name: python 1386 | version: 3.11.10 1387 | build: hce54a09_3_cpython 1388 | build_number: 3 1389 | subdir: win-64 1390 | url: https://conda.anaconda.org/conda-forge/win-64/python-3.11.10-hce54a09_3_cpython.conda 1391 | sha256: 3931c546219d069918389e4dbe12057af4cc68a1060577a04014c6b5fc618aa0 1392 | md5: 5d54d429c0eb2273d1cc69763de6edaf 1393 | depends: 1394 | - bzip2 >=1.0.8,<2.0a0 1395 | - libexpat >=2.6.3,<3.0a0 1396 | - libffi >=3.4,<4.0a0 1397 | - libsqlite >=3.46.1,<4.0a0 1398 | - libzlib >=1.3.1,<2.0a0 1399 | - openssl >=3.3.2,<4.0a0 1400 | - tk >=8.6.13,<8.7.0a0 1401 | - tzdata 1402 | - ucrt >=10.0.20348.0 1403 | - vc >=14.2,<15 1404 | - vc14_runtime >=14.29.30139 1405 | - xz >=5.2.6,<6.0a0 1406 | constrains: 1407 | - python_abi 3.11.* *_cp311 1408 | license: Python-2.0 1409 | size: 18206702 1410 | timestamp: 1729041779073 1411 | - kind: conda 1412 | name: python_abi 1413 | version: '3.9' 1414 | build: 5_cp39 1415 | build_number: 5 1416 | subdir: linux-64 1417 | url: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.9-5_cp39.conda 1418 | sha256: 019e2f8bca1d1f1365fbb9965cd95bb395c92c89ddd03165db82f5ae89a20812 1419 | md5: 40363a30db350596b5f225d0d5a33328 1420 | constrains: 1421 | - python 3.9.* *_cpython 1422 | license: BSD-3-Clause 1423 | license_family: BSD 1424 | size: 6193 1425 | timestamp: 1723823354399 1426 | - kind: conda 1427 | name: python_abi 1428 | version: '3.11' 1429 | build: 5_cp311 1430 | build_number: 5 1431 | subdir: win-64 1432 | url: https://conda.anaconda.org/conda-forge/win-64/python_abi-3.11-5_cp311.conda 1433 | sha256: 9b210e5807dd9c9ed71ff192a95f1872da597ddd10e7cefec93a922fe22e598a 1434 | md5: 895b873644c11ccc0ab7dba2d8513ae6 1435 | constrains: 1436 | - python 3.11.* *_cpython 1437 | license: BSD-3-Clause 1438 | license_family: BSD 1439 | size: 6707 1440 | timestamp: 1723823225752 1441 | - kind: conda 1442 | name: readline 1443 | version: '8.2' 1444 | build: h8228510_1 1445 | build_number: 1 1446 | subdir: linux-64 1447 | url: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda 1448 | sha256: 5435cf39d039387fbdc977b0a762357ea909a7694d9528ab40f005e9208744d7 1449 | md5: 47d31b792659ce70f470b5c82fdfb7a4 1450 | depends: 1451 | - libgcc-ng >=12 1452 | - ncurses >=6.3,<7.0a0 1453 | license: GPL-3.0-only 1454 | license_family: GPL 1455 | size: 281456 1456 | timestamp: 1679532220005 1457 | - kind: conda 1458 | name: tbb 1459 | version: 2021.13.0 1460 | build: hc790b64_0 1461 | subdir: win-64 1462 | url: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.13.0-hc790b64_0.conda 1463 | sha256: 990dbe4fb42f14700c22bd434d8312607bf8d0bd9f922b054e51fda14c41994c 1464 | md5: 28496a1e6af43c63927da4f80260348d 1465 | depends: 1466 | - libhwloc >=2.11.1,<2.11.2.0a0 1467 | - ucrt >=10.0.20348.0 1468 | - vc >=14.2,<15 1469 | - vc14_runtime >=14.29.30139 1470 | license: Apache-2.0 1471 | license_family: APACHE 1472 | size: 151494 1473 | timestamp: 1725532984828 1474 | - kind: conda 1475 | name: tk 1476 | version: 8.6.13 1477 | build: h5226925_1 1478 | build_number: 1 1479 | subdir: win-64 1480 | url: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda 1481 | sha256: 2c4e914f521ccb2718946645108c9bd3fc3216ba69aea20c2c3cedbd8db32bb1 1482 | md5: fc048363eb8f03cd1737600a5d08aafe 1483 | depends: 1484 | - ucrt >=10.0.20348.0 1485 | - vc >=14.2,<15 1486 | - vc14_runtime >=14.29.30139 1487 | license: TCL 1488 | license_family: BSD 1489 | size: 3503410 1490 | timestamp: 1699202577803 1491 | - kind: conda 1492 | name: tk 1493 | version: 8.6.13 1494 | build: noxft_h4845f30_101 1495 | build_number: 101 1496 | subdir: linux-64 1497 | url: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda 1498 | sha256: e0569c9caa68bf476bead1bed3d79650bb080b532c64a4af7d8ca286c08dea4e 1499 | md5: d453b98d9c83e71da0741bb0ff4d76bc 1500 | depends: 1501 | - libgcc-ng >=12 1502 | - libzlib >=1.2.13,<2.0.0a0 1503 | license: TCL 1504 | license_family: BSD 1505 | size: 3318875 1506 | timestamp: 1699202167581 1507 | - kind: conda 1508 | name: tzdata 1509 | version: 2024b 1510 | build: hc8b5060_0 1511 | subdir: noarch 1512 | noarch: generic 1513 | url: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda 1514 | sha256: 4fde5c3008bf5d2db82f2b50204464314cc3c91c1d953652f7bd01d9e52aefdf 1515 | md5: 8ac3367aafb1cc0a068483c580af8015 1516 | license: LicenseRef-Public-Domain 1517 | size: 122354 1518 | timestamp: 1728047496079 1519 | - kind: conda 1520 | name: ucrt 1521 | version: 10.0.22621.0 1522 | build: h57928b3_1 1523 | build_number: 1 1524 | subdir: win-64 1525 | url: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda 1526 | sha256: db8dead3dd30fb1a032737554ce91e2819b43496a0db09927edf01c32b577450 1527 | md5: 6797b005cd0f439c4c5c9ac565783700 1528 | constrains: 1529 | - vs2015_runtime >=14.29.30037 1530 | license: LicenseRef-MicrosoftWindowsSDK10 1531 | size: 559710 1532 | timestamp: 1728377334097 1533 | - kind: conda 1534 | name: unixodbc 1535 | version: 2.3.12 1536 | build: h661eb56_0 1537 | subdir: linux-64 1538 | url: https://conda.anaconda.org/conda-forge/linux-64/unixodbc-2.3.12-h661eb56_0.conda 1539 | sha256: 718eb807a5e6e6993ee06745cb2a25a6b353427485a6e50df01db99c6016a53f 1540 | md5: a737e5c549c13fbb5590c581848b0446 1541 | depends: 1542 | - libedit >=3.1.20191231,<3.2.0a0 1543 | - libgcc-ng >=12 1544 | - libiconv >=1.17,<2.0a0 1545 | - libstdcxx-ng >=12 1546 | license: LGPL-2.1 1547 | size: 281830 1548 | timestamp: 1691504075258 1549 | - kind: conda 1550 | name: vc 1551 | version: '14.3' 1552 | build: ha32ba9b_22 1553 | build_number: 22 1554 | subdir: win-64 1555 | url: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_22.conda 1556 | sha256: 2a47c5bd8bec045959afada7063feacd074ad66b170c1ea92dd139b389fcf8fd 1557 | md5: 311c9ba1dfdd2895a8cb08346ff26259 1558 | depends: 1559 | - vc14_runtime >=14.38.33135 1560 | track_features: 1561 | - vc14 1562 | license: BSD-3-Clause 1563 | license_family: BSD 1564 | size: 17447 1565 | timestamp: 1728400826998 1566 | - kind: conda 1567 | name: vc14_runtime 1568 | version: 14.40.33810 1569 | build: hcc2c482_22 1570 | build_number: 22 1571 | subdir: win-64 1572 | url: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.40.33810-hcc2c482_22.conda 1573 | sha256: 4c669c65007f88a7cdd560192f7e6d5679d191ac71610db724e18b2410964d64 1574 | md5: ce23a4b980ee0556a118ed96550ff3f3 1575 | depends: 1576 | - ucrt >=10.0.20348.0 1577 | constrains: 1578 | - vs2015_runtime 14.40.33810.* *_22 1579 | license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime 1580 | license_family: Proprietary 1581 | size: 750719 1582 | timestamp: 1728401055788 1583 | - kind: conda 1584 | name: vs2015_runtime 1585 | version: 14.40.33810 1586 | build: h3bf8584_22 1587 | build_number: 22 1588 | subdir: win-64 1589 | url: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.40.33810-h3bf8584_22.conda 1590 | sha256: 80aa9932203d65a96f817b8be4fafc176fb2b3fe6cf6899ede678b8f0317fbff 1591 | md5: 8c6b061d44cafdfc8e8c6eb5f100caf0 1592 | depends: 1593 | - vc14_runtime >=14.40.33810 1594 | license: BSD-3-Clause 1595 | license_family: BSD 1596 | size: 17453 1597 | timestamp: 1728400827536 1598 | - kind: conda 1599 | name: xz 1600 | version: 5.2.6 1601 | build: h166bdaf_0 1602 | subdir: linux-64 1603 | url: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 1604 | sha256: 03a6d28ded42af8a347345f82f3eebdd6807a08526d47899a42d62d319609162 1605 | md5: 2161070d867d1b1204ea749c8eec4ef0 1606 | depends: 1607 | - libgcc-ng >=12 1608 | license: LGPL-2.1 and GPL-2.0 1609 | size: 418368 1610 | timestamp: 1660346797927 1611 | - kind: conda 1612 | name: xz 1613 | version: 5.2.6 1614 | build: h8d14728_0 1615 | subdir: win-64 1616 | url: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 1617 | sha256: 54d9778f75a02723784dc63aff4126ff6e6749ba21d11a6d03c1f4775f269fe0 1618 | md5: 515d77642eaa3639413c6b1bc3f94219 1619 | depends: 1620 | - vc >=14.1,<15 1621 | - vs2015_runtime >=14.16.27033 1622 | license: LGPL-2.1 and GPL-2.0 1623 | size: 217804 1624 | timestamp: 1660346976440 1625 | - kind: conda 1626 | name: zstd 1627 | version: 1.5.6 1628 | build: ha6fb4c9_0 1629 | subdir: linux-64 1630 | url: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.6-ha6fb4c9_0.conda 1631 | sha256: c558b9cc01d9c1444031bd1ce4b9cff86f9085765f17627a6cd85fc623c8a02b 1632 | md5: 4d056880988120e29d75bfff282e0f45 1633 | depends: 1634 | - libgcc-ng >=12 1635 | - libstdcxx-ng >=12 1636 | - libzlib >=1.2.13,<2.0.0a0 1637 | license: BSD-3-Clause 1638 | license_family: BSD 1639 | size: 554846 1640 | timestamp: 1714722996770 1641 | --------------------------------------------------------------------------------