Conversions between tf and eigen - eigen

Eigen::Affine3f transform_temp = (Affine3f)transforms[i];
const Eigen::Matrix3d rotation_part = transform_temp.rotation().cast<double>();
const Eigen::Vector3d translation_part = transform_temp.translation().cast<double>();
tf::Matrix3x3 rot;
tf::Vector3 tra;
tf::matrixEigenToTF(rotation_part, rot);
tf::vectorEigenToTF(translation_part, tra);
tf::Transform temp_transform(rot, tra);
listener->lookupTransform (link, msg_in->header.frame_id, ros::Time(0), tfTransform);
broadcaster->sendTransform(tf::StampedTransform(tfTransform * temp_transform.inverse(), ros::Time::now(), link, "chess_board"));
I got the following error. Do not know why, I have find_package(catkin REQUIRED COMPONENTS tf tf_conversions) and also target_link_libraries(${catkin_LIBRARIES})
undefined reference to `tf::matrixEigenToTF(Eigen::Matrix<double, 3, 3, 1, 3, 3> const&, tf::Matrix3x3&)'

You have to set up you CMakeList.txt as shown in this answer to properly include Eigen in your project.
Also, you don't need to split the affine transform in the rotation and traslation components (have a look at Eigen-tf conversion).
Eigen::Affine3f transform_eigen = (Affine3f)transforms[i];
tf::Transform transform_tf;
tf::transformEigenToTF(transform_eigen, transform_tf);
EDIT:
I have suddenly thought about Eigen library and not about what could be actually the problem. Have you added the tf_conversions dependency in the package.xml file? You have not mentioned it. Also, you have to include the library: #include <tf_conversions/tf_eigen.h>

Related

How to pass an image in a Halide::Runtime::Buffer in Halide aot compilation?

So in the Halide aot example https://halide-lang.org/tutorials/tutorial_lesson_10_aot_compilation_run.html, there's this line:
Halide::Runtime::Buffer<uint8_t> input(640, 480), output(640, 480);
My question is, how does one load an image into the input runtime buffer?
The same way the previous tutorials load images.
Add this include:
#include "halide_image_io.h" // for load_image and save_image
Then replace
Halide::Runtime::Buffer<uint8_t> input(640, 480), output(640, 480);
with
Halide::Runtime::Buffer<uint8_t> input = Halide::Tools::load_image("path/to/input.png");
Halide::Runtime::Buffer<uint8_t> output(input.width(), input.height());
If you're interested in saving the output, after the error check, add the line:
Halide::Tools::save_image(output, "path/to/output.png");
Note that the paths, if not absolute paths, will be in the following directories: the Halide/tutorial/ directory for input, and the Halide/bin/build/tmp/ directory for the output, after running:
make tutorial_lesson_10_aot_compilation_run
from the root directory of Halide.
The latest syntax is as follows:
Halide::Runtime::Buffer<float> in = Tools::load_image("image.png");
Halide::Runtime::Buffer<float> out(in.width(), in.height(),in.channels());
int error = halide_blur(in, out); //halide_blur is the function defined in aot compiled code
Tools::save_image(out, output.png");

Compute Conjugate Gradient using Eigen library

I writed the following C++ code to compute the conjugate gradient of a specific matrix, compiler is CMake 3.6.2 in Ubuntu 16.04:
ConjugateGradient<SparseMatrix<double>, Lower|Upper> cg;
cg.setMaxIterations(60);
cg.compute(A);
SparseMatrix<double> beta;
beta = cg.solve(logP);
It take limitless time to run and does not stop. However, if I change the last line into:
cg.solve(logP);
the code can run and terminate, but I can't get the result of the computation. A and logP are both SparseMatrix. How should I get the result of the solve() function?
Changing the type of the result object "beta" into MatrixXd leads to the following error:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
while changing the type into VectorXd leads to:
void Eigen::PlainObjectBase<Derived>::resizeLike(const Eigen::EigenBase<OtherDerived>&) [with OtherDerived = Eigen::Solve<Eigen::ConjugateGradient<Eigen::SparseMatrix<do‌​uble>, 3>, Eigen::SparseMatrix<double> >; Derived = Eigen::Matrix<double, -1, 1>]: Assertion `other.rows() == 1 || other.cols() == 1' failed.
So I think the key problem is what type should "beta" be.

ROS ImagePtr and Image Compilation Confusion [duplicate]

This question already has an answer here:
ROS Custom message with sensor_msgs/Image Publisher
(1 answer)
Closed 7 years ago.
I am trying to create a publish a custom message that has two images. Here is the custom message file:
Header header
sensor_msgs/Image leftimage
sensor_msgs/Image rightimage
And here is the file where I try to publish the images from my stereo camera over ROS using my custom message:
sensor_msgs::ImagePtr leftmsg;
sensor_msgs::ImagePtr rightmsg;
leftmsg = cv_bridge::CvImage(std_msgs::Header(), "mono8", leftframe).toImageMsg();
rightmsg = cv_bridge::CvImage(std_msgs::Header(), "mono8", rightframe).toImageMsg();
stereo.leftimage = leftmsg;
stereo.rightimage = rightmsg;
stereo_pub.publish(stereo);
However, I am getting the following compilation error when I catkin_make:
error: no match for ‘operator=’ (operand types are ‘duo_cam::Stereo_<std::allocator<void> >::_leftimage_type {aka sensor_msgs::Image_<std::allocator<void> >}’ and ‘sensor_msgs::ImagePtr {aka boost::shared_ptr<sensor_msgs::Image_<std::allocator<void> > >}’)
stereo.leftimage = leftmsg;
^
note: candidate is:
In file included from /opt/ros/indigo/include/image_transport/publisher.h:39:0,
from /opt/ros/indigo/include/image_transport/image_transport.h:38,
sensor_msgs::Image_<std::allocator<void> >& sensor_msgs::Image_<std::allocator<void> >::operator=(const sensor_msgs::Image_<std::allocator<void> >&)
struct Image_
^
How do I correct this? I already am using the toImageMsg() function which I see online makes the ImagePtr into an Image, so not sure what is going wrong.
According to the documentation the signature of toImageMsg is
sensor_msgs::ImagePtr toImageMsg() const;
that is it does not convert the ImagePtr to Image (CvImage is used to convert OpenCV images to ROS images). This can also be seen by the fact that you declared leftmsg and rightmsg as ImagePtr; if toImageMsg would return Image, this would not work.
To get the Image of a ImagePtr, just dereference the pointer. The following should work:
stereo.leftimage = *leftmsg;
stereo.rightimage = *rightmsg;

Error testing OGRE's tutorial code. incomplete type 'Ogre::MeshManager'

I am trying to go through the OGRE's tutorial #2.
I successfully went trough the first part.
My problem is when I try to compile I get an error in this method:
void TutorialApplication::createScene(void){
mSceneMgr->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));
mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
Ogre::Entity* entNinja = mSceneMgr->createEntity("Ninja", "ninja.mesh");
entNinja->setCastShadows(true);
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
headNode->attachObject(entNinja);
Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0);
Ogre::MeshManager::getSingleton().createPlane("ground", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
plane, 1500, 1500, 20, 20, true, 1, 5, 5, Ogre::Vector3::UNIT_Z);
Ogre::Entity* entGround = mSceneMgr->createEntity("GroundEntity", "ground");
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(entGround);
entGround->setCastShadows(false);
entGround->setMaterialName("Examples/Rockwall");
}
The error I get is:
error: incomplete type 'Ogre::MeshManager' used in nested name
specifier
Ogre::MeshManager::getSingleton().createPlane("ground", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Which is weird, because apparently anybody is having problems with this tutorial. I am using Ogre 1.9 which I compiled in my machine (Ubuntu 14.04 x64).
If you add the following include into your code, it should work. The reason for your issue might be, that the respective tutorial has not been updated to match Ogre 1.9.
#include <OgreMeshManager.h>

Clang does not compile a g++ project

When trying to compile a g++ project with the clang compiler, there is a strange error showing up.
Here is the snippet of the source file:
std::set<TTransportNetworkId> l_transportNetworkIds;
SelectionResultContainer l_searchResult = p_repo.rootMoc() / LnAny("LNBTS") / LnAny("LNMME");
BOOST_FOREACH(const SelectionResult & l_lnmmeSR, l_searchResult)
{
const MoLnmme & l_lnmme = l_lnmmeSR;
l_transportNetworkIds.insert(*l_lnmme.transportNwId);
}
The error message is:
conditional expression is ambiguous; 'rvalue_probe<Rrom::DataRep::SelectionResultContainer>' can be converted to 'Rrom::DataRep::SelectionResultContainer' and vice versa
BOOST_FOREACH(const SelectionResult & l_lnmmeSR, l_searchResult)
Conditions are:
The file compiles fine with gcc_4.3.2
clang in version 3.2 throws the above error
Already tried to include the latest boost library which results in the same error
My guess is that clang handles rvalue conditions differently than this gcc version does.
clang is supposed to be a drop-in-replacement for gcc, so how can one get rid of this error without touching the source file?
Are there any options in clang which somehow disables these kind of errors?!
UPDATE:
I could create an example source file, which you can reproduce for yourself:
#include <vector>
#include <boost/foreach.hpp>
class A : public std::vector<int>
{
public:
template <class T>
operator const T &() const;
};
void foo(){
A colA;
int b = 1;
BOOST_FOREACH(b, colA)
{
;
}
}
When compiled with clang 3.2 the above error is raised, with some additional insights to where exactly the error occurs:
error: conditional expression is ambiguous; 'rvalue_probe<A>' can be converted to 'A' and vice versa BOOST_FOREACH(b, colA)
expanded from macro 'BOOST_FOREACH' f (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL))
expanded from macro 'BOOST_FOREACH_CONTAIN' BOOST_FOREACH_EVALUATE(COL)
expanded from macro 'BOOST_FOREACH_EVALUATE' (true ? boost::foreach_detail_::make_probe((COL), BOOST_FOREACH_ID(_foreach_is_rvalue)) : (COL))
This code is compiled without errors with gcc_4.7.2.
Any ideas why the two compilers behave differently?
I found the solution in this document, see http://www.boost.org/doc/libs/1_43_0/boost/foreach.hpp
Snippet:
// Some compilers do not correctly implement the lvalue/rvalue conversion
// rules of the ternary conditional operator.
# if defined(BOOST_FOREACH_NO_RVALUE_DETECTION)
So, when providing a -DBOOST_FOREACH_NO_RVALUE_DETECTION definition option to clang, the error disappears.
Still the question remains whether gcc or clang is right or wrong on this point.

Resources