2

I have poses of two objects. They are in terms of x,y,z and roll, pitch and yaw (I get them in quaternion and then convert them to roll,pitch,yaw). What I need to do is I will record the relative pose between two objects, record them, so, when one of the object rotates, the other is translated and rotated exactly the same way. I am getting the pose from the centroid of the objects.

This video will illustrate what I intend to do.

https://drive.google.com/file/d/1NKtS9fv-FasloVwCKqYIAV1Uc2i9_PN0/view

I have visited the following site for help:

http://planning.cs.uiuc.edu/node102.html

Please help me, I am stuck for a long time, I need a direction, I am new in robotics and I do not have any background in computer vision.

@Vik, so I have implemented as the way you wanted but it is not working properly. I am working in ROS environment in python but I have given the logic part of the code. If you could take a look, then it would be very helpful. I got my matrices from here: http://planning.cs.uiuc.edu/node104.html

#This is object2
p = PoseStamped()
p.header.frame_id = robot.get_planning_frame()
p.pose.position.x = 0.90
p.pose.position.y = 0.30
p.pose.position.z = 1.2
p.pose.orientation.x=0.0
p.pose.orientation.y=0.0
p.pose.orientation.z=0.0
p.pose.orientation.w=1.0
scene.add_box("object2", p, (0.1, 0.1, 0.2))

rospy.sleep(2)

quaternion1 =   (p.pose.orientation.x,p.pose.orientation.y,p.pose.orientation.z,p.pose.orientation.w)
euler = tf.transformations.euler_from_quaternion(quaternion1, axes='sxyz') # will provide result in x, y,z sequence
roll=euler[0]
pitch=euler[1]
yaw=euler[2]

C00=math.cos(yaw)*math.cos(pitch)
C01=math.cos(yaw)*math.sin(pitch)*math.sin(roll) - math.sin(yaw)*math.sin(roll)
C02=math.cos(yaw)*math.sin(pitch)*math.cos(roll) + math.sin(yaw)*math.sin(roll)
C03=p.pose.position.x
C10=math.sin(yaw)*math.cos(pitch)
C11=math.sin(yaw)*math.sin(pitch)*math.sin(roll) + math.cos(yaw)*math.cos(roll)
C12=math.sin(yaw)*math.sin(pitch)*math.cos(roll) -math.cos(yaw)*math.sin(roll)
C13=p.pose.position.y
C20= -math.sin(pitch)
C21=math.cos(pitch)*math.sin(roll)
C22=math.cos(pitch)*math.cos(roll)
C23=p.pose.position.z
C30=0
C31=0
C32=0
C33=1

obj2_mat=np.array([[C00, C01, C02, C03],[C10, C11, C12, C13],[C20, C21, C22, C23],[C30, C31, C32, C33]])

#This is object1
p1 = PoseStamped()
p1.header.frame_id = robot.get_planning_frame()
p1.pose.position.x = 0.9
p1.pose.position.y = 0.30
p1.pose.position.z = 0.7
p1.pose.orientation.x=0.0
p1.pose.orientation.y=0.0
p1.pose.orientation.z=0.0
p1.pose.orientation.w=1.0


scene.add_box("object1", p1, (0.1, 0.1, 0.5))


rospy.sleep(2)

quaternion2 = (p1.pose.orientation.x,p1.pose.orientation.y,p1.pose.orientation.z,p1.pose.orientation.w)
euler = tf.transformations.euler_from_quaternion(quaternion2, axes='sxyz')
roll=euler[0]
pitch=euler[1]
yaw=euler[2]

C00=math.cos(yaw)*math.cos(pitch)
C01=math.cos(yaw)*math.sin(pitch)*math.sin(roll) - math.sin(yaw)*math.sin(roll)
C02=math.cos(yaw)*math.sin(pitch)*math.cos(roll) + math.sin(yaw)*math.sin(roll)
C03=p1.pose.position.x
C10=math.sin(yaw)*math.cos(pitch)
C11=math.sin(yaw)*math.sin(pitch)*math.sin(roll) + math.cos(yaw)*math.cos(roll)
C12=math.sin(yaw)*math.sin(pitch)*math.cos(roll) -math.cos(yaw)*math.sin(roll)
C13=p1.pose.position.y
C20= -math.sin(pitch)
C21=math.cos(pitch)*math.sin(roll)
C22=math.cos(pitch)*math.cos(roll)
C23=p1.pose.position.z
C30=0
C31=0
C32=0
C33=1

obj1_mat=np.array([[C00, C01, C02, C03],[C10, C11, C12, C13],[C20, C21, C22, C23],[C30, C31, C32, C33]])

transformation_mat=np.dot(inv(obj2_mat), obj1_mat) #generating the transformation

rospy.sleep(10)

#This is object1 in second pose
p2 = PoseStamped()
p2.header.frame_id = robot.get_planning_frame()
p2.pose.position.x = 0.70
p2.pose.position.y = -0.9
p2.pose.position.z = 0.7
p2.pose.orientation.x=0.3826834
p2.pose.orientation.y=0.0
p2.pose.orientation.z=0.0
p2.pose.orientation.w=-0.9238795
scene.add_box("object1", p2, (0.1, 0.1, 0.5))

object_position_mat=np.array([[p2.pose.position.x],[p2.pose.position.y],[p2.pose.position.z],[1]]) # (x,y,z,1) position matrix for object1 in its second position

rospy.sleep(2)

Final_position=np.dot(transformation_mat, object_position_mat) #Getting the new position of object2 by multiplying transformation matrix with position of object1


print "============ Generating plan 2"


#This is object2 in second pose
p = PoseStamped()
p.header.frame_id = robot.get_planning_frame()
p.pose.position.x = Final_position[0]
p.pose.position.y = Final_position[1]
p.pose.position.z = Final_position[2]
p.pose.orientation.x=p2.pose.orientation.x #Kept the same orientation values of object1 in second pose, did not do any calculation as it is logical
p.pose.orientation.y=p2.pose.orientation.y
p.pose.orientation.z=p2.pose.orientation.z
p.pose.orientation.w=p2.pose.orientation.w

scene.add_box("object2", p, (0.1, 0.1, 0.2)) 
  • Hi, welcome to stack overflow. Might be worth describing more what you're attempting to do rather than including a external website. They have a habit of disappearing. – Glenn Watson Mar 13 '19 at 20:07
  • Hi, thank you for your comment, it is in my google drive so it is safe, it is pretty difficult to explain what I exactly want so I added the video for clear understanding. – Tawfiq Chowdhury Mar 13 '19 at 21:59

1 Answers1

4

Using the notation in http://www.ccs.neu.edu/home/rplatt/cs5335_fall2017/slides/homogeneous_transforms.pdf, let's say you have 2 Homogeneous Transformation matrices of the objects in the world frame and .
You can compose the 4x4 transformation matrices using where R is the 3x3 rotation matrix and X is a 3x1 the translation vector.

What you are looking for is which is simply where

Once you transform object one in your desired way, you should be able to just apply and get the desired results.

Update:
If refers to the coordinates of points (for examples object points like its corners) in object 2's local co-orindate system as . Then these points are given in the any arbitrary frame f as

Here is some code based on your code, hope I understand what you are trying to do:

from tf.transformations import euler_from_quaternion, quaternion_from_euler, \
                               quaternion_matrix, quaternion_from_matrix
from geometry_msgs.msg import PoseStamped, Pose, Point, Quaternion
from std_msgs.msg import Header
import numpy as np

def PoseStamped_2_mat(p):
    q = p.pose.orientation
    pos = p.pose.position
    T = quaternion_matrix([q.x,q.y,q.z,q.w])
    T[:3,3] = np.array([pos.x,pos.y,pos.z])
    return T

def Mat_2_posestamped(m,f_id="test"):
    q = quaternion_from_matrix(m)
    p = PoseStamped(header = Header(frame_id=f_id), #robot.get_planning_frame()
                    pose=Pose(position=Point(*m[:3,3]), 
                    orientation=Quaternion(*q)))
    return p

def T_inv(T_in):
    R_in = T_in[:3,:3]
    t_in = T_in[:3,[-1]]
    R_out = R_in.T
    t_out = -np.matmul(R_out,t_in)
    return np.vstack((np.hstack((R_out,t_out)),np.array([0, 0, 0, 1])))

#This is object2
p_o2 = PoseStamped(header = Header(frame_id="test"), #robot.get_planning_frame()
                   pose=Pose(position=Point(0.9,0.3,1.2), 
                   orientation=Quaternion(0,0,0,1)))

#scene.add_box("object2", p_o2, (0.1, 0.1, 0.2))
#rospy.sleep(2)
Tw2 = PoseStamped_2_mat(p_o2)

#This is object1
p_o1 = PoseStamped(header = Header(frame_id="test"), #robot.get_planning_frame()
                   pose=Pose(position=Point(0.9,0.3,0.7), 
                   orientation=Quaternion(0,0,0,1)))
#scene.add_box("object1", p_o1, (0.1, 0.1, 0.5))
#rospy.sleep(2)
Tw1 = PoseStamped_2_mat(p_o1)

T2w = T_inv(Tw2)
T21 = np.matmul(T2w, Tw1) 

#rospy.sleep(10)
#This is object1 in second pose
p_o2_prime = PoseStamped(header = Header(frame_id="test"), #robot.get_planning_frame()
                         pose=Pose(position=Point(0.7,-0.9,0.7), 
                         orientation=Quaternion(0.3826834,0,0,-0.9238795)))
#scene.add_box("object1", p_o2_prime, (0.1, 0.1, 0.5))
Tw2_prime = PoseStamped_2_mat(p_o2_prime)


Tw1_prime = np.matmul(Tw2_prime, T21)

#rospy.sleep(2)

print "============ Generating plan 2"

#This is object2 in second pose
p_o1_prime = Mat_2_posestamped(Tw1_prime, f_id="test") #  robot.get_planning_frame()
#scene.add_box("object2", p_o1_prime, (0.1, 0.1, 0.2))
Vik
  • 690
  • 7
  • 22
  • Thanks a lot for the ideas, to be clear from programming perspective, I would like to ask few things: 1. I have 3 position values (x,y,z) and 3 orientation values (roll, pitch, yaw), so by applying transformation, do you mean after multiplying the matrices, I should multiply the result with x,y,z and roll, pitch, yaw (I will put them in a 1x3 matrix?). 2. I have seen in web but I would still like to know what exactly would be my homogeneous transformation matrix where I will put x,y,z and roll,pitch and yaw values. – Tawfiq Chowdhury Mar 15 '19 at 02:57
  • Is it the matrix? http://planning.cs.uiuc.edu/node104.html If it is the matrix, then do you mean, I will put the x,y,z and roll, pitch, yaw values in two different matrices, perform the operations you said, final answer will be a 4x4 matrix and then I need to multiply that 4x4 matrix with the first object's new position and orientation in world coordinates? If yes, then I need to put the 3 position and orientation values in a 1x4 matrices for the matrix multiplication to work, will be it like [x, y, z, 1] ? – Tawfiq Chowdhury Mar 15 '19 at 03:04
  • See updated answer. No you don't have 2 separate matrices. A 4x4 homogenous transformation encodes both the Rotation and translation. – Vik Mar 15 '19 at 13:44
  • Thank you for the reply. I think you are referring to this (http://planning.cs.uiuc.edu/node104.html) 4x4 transformation matrix. So, I will get one such matrix for Object1 in world coordinate and another for object 2 in world coordinate and then I will multiply the inverse of one with the other to get the transformation. How do we apply the transformation? Do we multiply the transformation (new 4x4 matrix) with the new position (x,y,z,1) and orientation (roll,pitch,yaw,1) of one object to get the new position and orientation of the other? If yes, then what is the order of multiplication? – Tawfiq Chowdhury Mar 20 '19 at 21:36
  • Could you please take a look at my original post where I have given my code? – Tawfiq Chowdhury Mar 22 '19 at 20:17
  • Tawfiq, I have added a code to reflect what I believe you are trying to do. I think you might have been inverting the wrong matrix. Hope fully my notation will help you understand better. – Vik Mar 25 '19 at 00:06
  • Tawfiq, did the code help solve what you were trying to do? If yes, please 'accept' the answer. Cheers... – Vik Mar 27 '19 at 02:02
  • Hi, I tried the inverse matrix in the other combination before posting my last query, I believe the transformation is working but the object alignment is not shown as the way I showed in the video, it is putting one object on top of the other, I believe the reason behind that is in moveit ros, I get or set the pose from centroid of the object but I need it from the tip to visually display it as the way I showed in the video, thanks a lot for your explanations and help. – Tawfiq Chowdhury Mar 28 '19 at 04:50