OdometryIIRFilter.py
Go to the documentation of this file.
00001 #! /usr/bin/env python
00002 
00003 import rospy
00004 import numpy
00005 from nav_msgs.msg import Odometry
00006 from geometry_msgs.msg import Quaternion, Point, TransformStamped
00007 import tf
00008 import copy
00009 import threading
00010 from jsk_robot_startup.IIRFilter import IIRFilter
00011 from jsk_robot_startup.odometry_utils import transform_quaternion_to_euler
00012 
00013 class OdometryIIRFilter(object):
00014     def __init__(self):
00015         rospy.init_node("OdometryIIRFilter", anonymous=True)
00016         # parameters
00017         self.rate = float(rospy.get_param("~rate", 100))
00018         self.odom_frame = rospy.get_param("~odom_frame", "filtered_odom")
00019         self.filter_dim = rospy.get_param("~filter_dimension", 2)
00020         self.cutoff = min(float(rospy.get_param("~cutoff", 10)), self.rate / 2.0) # must be larger than nyquist frequency
00021         self.odom = None
00022         self.filtered_odom = None
00023         self.prev_rpy = None
00024         self.dt = 0.0
00025         self.r = rospy.Rate(self.rate)
00026         self.lock = threading.Lock()
00027         self.filters = []
00028         for i in range(6):
00029             self.filters.append(IIRFilter(self.filter_dim, self.cutoff / self.rate))
00030         # tf
00031         self.publish_tf = rospy.get_param("~publish_tf", True)
00032         if self.publish_tf:
00033             self.invert_tf = rospy.get_param("~invert_tf", True)
00034             self.broadcast = tf.TransformBroadcaster()
00035             self.listener = tf.TransformListener()
00036         # pub/sub
00037         self.pub = rospy.Publisher("~output", Odometry, queue_size=10)
00038         self.odom_sub = rospy.Subscriber("~source_odom", Odometry, self.source_odom_callback)
00039         self.init_transform_sub = rospy.Subscriber("~initial_base_link_transform", TransformStamped, self.init_transform_callback)
00040 
00041     def initialize_filter(self):
00042         with self.lock:
00043             self.odom = None
00044             self.filtered_odom = None
00045             self.prev_rpy = None
00046             self.filters = []
00047             for i in range(6):
00048                 self.filters.append(IIRFilter(self.filter_dim, self.cutoff / self.rate))
00049 
00050     def execute(self):
00051         while not rospy.is_shutdown():
00052             self.update()
00053             self.r.sleep()
00054             
00055     def init_transform_callback(self, msg):
00056         self.initialize_filter()
00057             
00058     def source_odom_callback(self, msg):
00059         with self.lock:
00060             self.odom = msg
00061 
00062     def update(self):
00063         with self.lock:
00064             if self.odom == None:
00065                 return
00066             current_euler = transform_quaternion_to_euler([self.odom.pose.pose.orientation.x, self.odom.pose.pose.orientation.y, self.odom.pose.pose.orientation.z, self.odom.pose.pose.orientation.w], self.prev_rpy)
00067             current_6d_pose = [self.odom.pose.pose.position.x, self.odom.pose.pose.position.y, self.odom.pose.pose.position.z] + current_euler
00068             for i in range(6):
00069                 current_6d_pose[i] = self.filters[i].execute(current_6d_pose[i])
00070             self.filtered_odom = copy.deepcopy(self.odom)
00071             self.filtered_odom.header.frame_id = self.odom_frame
00072             self.filtered_odom.pose.pose.position = Point(*current_6d_pose[:3])
00073             self.filtered_odom.pose.pose.orientation = Quaternion(*tf.transformations.quaternion_from_euler(*current_6d_pose[3:6]))
00074             self.prev_rpy = current_6d_pose[3:6]
00075             self.pub.publish(self.filtered_odom)
00076             if self.publish_tf:
00077                 broadcast_transform(self.broadcast, self.filtered_odom, self.invert_tf)


jsk_robot_startup
Author(s):
autogenerated on Sat Jul 1 2017 02:42:18