summaryrefslogtreecommitdiff
path: root/LocomotorPrimitivesController.cpp
blob: 27ac205ce15f27102d4ca2ed887b8144925a622a (plain)
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
#include <OpenSim/OpenSim.h>

#include "LocomotorPrimitivesController.h"

#define VERBOSE 1

// XXX
extern clock_t ts_start;

static const double TIME_DAMP = 0.1;
static const unsigned int N_PRINT = 1000;

int LocomotorPrimitivesController::checkControls()
{
	const int act_set_siz = getActuatorSet().getSize();
	int ret = 0;

	/* Iterate over all controls in the model and check whether they're
	 * available in the loaded storage */
	for (int i = 0; i < act_set_siz; i++) {
		const OpenSim::Muscle *muscle = dynamic_cast<const OpenSim::Muscle *>(&getActuatorSet().get(i));
		const OpenSim::Array<int> indices = _act.getColumnIndicesForIdentifier(muscle->getName());

		if (indices.getSize() == 0) {
			std::cerr << "Error: no actuation data for muscle '" << muscle->getName() << "' found" << std::endl;
			ret--;
		}
	}

	return ret;
}

void LocomotorPrimitivesController::computeControls(const SimTK::State &s, SimTK::Vector &controls) const
{
	double t = s.getTime();
	static double last_twitch = t;
	static unsigned int n = 0;

	/* Extract muscle activation for each of the muscles */
	const int act_set_siz = getActuatorSet().getSize();
	const int nc = _act.getSmallestNumberOfStates();

	/* Get the first nc states at a specified time (_NOT_ the state at nc as
	 * with getData()). */
	_act.getDataAtTime(t, nc, _muscle_act);

	for (int i = 0; i < act_set_siz; i++) {
		const OpenSim::Muscle *muscle = dynamic_cast<const OpenSim::Muscle *>(&getActuatorSet().get(i));
		const OpenSim::Array<int> indices = _act.getColumnIndicesForIdentifier(muscle->getName());
		double mact;

		if (indices.getSize() != 0) {
			int idx = indices.get(0) - 1;
			if (n % N_PRINT == 0)
				std::cout << "[" << (1.e3 * clock() - ts_start) / CLOCKS_PER_SEC << "ms] " << t << " (" << idx << ") actuation data for '" << muscle->getName() << "' found: " << _muscle_act[idx] << std::endl;

			if (_muscle_act[idx] > 1.0) {
				std::cerr << "Error: muscle actuation larger than 1.0 (" << _muscle_act[idx] << "), truncating" << std::endl;
				_muscle_act[idx] = 1.0;
			}

			mact = _muscle_act[idx];
		} else {
			// no actuation data for muscle at that time, so set it to 0.0
			mact = 0.0;
		}

		SimTK::Vector ctrl(1, mact);
		muscle->addInControls(ctrl, controls);
	}

	n++;
}