21 geometry_msgs::Vector3
operator-(
const geometry_msgs::Point p0,
const geometry_msgs::Point p1)
23 geometry_msgs::Vector3 v;
33 geometry_msgs::Vector3
operator*(
const double s,
const geometry_msgs::Vector3 v)
35 geometry_msgs::Vector3 u;
45 geometry_msgs::Point
operator+(
const geometry_msgs::Point p,
const geometry_msgs::Vector3 v)
47 geometry_msgs::Point pb;
57 geometry_msgs::Point
FIR_cop(
const geometry_msgs::Point cop_prev,
const geometry_msgs::Point cop_new)
59 geometry_msgs::Point cop_filtered;
62 cop_filtered.x = (1-beta)*cop_prev.x + beta*cop_new.x;
63 cop_filtered.y = (1-beta)*cop_prev.y + beta*cop_new.y;
71 geometry_msgs::Vector3
FIR_force(
const geometry_msgs::Vector3 force_prev,
const geometry_msgs::Vector3 force_new)
73 geometry_msgs::Vector3 force_filtered;
76 force_filtered.x = (1-beta)*force_prev.x + beta*force_new.x;
77 force_filtered.y = (1-beta)*force_prev.y + beta*force_new.y;
79 return force_filtered;
104 geometry_msgs::Vector3Stamped
force;
121 cop_global_filtered_pub = nh_.advertise<geometry_msgs::PointStamped>(
"/cop_global_filtered",1000);
122 feedback_force_stability_pub = nh_.advertise<geometry_msgs::Vector3Stamped>(
"/feedback_force_stability",1000);
123 feedback_force_instability_pub = nh_.advertise<geometry_msgs::Vector3Stamped>(
"/feedback_force_instability",1000);
124 feedback_force_pub = nh_.advertise<geometry_msgs::Vector3Stamped>(
"/feedback_force",1000);
125 feedback_force_filtered_pub = nh_.advertise<geometry_msgs::Vector3Stamped>(
"/feedback_force_filtered",1000);
141 phua_position.pose.position.x = msg.pose.position.x;
142 phua_position.pose.position.y = msg.pose.position.y;
143 phua_position.pose.position.z = msg.pose.position.z;
149 geometry_msgs::PointStamped cop_global_new;
151 cop_global_new.point.x = msg.point.x*1000;
152 cop_global_new.point.y = msg.point.y*1000;
156 cop_global.point = cop_global_new.point;
159 cop_global_filtered_pub.publish(cop_global);
166 support_base.polygon.points.clear();
168 for (uint i=0; i<msg.polygon.points.size(); i++)
170 geometry_msgs::Point32 p;
172 p.x = msg.polygon.points[i].x*1000;
173 p.y = msg.polygon.points[i].y*1000;
174 p.z = msg.polygon.points[i].z*1000;
176 support_base.polygon.points.push_back(p);
179 if (wn_PnPoly(cop_global.point, support_base.polygon) != 0)
181 vector<double> distance;
183 for (uint i=0; i<support_base.polygon.points.size()-1; i++)
185 vector<geometry_msgs::Point> segment(2);
187 segment[0].x = support_base.polygon.points[i].x;
188 segment[0].y = support_base.polygon.points[i].y;
190 segment[1].x = support_base.polygon.points[i+1].x;
191 segment[1].y = support_base.polygon.points[i+1].y;
193 distance.push_back(dist_PointSegment(cop_global.point, segment));
196 distance_min = *min_element(distance.begin(), distance.end());
200 calculateFeedback(cop_global, distance_min);
203 ROS_ERROR(
"Center of Pressure is beyond support polygon boundary. System unstable!");
212 geometry_msgs::Vector3Stamped force_stability, force_instability, force_new;
214 double cop_s = sqrt(cop.point.x*cop.point.x + cop.point.y*cop.point.y);
218 double a1 = 0.35, b1 = 40, c1=0.2;
219 double a2 = 0.35, b2 = 16.89733, c2=0.2;
221 double force_f1, force_f2;
225 else if (cop_s >= 5 && cop_s < 28.4490)
226 force_f1 = (0.025*cop_s - 0.125);
227 else if (cop_s >= 28.4490 && cop_s < 40)
228 force_f1 = (1/(c1*(1+exp(-a1*(cop_s - b1)))) + 0.5);
229 else if (cop_s >= 40)
232 if (distance > 51.8972)
234 else if (distance <= 51.8972 && distance > 28.4490)
235 force_f2 = (-(0.025)*(distance) + (1.29743));
236 else if (distance <= 28.4490 && distance > 16.89733)
237 force_f2 = (1/(c2*(1+exp(a2*((distance) - b2)))) + 0.5);
238 else if (distance <= 16.89733)
241 double r1 = (1*force_f1)/cop_s;
242 double r2 = (1*force_f2)/cop_s;
244 force_stability.vector.x = (cop.point.x * r1);
245 force_stability.vector.y = cop.point.y * r1;
246 force_stability.vector.z = 0;
248 force_instability.vector.x = cop.point.x * r2;
249 force_instability.vector.y = cop.point.y * r2;
250 force_instability.vector.z = 0;
271 feedback_force_stability_pub.publish(force_stability);
274 feedback_force_instability_pub.publish(force_instability);
276 double vm_stability_x, vm_stability_y;
277 double vm_instability_x, vm_instability_y;
279 if (force_stability.vector.x - force_stability_prev.vector.x != 0)
280 vm_stability_x = (force_stability.vector.x - force_stability_prev.vector.x) / 0.05;
282 vm_stability_x = (force_stability.vector.x) / 0.05;
284 if (force_instability.vector.x - force_instability_prev.vector.x != 0)
285 vm_instability_x = (force_instability.vector.x - force_instability_prev.vector.x) / 0.05;
287 vm_instability_x = (force_instability.vector.x) / 0.05;
289 if (force_stability.vector.y - force_stability_prev.vector.y != 0)
290 vm_stability_y = (force_stability.vector.y - force_stability_prev.vector.y) / 0.05;
292 vm_stability_y = (force_stability.vector.y) / 0.05;
294 if (force_instability.vector.y - force_instability_prev.vector.y != 0)
295 vm_instability_y = (force_instability.vector.y - force_instability_prev.vector.y) / 0.05;
297 vm_instability_y = (force_instability.vector.y) / 0.05;
301 rvm_x = abs(vm_instability_x / vm_stability_x);
302 rvm_y = abs(vm_instability_y / vm_stability_y);
304 force_new.vector.x = (rvm_x/(rvm_x+1)) * force_instability.vector.x + (1/(rvm_x+1)) * force_stability.vector.x;
305 force_new.vector.y = (rvm_y/(rvm_y+1)) * force_instability.vector.y + (1/(rvm_y+1)) * force_stability.vector.y;
306 force_new.vector.z = 0;
308 if (force_instability.vector.x == 0 || force_stability.vector.x == 0)
309 force_new.vector.x = force_instability.vector.x + force_stability.vector.x;
311 if (force_instability.vector.y == 0 || force_stability.vector.y == 0)
312 force_new.vector.y = force_instability.vector.y + force_stability.vector.y;
315 feedback_force_pub.publish(force_new);
318 force.vector =
FIR_force(force.vector, force_new.vector);
321 cout <<
"Force vector filtered = " <<
'(' << force.vector.x <<
", " << force.vector.y <<
')' << endl;
322 cout <<
"--------------------------------------" << endl;
325 feedback_force_filtered_pub.publish(force);
327 force_stability_prev = force_stability;
328 force_instability_prev = force_instability;
333 int isLeft(geometry_msgs::Point32 p0, geometry_msgs::Point32 p1, geometry_msgs::Point p2)
335 return ((p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y));
340 int wn_PnPoly(geometry_msgs::Point p, geometry_msgs::Polygon poly)
342 int n = poly.points.size()-1;
347 for (
int i=0; i<n; i++)
349 if (poly.points[i].y <= p.y)
351 if (poly.points[i+1].y > p.y)
353 if (isLeft(poly.points[i], poly.points[i+1], p) > 0)
359 if (poly.points[i+1].y <= p.y)
361 if (isLeft(poly.points[i], poly.points[i+1], p) < 0)
371 double dot(geometry_msgs::Vector3 u, geometry_msgs::Vector3 v)
373 return (u.x*v.x + u.y*v.y + u.z*v.z);
377 double norm(geometry_msgs::Vector3 v)
379 return (sqrt(dot(v,v)));
383 double d(geometry_msgs::Point p0, geometry_msgs::Point p1)
385 return (norm(p0-p1));
392 geometry_msgs::Vector3 v = seg_point[1] - seg_point[0];
394 geometry_msgs::Vector3 w = p - seg_point[0];
396 double c1 = dot(w,v);
398 return d(p, seg_point[0]);
400 double c2 = dot(v,v);
402 return d(p, seg_point[1]);
405 geometry_msgs::Point pb = seg_point[0] + b*v;
412 int main(
int argc,
char **argv)
414 ros::init(argc, argv,
"haptic_feedback");
ros::Publisher feedback_force_filtered_pub
geometry_msgs::Vector3 FIR_force(const geometry_msgs::Vector3 force_prev, const geometry_msgs::Vector3 force_new)
ros::Publisher cop_global_filtered_pub
ros::Subscriber simulation_state_sub
geometry_msgs::Vector3 operator*(const double s, const geometry_msgs::Vector3 v)
geometry_msgs::Point operator+(const geometry_msgs::Point p, const geometry_msgs::Vector3 v)
geometry_msgs::PointStamped cop_global
geometry_msgs::Vector3Stamped force_stability_prev
geometry_msgs::Vector3 operator-(const geometry_msgs::Point p0, const geometry_msgs::Point p1)
geometry_msgs::PolygonStamped support_base
void phuaPosition(const geometry_msgs::PoseStamped &msg)
ros::Subscriber support_base_position_sub
Feedback(ros::NodeHandle nh)
geometry_msgs::PoseStamped phua_position
geometry_msgs::Point FIR_cop(const geometry_msgs::Point cop_prev, const geometry_msgs::Point cop_new)
ros::Subscriber simulation_state_sub
double dot(geometry_msgs::Vector3 u, geometry_msgs::Vector3 v)
ros::Publisher feedback_force_instability_pub
ros::Publisher feedback_force_stability_pub
geometry_msgs::Vector3Stamped force
ros::Subscriber phua_position_sub
int main(int argc, char **argv)
void copPosition(const geometry_msgs::PointStamped &msg)
void supportBaseDefinition(const geometry_msgs::PolygonStamped &msg)
ros::Publisher feedback_force_pub
int isLeft(geometry_msgs::Point32 p0, geometry_msgs::Point32 p1, geometry_msgs::Point p2)
void simulationState(const vrep_common::VrepInfo &msg)
ros::Subscriber cop_global_position_sub
geometry_msgs::PointStamped cop_filtered
void calculateFeedback(geometry_msgs::PointStamped cop, double distance)
int wn_PnPoly(geometry_msgs::Point p, geometry_msgs::Polygon poly)
double d(geometry_msgs::Point p0, geometry_msgs::Point p1)
double norm(geometry_msgs::Vector3 v)
double dist_PointSegment(geometry_msgs::Point p, vector< geometry_msgs::Point > seg_point)