lmc_filter_node.cpp
Go to the documentation of this file.
1 #include "ros/ros.h"
2 #include "leap_motion/Human.h"
3 #include "leap_motion/Hand.h"
4 #include "leap_motion/Finger.h"
5 #include "leap_motion/Bone.h"
6 
7 #include <iostream>
8 #include "Leap.h"
9 #include "../inc/lmc_filter_node.h"
10 
12 
13 std::vector< std::vector<lpf> > hands;
14 bool set_up_right = true;
15 bool set_up_left = true;
16 
24 {
25  c_ = 4.0;
26 }
27 
35 lpf::lpf(double cutoff)
36 {
37  c_ = cutoff;
38 }
39 
47 void lpf::setCutoff(double cutoff)
48 {
49  c_ = cutoff;
50 }
51 
59 void lpf::setInitialPos(double initial_msrmt, int b_idx, int dim)
60 {
61  prev_msrmts_[b_idx][dim][0] = initial_msrmt;
62  prev_msrmts_[b_idx][dim][1] = initial_msrmt;
63  prev_msrmts_[b_idx][dim][2] = initial_msrmt;
64 
65  prev_filtered_msrmts_[b_idx][dim][0] = initial_msrmt;
66  prev_filtered_msrmts_[b_idx][dim][1] = initial_msrmt;
67 }
68 
79 double lpf::filter(const double& new_msrmt, int b_idx, int dim)
80 {
81  // Push in the new measurement
82  prev_msrmts_[b_idx][dim][2] = prev_msrmts_[b_idx][dim][1];
83  prev_msrmts_[b_idx][dim][1] = prev_msrmts_[b_idx][dim][0];
84  prev_msrmts_[b_idx][dim][0] = new_msrmt;
85 
86  double new_filtered_msrmt = (1 / (1 + c_*c_ + 1.414*c_) ) * (prev_msrmts_[b_idx][dim][2] + 2*prev_msrmts_[b_idx][dim][1]
87  + prev_msrmts_[b_idx][dim][0] - (c_*c_ - 1.414*c_ + 1) * prev_filtered_msrmts_[b_idx][dim][1]
88  - (-2 * c_*c_ + 2) * prev_filtered_msrmts_[b_idx][dim][0]);
89 
90  // Store the new filtered measurement
91  prev_filtered_msrmts_[b_idx][dim][1] = prev_filtered_msrmts_[b_idx][dim][0];
92  prev_filtered_msrmts_[b_idx][dim][0] = new_filtered_msrmt;
93 
94  return new_filtered_msrmt;
95 }
96 
103 double lpf::getFilteredMsrmt(int b_idx, int dim){
104  return prev_filtered_msrmts_[b_idx][dim][0];
105 }
106 
116 void filterMessage(leap_motion::Hand hand, uint8_t hand_idx){
117  if(set_up_right || set_up_left ){
118  hands[hand_idx][5].setInitialPos( hand.palm_center.x, 0 , 0);
119  hands[hand_idx][5].setInitialPos( hand.palm_center.y, 0 , 1);
120  hands[hand_idx][5].setInitialPos( hand.palm_center.z, 0 , 2);
121  }
122 
123  hand.palm_center.x = hands[hand_idx][5].filter( hand.palm_center.x, 0 , 0);
124  hand.palm_center.y = hands[hand_idx][5].filter( hand.palm_center.y, 0 , 1);
125  hand.palm_center.z = hands[hand_idx][5].filter( hand.palm_center.z, 0 , 2);
126 
127  leap_motion::Finger finger;
128  for(unsigned int j = 0; j < hand.finger_list.size(); j++)
129  {
130  finger = hand.finger_list[j];
131  leap_motion::Bone bone;
132  for(unsigned int k = 0; k < finger.bone_list.size(); k++)
133  {
134  bone = finger.bone_list[k];
136  {
137  hands[hand_idx][finger.type].setInitialPos(bone.bone_end.position.x, bone.type, 0);
138  hands[hand_idx][finger.type].setInitialPos(bone.bone_end.position.y, bone.type, 1);
139  hands[hand_idx][finger.type].setInitialPos(bone.bone_end.position.z, bone.type, 2);
140  }
141 
142  bone.bone_end.position.x = hands[hand_idx][finger.type].filter(bone.bone_end.position.x, bone.type, 0);
143  bone.bone_end.position.y = hands[hand_idx][finger.type].filter(bone.bone_end.position.y, bone.type, 1);
144  bone.bone_end.position.z = hands[hand_idx][finger.type].filter(bone.bone_end.position.z, bone.type, 2);
145 
146  if(bone.type != 0)
147  {
148  bone.bone_start.position.x = hands[hand_idx][finger.type].getFilteredMsrmt( bone.type - 1, 0);
149  bone.bone_start.position.y = hands[hand_idx][finger.type].getFilteredMsrmt( bone.type - 1, 1);
150  bone.bone_start.position.z = hands[hand_idx][finger.type].getFilteredMsrmt( bone.type - 1, 2);
151  }
152  else
153  {
154  if( set_up_right || set_up_left )
155  {
156  hands[hand_idx][finger.type].setInitialPos(bone.bone_start.position.x, 5, 0);
157  hands[hand_idx][finger.type].setInitialPos(bone.bone_start.position.y, 5, 1);
158  hands[hand_idx][finger.type].setInitialPos(bone.bone_start.position.z, 5, 2);
159  }
160  bone.bone_start.position.x = hands[hand_idx][finger.type].filter(bone.bone_start.position.x, 5, 0);
161  bone.bone_start.position.y = hands[hand_idx][finger.type].filter(bone.bone_start.position.y, 5, 1);
162  bone.bone_start.position.z = hands[hand_idx][finger.type].filter(bone.bone_start.position.z, 5, 2);
163  }
164  }
165  }
166  if(set_up_right)
167  {
168  set_up_right = false;
169  }
170  if(set_up_left)
171  {
172  set_up_left = false;
173  }
174 }
175 
185 void messageCallback(const leap_motion::Human::ConstPtr& human){
186  leap_motion::Hand hand;
187 
188  if( human -> right_hand.is_present )
189  {
190  hand = human -> right_hand;
191  filterMessage(hand, 0);
192  }
193 
194  if( human -> left_hand.is_present )
195  {
196  hand = human -> left_hand;
197  filterMessage(hand, 1);
198  }
199 
200  // Forward the now filtered human message
201  filt_pub->publish(human);
202 }
203 
204 int main(int argc, char** argv) {
205  ros::init(argc, argv, "leap_motion");
206  ros::NodeHandle nh("leap_motion");
207 
208  double cutoff;
209  bool is_enabled;
210  nh.getParam("/filter_cutoff", cutoff);
211  nh.getParam("/enable_filter", is_enabled);
212 
213  if(is_enabled)
214  {
215  // Left and right hand setup
216  hands.push_back( std::vector<lpf> ( 6, lpf( cutoff ) ) );
217  hands.push_back( std::vector<lpf> ( 6, lpf( cutoff ) ) );
218 
219  ros::Subscriber human_sub = nh.subscribe<leap_motion::Human>("leap_device", 1, messageCallback);
220  ros::Publisher f_pub = nh.advertise<leap_motion::Human>("leap_filtered", 1);
221  filt_pub = &f_pub;
222 
223  ros::spin();
224  }
225 
226  return 0;
227 }
void setInitialPos(double initial_msrmt, int b_idx, int dim)
This is used to set the inital position values of a filter.
void publish(const boost::shared_ptr< M > &message) const
static ros::Publisher * filt_pub
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
ROSCPP_DECL void spin(Spinner &spinner)
void messageCallback(const leap_motion::Human::ConstPtr &human)
A callback function that is run everytime a new Human.msg is received.
int main(int argc, char **argv)
std::vector< std::vector< lpf > > hands
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
lpf()
Uses default values for initial setup.
double getFilteredMsrmt(int f_idx, int dim)
This is used to get a filtered value of a bone.
void setCutoff(double)
Use this to change the cutoff of a lpf object.
bool set_up_right
double c_
bool getParam(const std::string &key, std::string &s) const
double prev_msrmts_[6][3][3]
double filter(const double &new_msrmt, int f_idx, int dim)
This is used to filter the position values of a bone.
void filterMessage(leap_motion::Hand hand, uint8_t hand_idx)
This is used to filter the unfiltered human.msg.
bool set_up_left
double prev_filtered_msrmts_[6][3][2]


leap_motion
Author(s): Florian Lier , Mirza Shah , Isaac IY Saito
autogenerated on Tue Jun 2 2020 03:58:01