How to publish pose in new frame?
Hi all,
Thanks a lot for reading my question. I am currently running a simulator in python where I have my robot move in a forward direction by 'x' and then back by the same amount. Due to several factors after this sequence, the robot doesn't return to the exact initial position (0,0) . What I want to do, is make it go back to its starting position after the sequence is ran. As of now I have written a code where I listen to the transform from the 'odom' frame to the 'baselink' frame, the latter being the frame I want to bring back to the origin. My approach was to publish a new frame called 'recentered' after the sequence is done and then calculate the pose of the 'baselink' frame in this new frame. Now I don't know how to publish this Pose (which is an identity 4x4 TF matrix) so that the robot starts at that position in the next run. I would be thankful for any inputs on how to do this. My code:
def __init__(self):
self.cmd_vel_pub = rospy.Publisher('cmd_vel',Twist,queue_size = 0.7)
self.tf_pub = rospy.Publisher('transform', TransformStamped, queue_size = 0.5)
self.tf2 = tf.TransformerROS(True, rospy.Duration(10.0))
self.X_sent = []
self.Y_sent = []
self.T_sent = []
self.Ang_sent = []
self.X_meas = []
self.Y_meas = []
self.T_meas = []
self.Ang_meas = []
self.X_trans = []
self.Y_trans = []
#self.rand = random.random()
def run_command(self):
sequence = [[1,0,0.05],[0,0,0],[0,0,0.1292],[1,0,0.1293],[0,0,0.1292],[1,0,0],[0,0,0],[-1,0,0],
[0,0,-0.1292],[-1,0,-0.1],[0,0,-0.1292],[-1,0,0],[0,0,0]]
for cmd in sequence:
#rospy.loginfo('Publishing sequence')
rospy.Rate(0.5).sleep()
msg = Twist()
msg.linear.x = cmd[0]
msg.linear.y = cmd[1]
msg.angular.z = cmd[2]
t = rospy.get_rostime()
self.X_sent.append(cmd[0])
self.Y_sent.append(cmd[1])
self.Ang_sent.append(cmd[2])
self.T_sent.append(t.secs + t.nsecs * 1e-9)
self.cmd_vel_pub.publish(msg)
self.tf_buffer = tf2_ros.Buffer()
self.tf2_listener = tf2_ros.TransformListener(self.tf_buffer)
self.transform_odom_rec = self.tf_buffer.lookup_transform('odom','recentered',rospy.Time(0),rospy.Duration(5)) #from rec. to odom
self.transform_bl_odom = self.tf_buffer.lookup_transform('base_link','odom',rospy.Time(0),rospy.Duration(5)) #from odom to base_link
self.tf2_listener.transformPose('recentered', self.msg)
##transform matrix from odometry to recentered frame.
trans_or_x = self.transform_odom_rec.transform.translation.x
trans_or_y = self.transform_odom_rec.transform.translation.y
trans_or_z = self.transform_odom_rec.transform.translation.z
trans_or = [trans_or_x,trans_or_y,trans_or_z]
#print(trans_or)
rot_or_x = self.transform_odom_rec.transform.rotation.x
rot_or_y = self.transform_odom_rec.transform.rotation.y
rot_or_z = self.transform_odom_rec.transform.rotation.z
rot_or_w = self.transform_odom_rec.transform.rotation.w
quat_or = [rot_or_x,rot_or_y,rot_or_z,rot_or_w]
q_or = tf.transformations.euler_from_quaternion(quat_or, axes='sxyz')
tf_or = tf.transformations.euler_matrix(q_or[0],q_or[1],q_or[2], axes='sxyz')
tf_or[:,3] = [trans_or_x,trans_or_y,trans_or_z, 1.0]
#print(tf_or)
##transform matrix from base_link to odom frame
trans_bo_x = self.transform_bl_odom.transform.translation.x
trans_bo_y = self.transform_bl_odom.transform.translation.y
trans_bo_z = self.transform_bl_odom.transform.translation.z
trans_bo = [trans_bo_x,trans_bo_y,trans_bo_z]
rot_bo_x = self.transform_bl_odom.transform.rotation.x
rot_bo_y = self.transform_bl_odom.transform.rotation.y
rot_bo_z = self.transform_bl_odom.transform.rotation.z
rot_bo_w = self.transform_bl_odom.transform.rotation.w
quat_bo = [rot_bo_x,rot_bo_y,rot_bo_z,rot_bo_w]
q_bo = tf.transformations.euler_from_quaternion(quat_bo, axes='rxyz')
tf_bo = tf.transformations.euler_matrix(q_bo[0],q_bo[1],q_bo[2], axes='rxyz')
tf_bo[:,3] = [trans_bo_x,trans_bo_y,trans_bo_z, 1.0]
#print(tf_bo)
##transform matrix from base_link to recentered frame
self.tf_br = np.matmul(tf_or, tf_bo)
#print(tf_br)
tp = self.tf_br[:,3]
q_br = tf.transformations.euler_from_matrix(self.tf_br,'rxyz')
quat_br = tf.transformations.quaternion_from_euler(q_br[0], q_br[1],q_br[2], 'ryxz')
#print(quat_br)
self.trans_br_x = tp[0]
self.trans_br_y = tp[1]
self.trans_br_z = tp[2]
trans_br = [self.trans_br_x,self.trans_br_y,self.trans_br_z]
#print(trans_br)
self.rot_br_x = quat_br[0]
self.rot_br_y = quat_br[1]
self.rot_br_z = quat_br[2]
self.rot_br_w = quat_br[3]
self.x_odom = self.trans_br_x
self.x_odom = self.trans_br_y
self.ang_odom = self.rot_br_z
#transform = self.tf_buffer.lookup_transform('recentered','odom',rospy.Time(0),rospy.Duration(1.0))
#pose_transformed = tf2_geometry_msgs.do_transform_pose(self.msg, transform)
#publish pose con el msg(TransformStamped)
rospy.signal_shutdown('Command finished')
def callback_odom(self,msg):
self.msg = msg
#splitting informations from received msgs
self.frame_id = msg.header.frame_id
self.x_odom = msg.pose.pose.position.x
self.y_odom = msg.pose.pose.position.y
self.ang_odom = msg.pose.pose.orientation.z
self.time = msg.header.stamp.secs + msg.header.stamp.nsecs * 1e-9
#appending odom msgs to the lists
self.X_meas.append(self.x_odom)
self.Y_meas.append(self.y_odom)
self.T_meas.append(self.time)
self.Ang_meas.append(self.ang_odom)
#print(self.x_odom)
def ros_init(self):
rospy.init_node('pepper_cmd_evaluator',anonymous = True)
rospy.Subscriber('pepper_robot/odom',Odometry,self.callback_odom)
Asked by chusikowski on 2019-07-10 11:02:19 UTC
Comments