-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Publish camera pose as tf ros message #102
base: master
Are you sure you want to change the base?
Conversation
Quick question if you could help. How to get the world position from this transform? The translation is not following the view-direction of the camera, and I couldn't find any sensible multiplication to make it right. |
Haven't used it for quite a while, but the node should be: It is the pose of the camera in world frame, start position is 0,0,0. It worked for me but when you find any errors let me know. |
Hi. I'm newbie in ROS, and i have some questions. I was trying to display in rviz (camera display) the current camera image in overlay to the point cloud map. Everything is somehow working, however there seems to be a mismatch between the map points pose and published /tf (which imposes the displayed image pose). As a result, the map overlay is basically wrong. thank you |
Hi, I just checked again and found out that what I did is wrong. Currently I am correcting the code. I will update the pull request in the upcoming days. |
Updated. /tf/camera_pose returns distance from origin. |
Does /tf/camera_pose also apply to the stereo cameras instead of rgbd? Thanks! |
I have never tried Orb Slam 2 with a stereo camera, so I do not know. I can imagine that you can apply the same transformation to each of the camera. |
At the 146th line, are you sure that the transformation is correct? I don't think you should apply the rotation to the translation part, as [R, t;0 0 0 1]_[R0, 0;0 0 0 1] = [R_R0, t;0 0 0 1]. Please correct me if I am wrong. Even then, the translation part doesn't seem to work with my RGBD camera. All X,Y,Z components have the value below 10^{-4}. Could you give me any guide to solve this issue? Thanks, |
For me it worked ok. I have a camera mounted on a quadcopter and it gives me the translation in x,y,z direction. The origin(0,0,0) is where the algorithm was started. I also tried turning the camera and then translating it and the output was what I had expected. So the output was definitely not 10^4 or similar, but a translation from the origin in x,y,z direction, in cm. What the line does is changing the sequence of coordinates in the vector, xyz becomes zxy. So I guess the multiplication is necessary. But I struggled quite a bit to get the rotations right, so I would not be surprised if there is still a bug somewhere. Is Orb Slam running correctly? Do you see that the pointcloud is created? |
EDITED#2: Pointcloud is created. (my bad) The pointcloud is created but the frame in the visualisation is rotated when I try turning the camera, it doesn't translate to any position when I move the camera. I am not sure if I use the correct setting for my Asus Xtion Pro and it affects the result though, I have set |
Sorry for the late reply. I cannot help with your camera settings but what I figured out is that you should disable everything which says "Auto", like Auto White Balance, Auto Exposure, etc. |
Hi @Thomas00010111 , first of all, thanks your code to publish the camera pose, and then, what is the direction of your camera, forward(x) or down(z)? |
Hi @Thomas00010111, Did you manage to have both the pose and the map published on the same reference frame? I tried your code (as well as mine) but I had no success in having a coherent pose w.r.t. the map (pointcloud generated through I experience both a mismatch in the axes rotations (e.g. yaw rotation leads to upward/downward rotation) and an offset from the real pose (about 135° roll error in the starting position) which make me think there is a more generic conversion error between the RF used by ROS/Rviz and the one used in ORB SLAM2. |
Thanks for your code @Thomas00010111. I put your code in ros_stereo.cc and it works! I have the global position of the camera pose using a stereo camera. |
Hi all! @Thomas00010111, thank you for your work!! I used it in the ros_mono and it works! I have the pose and quaternion published in ROS. However, when I try to visualize it in RVIZ I keep getting the error that the quaternion isn't valid. I grabbed the values of the published quaternion, did the norm by hand and got values around 0,97; maybe that is what generates the error since it should be 1 (I think). I assume that's because you use a matrix for the globalRotation_rh instead of a quaternion and, as such, it isn't normalized. I tried to convert it to a quaternion and publish the transform normalized but I got a quaternion with even lower norm :(. Here's what I did:
By doing this I get the tf in RVIZ without errors which is odd since the quaternion is even "more invalid" (norm around 0,61). The pose works great but the orientation is really strange when I move the camera. If anyone could help me that would be great :) |
Hi @grifo,
Unfortunately, I do not have the time to work on this project. When I wrote
this code I was quite unexperienced in the field of slam, vision, etc. The
matrix which you get from the orb slam main module needs to be inverted, I
think I used minus signs to achieve this and I am not sure if this correct.
If Then try to apply the rotations.
Cheers,
Thomas
2017-04-13 10:33 GMT-07:00 Grifo <[email protected]>:
… Hi all!
@Thomas00010111 <https://github.com/Thomas00010111>, thank you for your
work!! I used it in the ros_mono and it works! I have the pose and
quaternion published in ROS.
However, when I try to visualize it in RVIZ I keep getting the error that
the quaternion isn't valid. I grabbed the values of the published
quaternion, did the norm by hand and got values around 0,97; maybe that is
what generates the error since it should be 1 (I think). I assume that's
because you use a matrix for the globalRotation_rh instead of a quaternion
and, as such, it isn't normalized.
I tried to convert it to a quaternion and publish the transform normalized
but I got a quaternion with even lower norm :(. Here's what I did:
`static tf::TransformBroadcaster br;
tf::Quaternion q;
tf::Matrix3x3 globalRotation_rh = cameraRotation_rh * rotation270degXZ;
tf::Vector3 globalTranslation_rh = cameraTranslation_rh * rotation270degXZ;
globalRotation_rh.getRotation(q);
tf::Transform transform = tf::Transform(q.normalize(), globalTranslation_rh);`
By doing this I get the tf in RVIZ without errors which is odd since the
quaternion is even "more invalid" (norm around 0,61). The pose works great
but the orientation is really strange when I move the camera.
If anyone could help me that would be great :)
Thank you in advance!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#102 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/APJF4tBhIpovycGpvD7ofRRejMqCzuzYks5rvlxSgaJpZM4Io9z0>
.
|
Hello @Thomas00010111 , Thank you for your reply! After thinking a bit I then realized the getRotation(Quaternion q) method should already give me a normalized quaternion. I didn't need to normalize it again, so I change the last code line to:
And it worked, I now get the transforms in RVIZ. I'm now having another problem, the transform seems to be initializing around this values: It should be initializing around: I get the translation being a bit odd due to the ORB-SLAM algorithm initialization but not the rotation part (quaternion). I'll try to better analyze your code to see how to get it initializing in the origin (0,0,0)(0,0,0,1) and I'll get back here if I'm able to do so. If anyone have any suggestions I would appreciate it since I'm no algebra expert. Thank you in advance, |
I got the quaternion to initialize correctly I think :) Here's what I did, it's a combination of your code with "TFinleyosu" 's answer here
I'm no expert, so it may all be wrong but it works for me ;) |
Could you address how to use this? @Grifo07 |
Hi @DalderupMaurice, If you post your code I can help you better maybe. Since yours is RGBD, I can't help you with just a copy paste code. |
Hi @Grifo07 What I basically did was open the edited files from this pull request which you can find here: Replace my original file with the changed file, rebuild the code and that is it. Im doing this for my thesis, my goal is to create an autonomous flying quadcopter, but unlike many I did not learn c++ or such complex algorithms/math in my education. |
Hi @Grifo07 The next step for me is having the same result while using Monoculaire. |
Hey @DalderupMaurice ! Sorry for the late reply! To use the monocular you can just copy paste the code I put in a previous answer. It publishes in the /tf topic the position and quaternion. I'm able to use it to navigate a quadcopter. You just have to modify it a bit to incorporate scale in the monocular case. I'm still trying to do this. However these guys: https://github.com/idsc-frazzoli/ardrone_testbed and https://www.youtube.com/watch?v=Bz3eOuCs-pI did a great job and released their code. If I had seen this at first I would try to branch my code from there. Maybe you have better luck ;) |
Grifo07, your reply in the comment works perfectly, spent hours to get the original code to work. Thank you soo much, please make a pull request to Thomas00010111 |
Hello there, Thanks @Hartvik90, however, ignore that code I wrote :P The reason is because I still didn't know much about quaternions at that time. And basically what mine does is using the same technique as Thomas00010111's but initialized in the origin. We still have a bit of drift error, which means that after a while the position in ROS will be completely different from the one ORB-SLAM2 returns. So I did something different now:
Explanation: https://en.wikipedia.org/wiki/Quaternion#Hamilton_product In short: Basically I use the hamilton product to orient the translation vector, meaning I go from local coordinates to world coordinates. What Thomas00010111 did and I copied, was to try to see what was the travel distance and orientation from the last position and add it to an accumulator (the pose). As you can guess, each calculation has an error which will increase with each cycle. This way we eliminate this :) Oh and ignore the Scalling if you don't use it. I use it to change the coordinates to actual metres. Sorry for the long post, |
Hi @Grifo07, thank you very much for sharing. I am still trying to use your code. |
HI @Grifo07,
|
Publish camera pose as tf ros message raulmur#102. Added publishing of pointcloud and position to ros rgbd example raulmur#443.
…inate Described in "Publish camera pose as tf ros message raulmur#102" by Grifo07
Dear @Grifo07, Can you share your ros_mono.cc? I need to publish the pose so I should add a topic to do that. |
@Grifo07 , @Thomas00010111 @hmchung . |
Hi there! @hmchung and @LiangLiang128 , you are right, I accidentally double-pasted my code. I edited my comment to reflect my actual code now. However, the correct part was the top part :/ @hesamira, this comment reflects my ros_mono.cc. The part you should look better for is the tf::TransformBroadcaster structure. @dishank-b, ORB-SLAM gets its position by comparing its current features with the features got in the last frame of the video stream. So, it's basically just a relative position, relative to the first position it ever tracked. So the scale is defined by the speed you move the camera when you initialize the algorithm. I assume it assumes the scale as one. So, if you move the camera lets say 2 meters before it gets the first relation between the first frames, it will assume you moved 1 unit and your scale will be 2. But I guess there is no way of knowing your scale without actually measuring it. In my application my drone has a IR sensor to measure distance, and by moving it up and down, I can measure the actual distance it traveled vs the ORB-SLAM distance and get a scale. Hope I helped, |
Thanks for the reply. It is a real help.
…On Mon, Aug 27, 2018 at 8:02 PM Grifo ***@***.***> wrote:
Hi there!
@hmchung <https://github.com/hmchung> and @LiangLiang128
<https://github.com/LiangLiang128> , you are right, I accidentally
double-pasted my code. I edited my comment to reflect my actual code now.
However, the correct part was the top part :/
The scaling part is used to "scale the world". So imagine the ORB-SLAM
gives me 1 unit to the right when I actually moved 3 meters. Basically my
scale is 3. So, during my application, I come up with the scale and
multiply it by the output of the ORB-SLAM getting my position in meters.
@hesamira <https://github.com/hesamira>, this comment
<#102 (comment)>
reflects my ros_mono.cc. The part you should look better for is the
tf::TransformBroadcaster
<http://docs.ros.org/melodic/api/tf/html/c++/classtf_1_1TransformBroadcaster.html>
structure.
@dishank-b <https://github.com/dishank-b>, ORB-SLAM gets its position by
comparing its current features with the features got in the last frame of
the video stream. So, it's basically just a relative position, relative to
the first position it ever tracked. So the scale is defined by the speed
you move the camera when you initialize the algorithm. I assume it assumes
the scale as one. So, if you move the camera lets say 2 meters before it
gets the first relation between the first frames, it will assume you moved
1 unit and your scale will be 2. But I guess there is no way of knowing
your scale without actually measuring it. In my application my drone has a
IR sensor to measure distance, and by moving it up and down, I can measure
the actual distance it traveled vs the ORB-SLAM distance and get a scale.
Hope I helped,
Sorry for the late response,
Cheers,
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#102 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AQ6RJdBw53G9cR6vDBTZn9lUalvEQo8Vks5uVALhgaJpZM4Io9z0>
.
--
Regards,
*Dishank Bansal*
Junior Year Undergraduate Student
IIT Kharagpur
Ph: +91 9800394333
Website <https://dishank-b.github.io/> | Git Hub
<https://github.com/dishank-b>
Computer Vision Team Member
Autonomous Ground Vehicle(AGV) Research Group <http://agv-iit-kgp.github.io>
IIT Kharagpur
|
Hi @Grifo07 and @Thomas00010111. Second question: I read about the drift the program might have, but if I move to one point to another 1 meter far away it tells me only 0,9, which I guess are centimeters and not meters. Third question: To know the camera position, I have to "rostopic echo" the topic /tf, right? Thank you for your help!! |
Hi @DodsGTH94, Answering you questions: Second question: Third question: I answered your questions only with what I know. I'm not saying everything I said is true, but it's what I believe to be true, from my experience with this algorithm. I advice you to do your own research and experiences also. Best of lucks, |
Thank you @Grifo07 . Thank you all!! |
Hi @DodsGTH94, Cheers! |
@Grifo07 thanks alot! got it to work for monocular, and published the transform. However i did it without the scale and world, (commented out, same as what @hmchung and @LiangLiang128 are asking) .im wondering how do u set the m_worldQ and m_worldT and what are these variables? In what situation does m_numScales fall below 1? |
So, I'll try to explain the scale part (ONLY FOR MONOCULAR): Basically I initialize my flight (I'm using a quadcopter), it initializes the ORB_SLAM2 and I start to get a pose. However I get it in unscaled units, meaning I know the drone is let's say 2 units in the air but I have no idea how does that translate to meters. Now imagine we move the drone again and get another value for the scale, let's say 3.2. I then do Hope it helps, |
@Grifo07 thanks for explaining the scale for tuning purposes. What about the m_worldT and m_worldQ? were u trying to assume a different world frame instead of (0,0,0) and mathematically why is an inverse applied? Anyway, am really grateful for the quaternion transformation! Maybe it would be good if you could show what is the inital frame of global and camera positions |
I can't really recall that part since it was a while ago, but it served the purpose of setting the current position of the drone as the world reference. Basically I had a service that I called whenever I wanted and that service would just do:
I don't remember much about the math behind it and I really don't have much time to dig into it.
Can't really understand this question. They both start at (0,0,0). |
Hi @DalderupMaurice , |
can u tell me what changes u had to make to apply this to stereo cameras? |
To anyone who needs it: this is the working code for Mono https://pastebin.com/tiPpsGLW @Grifo07 , does it mean that the camera_pose is where the SLAM THINKS it is? Even if I run rostopic echo /tf I get the following: frame_id: world Does it mean that the camera_pose is relative to the world at Translation T and Rotation R? So in order to get the actual position I need to do some inverse? @DodsGTH94 , I tried looking at the above mentioned translations and rotations and compare them to ground truth. It seems like that that the transform's stamp does not follow the other transforms stamp sequence and the pose does not match any of the ground truth data. All the other transforms follow the right sequence (around 1305031251) in rgbd_dataset_freiburg1_rpy.bag from TUM, while the /world /camera_pose shows transforms at around 1551195194 secs. Therefore I dont know how to even compare it. |
@DigitalGabriele, it was a while ago, so I may be mistaken, but I believe the camera_pose, after the hamilton product, represents the position of the camera with the initial position as reference. However they are still in "magical" units indeed. For me to get real units (metres), I use my |
@Grifo07, thank you so much for answering! What about the other question: Furthermore, on the example I ran (its almost 30sec long), I only got around 300 /camera_pose tfs, while for other tfs, like /world /kinect, it was thousands. All the other transforms follow the right sequence (around 1305031251) in rgbd_dataset_freiburg1_rpy.bag from TUM, while the /world /camera_pose shows transforms at around 1551195194 secs. Therefore I dont know how to even compare it. One more question: is it possible to use EKF on top of the camera_pose to enhance the ORB-SLAM's accuracy or do you think that should be done earlier in the pipe? |
Ros rgbd example: