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)