Eigen passing Quaternionf, discards qualifiers - c++

i am trying to use Eigen::Quaternionf. But i am getting when i just want to asign one Quaternion an error.
oldQuat = pos;
both are Eigen::Quaternionf, the following error is given. Is must be because the Methods are declared as constant (see: http://eigen.tuxfamily.org/dox/classEigen_1_1Quaternion.html)
Fehler: passing 'const Quaternionf {aka const Eigen::Quaternion<float>}' as 'this' argument of 'Eigen::Quaternion<Scalar, Options>& Eigen::Quaternion<Scalar, Options>::operator=(const Eigen::Quaternion<Scalar, Options>&) [with _Scalar = float, int _Options = 0, Eigen::Quaternion<Scalar, Options> = Eigen::Quaternion<float>]' discards qualifiers [-fpermissive]
I have to idea on how to get past this error. Thanks in advance
edit:
for (itCanon = canonicalValues.begin(), itTraj = exampleTraj.begin(); itCanon != canonicalValues.end(); ++itCanon, itTraj++)
{
const SampledTrajectoryV2::TrajData& state = *itTraj;
Eigen::Vector3f axis;
axis << itTraj->getPosition(1), itTraj->getPosition(2), itTraj->getPosition(3);
Eigen::AngleAxisf angleAxis(itTraj->getPosition(0), axis);
Eigen::Quaternionf pos(angleAxis);
pos.normalize();
//Error in both these lines! Same error both times.
Eigen::Vector3f vecVel = calcAngularVelocity(oldQuat, pos);
oldQuat = pos;
// D0 element R3x3 nicht kompatibel mit quat
result[*itCanon] = - A_Z*(B_Z*2*log(pos) - TAU * vecVel);
}
oldQuat is declared in the header. as are A_z, B_Z and TAU.

Eigen::Quaternionf<S, O>::operator= is declared as non const, but oldQuat is a const object (I suspect). Change it to non-const.

Related

why I cannot multiply an op result by the constant eigen tensor array

Why it's not legal to do multiplication of the tensor op(sqrt()) and the linear.constant()
Eigen::Tensor<float, 1> linear(2);
linear.setValues({3,4});
auto linear_square = linear * linear;
auto linear_square_sum = linear_square.sum().sqrt();
std::cout<<linear_square_sum<<std::endl; // 5
auto new_linear = linear_square_sum * linear.constant(5); //no compiling error but aborted when executing
error info
tensor2matrix:
/usr/local/include/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h:380:
Eigen::TensorEvaluator, Device>::TensorEvaluator(const XprType&,
const Device&) [with BinaryOp =
Eigen::internal::scalar_product_op; LeftArgType = const
Eigen::TensorCwiseUnaryOp,
const Eigen::TensorReductionOp,
const Eigen::DimensionList, const
Eigen::TensorCwiseBinaryOp, const Eigen::Tensor, const Eigen::Tensor
, Eigen::MakePointer> >; RightArgType = const Eigen::TensorCwiseNullaryOp,
const Eigen::Tensor >; Device = Eigen::DefaultDevice;
Eigen::TensorEvaluator, Device>::XprType =
Eigen::TensorCwiseBinaryOp, const
Eigen::TensorCwiseUnaryOp,
const Eigen::TensorReductionOp,
const Eigen::DimensionList, const
Eigen::TensorCwiseBinaryOp, const Eigen::Tensor, const Eigen::Tensor
, Eigen::MakePointer> >, const Eigen::TensorCwiseNullaryOp,
const Eigen::Tensor > >]: Assertion
`dimensions_match(m_leftImpl.dimensions(), m_rightImpl.dimensions())'
failed. Aborted
I'm pretty sure people already linked to you the documentation saying that using auto with expression templates is not a good idea. Evaluating one expression template multiple times seems like an even worse idea.
If you don't want/can't explicitly mention the types you can base them on the original values you put in.
Eigen::Tensor<float, 1> linear(2);
linear.setValues({ 3,4 });
decltype(linear) linear_square = linear * linear;
Eigen::Tensor<decltype(linear)::Scalar, 0> linear_square_sum = linear_square.sum().sqrt();
std::cout << linear_square_sum << std::endl; // 5
// Don't forget to convert to an actual scalar
// |
// v
decltype(linear) new_linear = linear_square_sum() * linear.constant(5);
std::cout << new_linear;
return 0;

Usage of accumulate with a custom object

I am using opencv library with C++, and I am trying to compute sum of points which are contained in vector<Point2f> difference
Point class has x property which is float.
float pointSumX(Point2f pt1,Point2f pt2)
{
return (pt1.x + pt2.x);
}
I defined function as above, and call it from accumulate shown below. But it throws error.
float avgMotionX = accumulate(difference.begin(),difference.end(),0,pointSumX);
Error is:
error: could not convert ‘__init’ from ‘int’ to ‘cv::Point_’ __init = __binary_op(__init, *__first);
Note: I am using C++11
float pointSumX(Point2f pt1, Point2f pt2)
should be
float pointSumX(float lhs, const Point2f& rhs)
{
return lhs + rhs.x;
}
as lhs is the accumulator.
Note also that you should call it
std::accumulate(difference.begin(), difference.end(), 0.f, pointSumX); // 0.f instead of 0
to return float and not int.

no match for 'operator =' for 3d vector

I am trying to convert a vector of coordinates std::vector surface into a 3D array, setting all entries of the 3d array that are contained in surface to 0;
however I am getting a no match for operator array.
I looked up the error several times but did not find my case....
std::vector<coordinates> surface is global.
the coordiantes simply look like
struct coords{
int xvalue;
int yvalue;
int zvalue;
coords(int x1, int y1, int z1) : xvalue(x1),yvalue(y1),zvalue(z1){}
~coords(){}
};
typedef struct coords coordinates;
and my method is:
(doubleBox is a typedef for a 3D double vector)
doubleBox levelset::putIntoBox( vector<coordinates> surface){
int xMaxs, yMaxs,zMaxs;
for (vector<coordinates>::iterator it = surface.begin() ; it != surface.end(); ++it){
if (it->xvalue > xMaxs)
xMaxs = it->xvalue;
if (it->yvalue > yMaxs)
yMaxs = it->yvalue;
if (it->zvalue > zMaxs)
zMaxs = it->zvalue;
//check invalid surface
if (it->xvalue < 0 || it->yvalue <0 || it->zvalue<0)
cout << "invalid surface with point coordinates below 0 !" << endl;
}
doubleBox surfaceBox[xMaxs+1][yMaxs+1][zMaxs+1];
int max = std::ceil(sqrt(xMaxs*xMaxs + yMaxs*yMaxs + zMaxs*zMaxs));
std::fill(&surfaceBox[0][0][0],&surfaceBox[0][0][0] + sizeof(surfaceBox)*sizeof(surfaceBox[0])/ sizeof(surfaceBox[0][0]) / sizeof(surfaceBox[0][0]), max);
for (vector<coordinates>::iterator it = surface.begin() ; it != surface.end(); it++){
surfaceBox[it->xvalue][it->yvalue][it->zvalue] = 0.0;
}
return surfaceBox;
}
the output is (declaring that the error lies in the second for-loop)
c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\vector.tcc:160:5: note: std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = std::vector<std::vector<double> >; _Alloc = std::allocator<std::vector<std::vector<double> > >]
vector<_Tp, _Alloc>::
^
c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\bits\vector.tcc:160:5: note: no known conversion for argument 1 from 'const int' to 'const std::vector<std::vector<std::vector<double> > >&'
..\src\Levelset.cpp: In member function 'doubleBox levelset::putIntoBox(std::vector<coords>)':
..\src\Levelset.cpp:295:1: warning: control reaches end of non-void function [-Wreturn-type]
Maybe this problem is caused by the fact that std::fill is used inappropriately??
Since doubleBox is defined as std::vector<std::vector<std::vector<double>, why do you define doubleBox surfaceBox[xMaxs+1][yMaxs+1][zMaxs+1]; in this way?
What you defined is a 3 dimensional array whose element type is doubleBox, which means that every element is of type std::vector<std::vector<std::vector<double>, which is not what you want.
You may need something like doubleBox surfaceBox(xMaxs + 1, std::vector<std::vector<double>>(yMaxs + 1, std::vector<double>(zMaxs + 1)));

get xyz from vector

Below is a function which helps control the car, it creates a matrix then creates a vector using that matrix and now I want to be able to get the x,y and z from that vector.
I've tried i32 CarX = vecVel.GetX; but im getting these three errors
error C3867: 'Vec2::GetX': function call missing argument list; use '&Vec2::GetX' to create a pointer to member
error C2440: '=' : cannot convert from 'const float (__thiscall Vec2::* )(void) const' to 'i32'
IntelliSense: a pointer to a bound function may only be used to call the function
I thought i32 carX = vecVel[0]; might work but no. i32 carX = vecVel.FX; doesnt work because it says FX is protected
void APIENTRY Car_Update(Object *pObject)
{
Car *pCar=(Car *)pObject;
Matrix mat;
Matrix *pmat;
Object_GetMatrix(pObject,&mat);
Object_GetMatrixPtr(pObject,&pmat);
Vec3 vecVel(pCar->vecBounce + mat.GetColumn(2) * pCar->fSpeed);
pCar->vecBounce = pCar->vecBounce *0.5f;
mat.RotY(pCar->fRot);
mat.SetColumn(3, vecVel + mat.GetColumn(3));
//mat.GetColumn;
pCar->fSpeed *= 0.8f;// friction
pCar->fRotWheelLast = pCar->fRotWheel;
pCar->fRotWheel += (pCar->fSpeed*30.f);
Level_GenerateDraw( &mat.GetColumn(3) );
Level_GenerateAlphas( &mat.GetColumn(3) );
Car_Light(pCar);
Collision_UpdateMat(pCar->pBox, &mat);
float fCol=1.f;
while(Level_TestBoxCollide( pCar->pBox ))
{
ColData Data;
float fDot;
Collision_GetColData(&Data);
fDot = -1.8f * Data.normal.Dot(vecVel);
pCar->vecBounce = (vecVel + Data.normal * fDot)*fCol;
pCar->fSpeed = 0.f;
mat.SetColumn(3, pmat->GetColumn(3) + pCar->vecBounce);
Collision_UpdateMat(pCar->pBox, &mat);
vecVel = pCar->vecBounce;
fCol-=0.1f;
if(fCol<0.f)
{
pCar->vecBounce.Set(0.f,0.f,0.f);
mat.SetColumn(3, pmat->GetColumn(3));
Collision_UpdateMat(pCar->pBox, &mat);
ASSERT(!Level_TestBoxCollide( pCar->pBox ), "still colliding");
}
}
Object_SetMatrix(pObject, &mat);
Vec3 vecWidth(mat.GetColumn(0)*0.2f);
Vec3 vecWheel1(mat.GetColumn(3) - mat.GetColumn(0)*0.6f);
Vec3 vecWheel2(mat.GetColumn(3) + mat.GetColumn(0)*0.6f);
vecWheel1.SetY( vecWheel1.GetY() - 0.7f );
vecWheel2.SetY( vecWheel2.GetY() - 0.7f );
Trail_AddPoint((Object*)pCar->pTrail[0], vecWheel1, vecWidth);
Trail_AddPoint((Object*)pCar->pTrail[1], vecWheel2, vecWidth);
}
The compiler is telling you that in order to call a function on a class you must follow the call with parentheses: i32 carX = vecVel.FX(). That is assuming that FX is a function that returns an i32 value on Vec2.

"Cannot initialize a parameter of type 'float *' with an Ivalue of type 'float'" compiler error

I am making a game in xcode with c++, opengl and GLUT. I have a model which has its own .h and .cpp file and I have drawn it but I now want to translate it. I can't use gltranslate because I want to move only the gun, not my camera. The model file goes as follows:
//M4.h
extern unsigned int M4NumVerts;
extern float M4Verts [151248];
extern float M4Normals [140064];
extern float M4TexCoords [153680];
//M4.cpp
unsigned int M4NumVerts = 37812;
float M4Verts [151248] = {
// f 1/1/1 1582/2/1 4733/3/1
-0.00205801177070031, 0.0252329378141267, -0.266482197565778,
-0.00205347560809555, 0.015738643990207, -0.265580239652506,
-0.00908273427886488, 0.018200092410135, -0.264843587943923,...};
float M4Normals [140064] = {
// f 1/1/1 1582/2/1 4733/3/1
-0.1361849642872, -0.0937589754128839, -0.986236741371776,
-0.1361849642872, -0.0937589754128839, -0.986236741371776,
-0.1361849642872, -0.0937589754128839, -0.986236741371776,...};
float M4TexCoords [153680] = {
// f 1/1/1 1582/2/1 4733/3/1
0.110088, 0.229552,
0.108891, 0.243519,
0.119508, 0.240861,..};
I have a function in my math class that translates the points like this:
void Math::translatePoint(float P[3], float x, float y, float z){
P[0] += x;
P[1] += y;
P[2] += z;
}
The function works for one point if I do the following:
Math::translatePoint(M4Verts[x], 0, 0, -0.5);
I want it to work for all the points so I made this for loop:
for (int x = 0; x < M4NumVerts; x++) {
Math::translatePoint(M4Verts[x], 0, 0, -0.5);
}
I do this but it wont work and I am met with the error:
Cannot initialize a parameter of type 'float *' with an Ivalue of type 'float'
I have searched around and tried to find alternatives like defining x as a float instead but nothing I try works. Can anybody help.
translatePoints expects an array of float of length 3. But you are passing a single float. Hence the compiler error. I'm afraid that I cannot discern what you are trying to do and so suggest the code that would be correct.