FTSensorTrigger.cpp
Go to the documentation of this file.
1/**
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @author Fabian Reister ( fabian dot reister at kit dot edu )
17 * @date 2022
18 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
19 * GNU General Public License
20 */
21
22#include "FTSensorTrigger.h"
23
28
30
32{
33
35 const std::string& robotName,
37 const Params& params) :
38 robotReader(robotReader), robotName(robotName), hand(hand), params(params)
39 {
40 ARMARX_INFO << "creating FTSensorTrigger";
41 }
42
43 void
45 {
46 ARMARX_VERBOSE << "Waiting for force spike";
47
48 const auto getForce = [&]()
49 {
50 const auto timestamp = Clock::Now();
51
52 const std::optional<std::map<armem::robot_state::RobotReader::Hand,
54 ft = robotReader.queryForceTorque(robotName, timestamp);
55
56
57 if (not ft.has_value())
58 {
59 ARMARX_ERROR << "No FT data available!";
60 }
61
63 std::string frame;
65
67
68 switch (hand)
69 {
70 case Hand::Left:
72 // frame = leftArmHelper.getForceTorqueSensorFrame();
73 break;
74 case Hand::Right:
76 // frame = rightArmHelper.getForceTorqueSensorFrame();
77 break;
78 default:
79 break;
80 }
82
83 const armarx::FramedDirection force(ftVal.force, frame, robotName);
84
85 const float directionalForce =
86 force.toEigen().cwiseProduct(params.forceDetectionMask).norm();
87
88 return directionalForce;
89 };
90
91 ARMARX_INFO << "waiting for force spike";
92 std::deque<float> spikes(params.windowSizeMs / params.cycleTimeMs, getForce());
93 ARMARX_INFO << "size of spikes " << spikes.size();
94
95 while (true) // stop run function if returning true
96 {
97 const float force = getForce();
98 ARMARX_INFO << VAROUT(force);
99
100 spikes.push_back(force);
101 spikes.pop_front();
102
103 float refValue = spikes.at(0);
104 bool low = true;
105 bool risingEdgeDetected = false;
106 bool fallingEdgeDetected = false;
107
108 bool f2rDetected = false;
109 bool r2fDetected = false;
111 for (const float spike : spikes)
112 {
113 if (low)
114 {
115 if (spike < refValue)
116 {
117 refValue = spike;
118 }
119 else if (spike > refValue + params.forceThreshold)
120 {
121 low = false;
122 risingEdgeDetected = true;
123 f2rDetected |= fallingEdgeDetected;
124 }
125 }
126
127 if (!low)
128 {
129 if (spike > refValue)
130 {
131 refValue = spike;
132 }
133 else if (spike < refValue - params.forceThreshold)
134 {
135 low = true;
136 fallingEdgeDetected = true;
137 r2fDetected |= risingEdgeDetected;
138 }
139 }
140 }
142
143 if (f2rDetected)
144 {
145 ARMARX_INFO << "Rising edge detected";
146 }
147
148 if (r2fDetected)
149 {
150 ARMARX_INFO << "Falling edge detected";
151 }
152
153 switch (edge)
154 {
155 case Edge::RISING:
156 {
157 if (f2rDetected)
158 {
159 return;
160 }
161 break;
162 }
163 case Edge::FALLING:
164 {
165 if (r2fDetected)
166 {
167 return;
168 }
169 break;
170 }
171 default:
172 break;
173 }
174
175
176 std::this_thread::sleep_for(std::chrono::milliseconds{params.cycleTimeMs});
177 }
178 }
179
180 void
182 {
183 ARMARX_VERBOSE << "Waiting for force spike";
184
185 const auto getForce = [&]()
186 {
187 const auto timestamp = Clock::Now();
188
189 const std::optional<std::map<armem::robot_state::RobotReader::Hand,
191 ft = robotReader.queryForceTorque(robotName, timestamp);
192
193
194 if (not ft.has_value())
195 {
196 ARMARX_ERROR << "No FT data available!";
197 }
198
200 std::string frame;
202
204
205 switch (hand)
206 {
207 case Hand::Left:
209 // frame = leftArmHelper.getForceTorqueSensorFrame();
210 break;
211 case Hand::Right:
213 // frame = rightArmHelper.getForceTorqueSensorFrame();
214 break;
215 default:
216 break;
217 }
219
220 const armarx::FramedDirection force(ftVal.force, frame, robotName);
221
222 return force.toEigen();
223 };
224 Eigen::Vector3f force_init = getForce();
225 ARMARX_INFO << "--- " << VAROUT(force_init);
226
227 while (true) // stop run function if returning true
228 {
229 const float force_delta = (getForce() - force_init).norm();
230
231 ARMARX_INFO << "--- " << VAROUT(force_delta);
232 if (force_delta > threshold)
233 {
234 ARMARX_INFO << VAROUT(force_init);
235 ARMARX_INFO << "----- force torque is triggered at value " << force_delta;
236 break;
237 }
238 std::this_thread::sleep_for(std::chrono::milliseconds{params.cycleTimeMs});
239 }
240 }
241} // namespace armarx::control::common::ft
std::string timestamp()
#define VAROUT(x)
static DateTime Now()
Current time on the virtual clock.
Definition Clock.cpp:93
FramedDirection is a 3 dimensional direction vector with a reference frame.
Definition FramedPose.h:87
virtual Eigen::Vector3f toEigen() const
Definition Pose.cpp:134
FTSensorTrigger(armarx::armem::robot_state::RobotReader &robotReader, const std::string &robotName, const armem::robot_state::RobotReader::Hand &hand, const Params &params=Params())
void waitForForceThreshold(float threshold) const
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
This file is part of ArmarX.
double norm(const Point &a)
Definition point.hpp:102
#define ARMARX_TRACE
Definition trace.h:77