You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+31-17Lines changed: 31 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,15 +41,28 @@ $ sudo make install
41
41
42
42
## Usage Example
43
43
44
-
The typical TPIK workflow is the following:
44
+
The following example shows the typical TPIK workflow:
45
45
46
-
1. define one or more tasks,
47
-
2. assign them to priority levels,
48
-
3. group priority levels into actions,
49
-
4. create a solver with an inverse kinematics backend,
50
-
5. select an action and compute joint velocities.
46
+
1. create one or more tasks,
47
+
2. define how each task updates its Jacobian, activation, and reference,
48
+
3. assign tasks to priority levels,
49
+
4. group priority levels into actions,
50
+
5. create a solver and compute joint velocities for the selected action.
51
+
52
+
In this example, `TestTask` is a simple reactive task derived from `tpik::ReactiveTask`. Its `Update()` method refreshes:
53
+
54
+
* the internal activation matrix,
55
+
* the Jacobian,
56
+
* and the task reference.
57
+
58
+
In particular, the reference is set inside `UpdateReference()` of the `TestTask` through:
59
+
60
+
```cpp
61
+
x_dot_bar_ = Eigen::VectorXd::Ones(6);
62
+
```
63
+
64
+
so each time `Update()` is called, the task target velocity reference is updated accordingly. An example usage of this class is the following:
51
65
52
-
The following example code creates two tasks, assigns them to two priority levels, and then defines three actions that enable different subsets of the hierarchy. A `tpik::Solver` is then instantiated with an `iCAT` backend and used to compute velocity commands for the currently selected action. The active action can be changed at runtime with `SetAction(...)`, allowing the controller to switch behavior without rebuilding the whole hierarchy.
53
66
54
67
```cpp
55
68
#include"test/TestTask.h"
@@ -80,6 +93,7 @@ int main()
80
93
auto task1 = std::make_shared<TestTask>(ID1);
81
94
auto task2 = std::make_shared<TestTask>(ID2);
82
95
96
+
// Set task gains
83
97
auto gain1 = std::make_shared<Eigen::MatrixXd>(
84
98
Eigen::MatrixXd::Identity(taskSpace, DoF));
85
99
auto gain2 = std::make_shared<Eigen::MatrixXd>(
@@ -88,6 +102,7 @@ int main()
88
102
task1->SetGain(gain1);
89
103
task2->SetGain(gain2);
90
104
105
+
// Update each task: activation, Jacobian, and reference are refreshed here
91
106
task1->Update();
92
107
task2->Update();
93
108
@@ -139,19 +154,18 @@ int main()
139
154
}
140
155
```
141
156
142
-
### Key classes
143
157
144
-
*`TestTask`: example task implementation
145
-
*`tpik::ActionManager`: manages tasks, priority levels, and actions
146
-
*`tpik::iCAT`: inverse kinematics backend
147
-
*`tpik::Solver`: computes the output velocities from the active action
158
+
This example creates two reactive tasks and updates them before solving. In `TestTask`, the Jacobian is built from the assigned gain matrix, while the task reference is explicitly set in `UpdateReference()` through `x_dot_bar_`. This means that the desired task-space behavior is not passed directly in `main()`, but encapsulated inside the task implementation itself.
159
+
160
+
The tasks are then assigned to two priority levels, and the priority levels are grouped into actions. The solver can switch between actions at runtime with `SetAction(...)`, making it possible to reuse the same hierarchy structure while enabling different control modes.
148
161
149
-
### Notes
162
+
### Key points
150
163
151
-
* Call `Update()` on tasks after changing gains, Jacobians, references, or internal task data.
152
-
* Use `SetUnifiedHierarchy(...)` to define the global task-priority structure.
153
-
* Use `AddAction(...)` to expose reusable control modes built from selected priority levels.
154
-
* Saturation limits can be configured on the IK backend before solving.
164
+
*`Update()` should be called whenever task data changes.
165
+
* The task reference is defined inside the task class through `UpdateReference()`.
166
+
* The Jacobian can also be task-specific and is updated in `UpdateJacobian()`.
167
+
*`ActionManager` organizes tasks into priority levels and actions.
168
+
*`Solver` computes joint velocities from the currently active action.
0 commit comments