File: constraintsolver.cc

package info (click to toggle)
step 4%3A25.08.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,628 kB
  • sloc: cpp: 16,808; xml: 762; python: 380; javascript: 93; sh: 39; makefile: 3
file content (110 lines) | stat: -rw-r--r-- 3,881 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
    SPDX-FileCopyrightText: 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>

    SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "constraintsolver.h"
#include "rigidbody.h"
#include "particle.h"
#include "types.h"
#include <iostream>
#include <unsupported/Eigen/IterativeSolvers>
#include <cmath>

using namespace Eigen;

namespace StepCore {

STEPCORE_META_OBJECT(ConstraintSolver, QT_TRANSLATE_NOOP("ObjectClass", "ConstraintSolver"), "ConstraintSolver", MetaObject::ABSTRACT, STEPCORE_SUPER_CLASS(Object),)
    //STEPCORE_PROPERTY_RW(double, toleranceAbs, QT_TRANSLATE_NOOP("PropertyName", "toleranceAbs"), STEPCORE_UNITS_1, "Allowed absolute tolerance", toleranceAbs, setToleranceAbs)
    //STEPCORE_PROPERTY_R_D(double, localError, QT_TRANSLATE_NOOP("PropertyName", "localError"), STEPCORE_UNITS_1, "Maximal local error during last step", localError))

STEPCORE_META_OBJECT(CGConstraintSolver, QT_TRANSLATE_NOOP("ObjectClass", "CGConstraintSolver"), "CGConstraintSolver", 0,
                        STEPCORE_SUPER_CLASS(ConstraintSolver),)


int CGConstraintSolver::solve(ConstraintsInfo* info)
{
    int nc = info->constraintsCount + info->contactsCount;
    
    // XXX: make this matrixes permanent to avoid memory allocations
    SparseRowMatrix a(nc, nc);
    VectorXd b(nc);
    VectorXd x(nc);
    x.setZero();

    a = info->jacobian * (info->inverseMass.asDiagonal() * info->jacobian.transpose());

    b = info->jacobian * info->acceleration;
    b += info->jacobianDerivative * info->velocity;
    b = - (b + info->value + info->derivative);

    IterationController iter(2.0E-5); // XXX

    // print debug info
    /*std::cout << "ConstraintSolver:" << endl
              << "J=" << info->jacobian << endl
              << "J'=" << info->jacobianDerivative << endl
              << "C=" << info->value << endl
              << "C'=" << info->derivative << endl
              << "invM=" << info->inverseMass << endl
              << "pos=" << info->position << endl
              << "vel=" << info->velocity << endl
              << "acc=" << info->acceleration << endl
              << "a=" << a << endl
              << "b=" << b << endl
              << "l=" << l << endl
              << "force=" << info->force << endl;*/

    // constrained_cg ?
    // XXX: limit iterations count

    // XXX: Use sparce vectors for fmin and fmax
    int fminCount = 0;
    int fmaxCount = 0;
    for(int i=0; i<nc; ++i) {
        if(std::isfinite(info->forceMin[i])) ++fminCount;
        if(std::isfinite(info->forceMax[i])) ++fmaxCount;
    }

    DynSparseRowMatrix c(fminCount + fmaxCount, nc);
    VectorXd f(fminCount + fmaxCount);

    int fminIndex = 0;
    int fmaxIndex = fminCount;
    for(int i=0; i<nc; ++i) {
        if(std::isfinite(info->forceMin[i])) {
            c.coeffRef(fminIndex,i) = -1;
            f[fminIndex] = -info->forceMin[i];
            ++fminIndex;
        }
        if(std::isfinite(info->forceMax[i])) {
            c.coeffRef(fmaxIndex, i) = 1;
            f[fmaxIndex] = info->forceMax[i];
            ++fmaxIndex;
        }
    }    
    internal::constrained_cg(a, c, x, b, f, iter);

    info->force = info->jacobian.transpose() * x;

    // print debug info
    /*std::cout << "Solved:" << endl
              << "J=" << info->jacobian << endl
              << "J'=" << info->jacobianDerivative << endl
              << "C=" << info->value << endl
              << "C'=" << info->derivative << endl
              << "invM=" << info->inverseMass << endl
              << "pos=" << info->position << endl
              << "vel=" << info->velocity << endl
              << "acc=" << info->acceleration << endl
              << "a=" << a << endl
              << "b=" << b << endl
              << "l=" << l << endl
              << "force=" << info->force << endl << endl << endl;*/
    return 0;
}

} // namespace StepCore