Given an octomap::OcTree, how can I get the cartesian coordinates of the occupied cells?
double printOccupied(boost::shared_ptr<octomap::OcTree> octree) {
// Get some octomap config data
auto res = octree->getResolution();
unsigned int max_depth = octree->getTreeDepth();
// Iterate over nodes
int count = 0;
std::cout << "printOccupied: octree res = " << res << std::endl;
std::cout << "printOccupied: octree max depth = " << max_depth << std::endl;
std::cout << "printOccupied: iterating over nodes..." << std::endl;
for (octomap::OcTree::iterator it = octree->begin(); it != octree->end(); ++it) {
if (octree->isNodeOccupied(*it) && it.getDepth() < max_depth) {
count++;
// Fetching the coordinates in octomap-space
std::cout << " x = " << it.getX() << std::endl;
std::cout << " y = " << it.getY() << std::endl;
std::cout << " z = " << it.getZ() << std::endl;
std::cout << " size = " << it.getSize() << std::endl;
std::cout << " depth = " << it.getDepth() << std::endl;
// Then convert to meters???
auto cell = std::make_tuple(it.getX() * res,
it.getY() * res,
it.getZ() * res);
}
}
std::cout << "printOccupied: number of occupied cells = " << count << std::endl;
}
For when I pass in an octree that is generated from an empty PlanningScene I get 0 occupied cells, as expected. When I use a scene that is known to have a single sphere of radius 0.05 meters at xyz coordinates (0.1, 0.8, 0.1), according to the scene's reference frame (also meters), I get the following output:
printOccupied: octree res = 0.02
printOccupied: octree max depth = 16
printOccupied: iterating over nodes...
x = -327.68
y = -327.68
z = -327.68
size = 655.36
depth = 1
x = 327.68
y = -327.68
z = -327.68
size = 655.36
depth = 1
x = -491.52
y = 491.52
z = -491.52
size = 327.68
depth = 2
x = 327.68
y = 327.68
z = -327.68
size = 655.36
depth = 1
x = -92.16
y = 624.64
z = 51.2
size = 20.48
depth = 6
x = -81.92
y = 409.6
z = 245.76
size = 163.84
depth = 3
x = -419.84
y = 624.64
z = 378.88
size = 20.48
depth = 6
x = -409.6
y = 409.6
z = 573.44
size = 163.84
depth = 3
x = 327.68
y = 327.68
z = 327.68
size = 655.36
depth = 1
printOccupied: number of occupied cells = 9
Surely there must be some conversion needed, as these octomap xyz values do not correspond to a single small sphere as expected. What is this conversion?
I see that the problem is the way in which you are using iterators. An octree has the structure of a tree, and the kind of iterator you are using navigates through the tree without taking into account the depth of the cells.
The depth counts from the tree root, so the cells that you show as output are high-level cells which should not be used, in general, for collision check purposes because of their size (depth=1 is the root of the tree, which contains 4 cells of depth 2... and that goes on recursively until max_depth, which is normally 16).
I understand that you want to know which leaf cells (the smaller ones) are occupied, and you have one iterator which might help you to do so. Here is how I do it:
for(OcTree::leaf_iterator it = octree->begin_leafs(), end = octree->end_leafs(); it != end; ++it){
// Fetching the coordinates in octomap-space
std::cout << " x = " << it.getX() << std::endl;
std::cout << " y = " << it.getY() << std::endl;
std::cout << " z = " << it.getZ() << std::endl;
std::cout << " size = " << it.getSize() << std::endl;
std::cout << " depth = " << it.getDepth() << std::endl;
}
}
No conversion is needed, xyz are already in global coordinates of the map.
Note: If you need to navigate only through cells which are inside a bounding box, take a look to the methods octree->begin_leafs_bbx() and end_leafs_bbx() to create your iterator. If you need to limit the depth of the leafs I think you can do that with those methods too.
I hope this helps. Best regards,
Adrián
EDIT: changed the code in the answer because of an error in the return type of begin_leafs(). Also, noted that begin_leafs() and end_leafs() have the same behavior than begin() and end() according to the Octomap API.
Related
I am trying to check if some compressed public key corresponds to an elliptic curve equation (secp256k1). As far as I know it should be valid once the following equation is fulfill y^2 = x^3 + ax + b or y^2 % p = (x^3 +ax +b) % p. Supposing that I have the following key:
pubkey = 027d550bc2384fd76a47b8b0871165395e4e4d5ab9cb4ee286d1c60d074d7d60ef
I am able to extract x-coordinate (do to it in this case I strip 02), in theory to calculate y without sqrt operation (due to losing precision) we can do in this case: y = (x^exp) % p, where exp = (p+1)/4 based on https://crypto.stackexchange.com/questions/101142/proof-that-user-compressed-public-key-corresponds-the-curve-equation-secp256k1
Now based on how I calculate y:
bmp::uint1024_t const y = bmp::powm(x, pp, p);
//or
bmp::uint1024_t const yy = (x^pp) % p;
I have other results, which impact later computations, generally the second example gives correct final result, but it seems, that for some reasons it doesn't work as it should... for power operation it gives the following result:
bmp::pow(x, pp): 5668936922878426254536308284732873549115769122415677675761389126416312181579**1**
x^pp: 5668936922878426254536308284732873549115769122415677675761389126416312181579**0**
Even in python3 code for x^pp I have the same result as the second one, so should I use something other than boost::multiprecision ? or do these computation in other way ?
Code can be test here: https://wandbox.org/permlink/JQ3ipCq6yQjptUet
#include <numeric>
#include <iostream>
#include <string>
#include <boost/multiprecision/cpp_int.hpp>
namespace bmp = boost::multiprecision;
bool verify(std::string const& address, std::size_t const stripped_prefix_size)
{
auto is_address_correct{false};
bmp::uint1024_t const p = bmp::uint1024_t{"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"} % 4;//3 % 4;//{"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"};
bmp::uint1024_t const a{"0x0000000000000000000000000000000000000000000000000000000000000000"};
bmp::uint1024_t const b{"0x0000000000000000000000000000000000000000000000000000000000000007"};
bmp::uint1024_t x{std::string{"0x"} + address.substr(2, address.size() - stripped_prefix_size)};
auto const right = (bmp::pow(x, 3) + (a * x) + b) % p;
//bmp::uint1024_t const y = bmp::sqrt(right) % p;
bmp::uint1024_t pp = (p + 1) / 4;
bmp::uint1024_t const y = bmp::powm(x, pp, p);
bmp::uint1024_t const yy = (x^pp) % p;//bmp::powm(x, pp, p);
auto const left = bmp::powm(y, 2, p);
auto const left2 = bmp::powm(yy, 2, p);
std::cout << "x: " << x << std::endl;
std::cout << "y pow pp: " << bmp::pow(x, pp.convert_to<int>()) << std::endl;
std::cout << " y^pp: " << bmp::uint1024_t{x^pp} << std::endl;
std::cout << "yy mod p: " << yy << std::endl;
std::cout << " y mod p: " << y << std::endl;
std::cout << "yy: " << yy << std::endl;
std::cout << "right: " << right << std::endl;
std::cout << " left: " << left << std::endl;
std::cout << "left2: " << left2 << std::endl;
is_address_correct = (left == right);
return is_address_correct;
}
int main()
{
auto const res = verify("027d550bc2384fd76a47b8b0871165395e4e4d5ab9cb4ee286d1c60d074d7d60ef", 2);
std::cout << "\nis valid: " << res << std::endl;
return 0;
}
Output:
x: 56689369228784262545363082847328735491157691224156776757613891264163121815791
y pow pp: 56689369228784262545363082847328735491157691224156776757613891264163121815791
y^pp: 56689369228784262545363082847328735491157691224156776757613891264163121815790
yy mod p: 2
y mod p: 0
yy: 2
right: 1
left: 0
left2: 1
is valid: 0
For the compressed key
027d550bc2384fd76a47b8b0871165395e4e4d5ab9cb4ee286d1c60d074d7d60ef
the uncompressed representation is
047d550bc2384fd76a47b8b0871165395e4e4d5ab9cb4ee286d1c60d074d7d60effbb6217403fe57ff1b2f84f74086b413c7682027bd6ddde4538c340ba1a25638
i.e.
x = 0x7d550bc2384fd76a47b8b0871165395e4e4d5ab9cb4ee286d1c60d074d7d60ef = 56689369228784262545363082847328735491157691224156776757613891264163121815791
y = 0xfbb6217403fe57ff1b2f84f74086b413c7682027bd6ddde4538c340ba1a25638 = 113852322045593354727100676608445520152048120867463853258291211042951302108728
This is also confirmed by the following code using the Boost library:
bool verify(std::string const& address, std::size_t const stripped_prefix_size)
{
auto is_address_correct{false};
bmp::uint1024_t const p = bmp::uint1024_t{"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"};
bmp::uint1024_t const a{"0x0000000000000000000000000000000000000000000000000000000000000000"};
bmp::uint1024_t const b{"0x0000000000000000000000000000000000000000000000000000000000000007"};
bmp::uint1024_t x{std::string{"0x"} + address.substr(2, address.size() - stripped_prefix_size)};
bmp::uint1024_t right = (bmp::powm(x, 3, p) + (a * x) + b) % p;
bmp::uint1024_t y = bmp::powm(right, (p + 1) / 4, p); // even, i.e. equals the searched y value because of leading 0x02 byte
bmp::uint1024_t left = bmp::powm(y, 2, p);
std::cout << "x: " << x << std::endl; // x: 56689369228784262545363082847328735491157691224156776757613891264163121815791
std::cout << "y: " << y << std::endl; // y: 113852322045593354727100676608445520152048120867463853258291211042951302108728
std::cout << "right: " << right << std::endl; // right: 33769945388650438579771708095049232540048570303667364755388658443270938208149
std::cout << "left: " << left << std::endl; // left: 33769945388650438579771708095049232540048570303667364755388658443270938208149
is_address_correct = (left == right);
return is_address_correct;
}
The code contains the following fixes/considerations:
When calculating y, not x but right must be applied.
The solution has two values -y and +y, s. here. Because of the leading 0x02 byte, that value must be used which has an even parity in the positive, and this is true here for +y.
The value for p must not be taken modulo 4 (see comment by President James K. Polk). The congruence of the modulus to 3 modulo 4 is only relevant for finding the correct solution path. A more detailed explanation can be found here.
I have a point-cloud. I want to get its RGB value. How can I do that?
To make my question clearer, please see the codes.
// Load the first input file into a PointCloud<T> with an appropriate type :
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud1 (new pcl::PointCloud<pcl::PointXYZRGB>);
if (pcl::io::loadPCDFile<pcl::PointXYZRGB> ("../data/station1.pcd", *cloud1) == -1)
{
std::cout << "Error reading PCD file !!!" << std::endl;
exit(-1);
}
I want to get each value alone
std::cout << " x = " << cloud1->points[11].x << std::endl;
std::cout << " y = " << cloud1->points[11].y << std::endl;
std::cout << " z = " << cloud1->points[11].z << std::endl;
std::cout << " r = " << cloud1->points[11].r << std::endl;
std::cout << " g = " << cloud1->points[11].g << std::endl;
std::cout << " b = " << cloud1->points[11].b << std::endl;
But as a result I get something like that :
x = 2.33672
y = 3.8102
z = 8.86153
r = �
g = w
b = �
From the point cloud docs:
A point structure representing Euclidean xyz coordinates, and the RGB color.
Due to historical reasons (PCL was first developed as a ROS package), the RGB information is packed into an integer and casted to a float. This is something we wish to remove in the near future, but in the meantime, the following code snippet should help you pack and unpack RGB colors in your PointXYZRGB structure:
// pack r/g/b into rgb
uint8_t r = 255, g = 0, b = 0; // Example: Red color
uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
p.rgb = *reinterpret_cast<float*>(&rgb);
To unpack the data into separate values, use:
PointXYZRGB p;
// unpack rgb into r/g/b
uint32_t rgb = *reinterpret_cast<int*>(&p.rgb);
uint8_t r = (rgb >> 16) & 0x0000ff;
uint8_t g = (rgb >> 8) & 0x0000ff;
uint8_t b = (rgb) & 0x0000ff;
Alternatively, from 1.1.0 onwards, you can use p.r, p.g, and p.b directly.
Definition at line 559 of file point_types.hpp.
Background: I am implementing the nearest neighbor algorithm for the Traveling-Salesman-Problem. I need to calculate the distance traveled for the tour as well as keep track of the order of points visited. I have defined a point class with instance variables x and y and a function calcDist for calculating the distance between two points. I start by storing all of the points in a std::unordered_set named points, creating an empty std::vector named path to store the tour path, and assigning the starting point to startPoint, and pass these to my nearestNeighbor() function:
void nearestNeighbor(unordered_set<Point, PointHasher> points, vector<Point> &path, Point startPoint) {
// Declare variables
unordered_set<Point, PointHasher>::iterator it;
Point currentLocation, possibleNeighbor, nearestNeighbor;
double totalDist = 0;
int pointsCount = path.capacity() - 1;
// Set the starting location
it = points.find(startPoint);
currentLocation = *it;
path[0] = currentLocation;
points.erase(currentLocation);
cout << "Start location: " << path[0].x << ", " << path[0].y << endl;
// Create the path
for (int i = 1; points.size() > 0; i++) {
double minDist = -1;
// Find the current location's nearest neighbor
for (it = points.begin(); it != points.end(); it++) {
possibleNeighbor = *it;
int currentDist = currentLocation.calcDist(possibleNeighbor);
if (minDist == -1 || currentDist < minDist) {
minDist = currentDist;
nearestNeighbor = possibleNeighbor;
}
}
// Record nearest neighbor data and prepare for the next iteration
currentLocation = nearestNeighbor;
path[i] = currentLocation;
points.erase(currentLocation);
totalDist += minDist;
cout << "Nearest neighbor: " << path[i].x << ", " << path[i].y << endl;
}
// Return to the starting location
path[pointsCount] = startPoint;
cout << "End location: " << startPoint.x << ", " << startPoint.y << endl;
cout << "Path:" << endl;
for (int i = 0; i < path.size(); i++) {
cout << path[0].x << ", " << path[0].y << endl;
}
cout << "Total distance: " << totalDist << endl;
}
The problem is that once the program exits the outer for loop, all the points in path are overwritten somehow. To see what I mean, here is the output:
Start location: 3, 4
Nearest neighbor: 6, 8
Nearest neighbor: 11, 7
Nearest neighbor: 50, 8
End location: 3, 4
Path:
3, 4
3, 4
3, 4
3, 4
3, 4
Total distance: 49
Press any key to continue . . .
I am thinking this either has to be a problem with pointers/addresses of the vector elements, or something with scope since the problem happens after exiting the for loop. I have even tried printing the path[1] after each iteration to see when it gets changed, but it is correct throughout the loop, and only changes in the output at the end. Any thoughts? I am stumped. And if you have made it this far, thank you very much for your time.
you are always outputing the coordinates of path[0] man
for (int i = 0; i < path.size(); i++) {
cout << path[0].x << ", " << path[0].y << endl;
}
You have
for (int i = 0; i < path.size(); i++) {
cout << path[0].x << ", " << path[0].y << endl;
}
This doesn't iterate through i. Change your 0 to i and you'll likely see something more helpful:
for (int i = 0; i < path.size(); i++) {
cout << path[i].x << ", " << path[i].y << endl;
}
Edit: Change path[i] = currentLocation; to path.push_back(currentLocation); - this will automatically increase the size of your path vector to fit the new elements.
void nearestNeighbor(
unordered_set<Point, PointHasher> points,
vector<Point> &path,
Point startPoint,
double &totalDist) // note the new variable passed here
{
// Declare variables
unordered_set<Point, PointHasher>::iterator it;
Point currentLocation, possibleNeighbor, nearestNeighbor;
// double totalDist = 0; Remove this line
// int pointsCount = path.capacity() - 1; And this
// Set the starting location
it = points.find(startPoint);
currentLocation = *it;
path.push_back(currentLocation); // Changed this line
points.erase(currentLocation);
cout << "Start location: " << path[0].x << ", " << path[0].y << endl;
// Create the path
for (int i = 1; points.size() > 0; i++) {
double minDist = -1;
// Find the current location's nearest neighbor
for (it = points.begin(); it != points.end(); it++) {
possibleNeighbor = *it;
int currentDist = currentLocation.calcDist(possibleNeighbor);
if (minDist == -1 || currentDist < minDist) {
minDist = currentDist;
nearestNeighbor = possibleNeighbor;
}
}
// Record nearest neighbor data and prepare for the next iteration
currentLocation = nearestNeighbor;
path.push_back(currentLocation); // And this line
points.erase(currentLocation);
totalDist += minDist;
cout << "Nearest neighbor: " << path[i].x << ", " << path[i].y << endl;
}
// Return to the starting location
path.push_back(startPoint); // And here also!
cout << "End location: " << startPoint.x << ", " << startPoint.y << endl; // This I didn't change,
// but perhaps you should make it reflect the last point in the vector,
// not the start point which is supposed to be the last point in the vector
cout << "Path:" << endl;
for (int i = 0; i < path.size(); i++) {
cout << path[i].x << ", " << path[i].y << endl;
}
cout << "Total distance: " << totalDist << endl;
}
I do not see any place which grows the size of the path vector.
I suspect that you're passing an empty std::vector, for the second argument, and as soon as you hit path[0]=currentLocation; ... undefined behavior.
Also, I don't think that capacity() does what you think it does.
That, and, as others have pointed out, you're not outputing the contents of the array correctly, but that's a minor problem. The major problem here is that this program is likely scribbling over and corrupting the heap.
I am trying to make a terrain using a height map image in OpenGL. As a experiment i use 4x4 pixel image. this is a zoomed screen shot. so you can see the pixels.
This is a part of my code.
ILubyte * image = ilGetData();
int bpp = ilGetInteger(IL_IMAGE_BPP);
std::cout << "BPP = " << bpp << std::endl;
for (int z=0; z < terrainHeight; ++z)
{
for (int x=0; x < terrainWidth; ++x)
{
pVertices[z*terrainWidth+x] = NxVec3(NxF32(x),
NxF32(image[z*terrainWidth+x]*bpp), NxF32(z));
}
}
for (int i=0; i < vertexCount; ++i)
{
std::cout << "x = " << pVertices[i].x << "\t y = "
<< pVertices[i].y << "\t z = " << pVertices[i].z << std::endl;
}
Then, i'm getting the following result.
I'm expecting the zero values(for y-coordinate) for (0,0), (1,1), (2,2) and (3,3). but the result is different. why i'm not getting the expected results ?
I think it should be image[(z*terrainWidth+x)*bpp] instead of image[z*terrainWidth+x]*bpp.
So I'm having what seems to me to be a very bizarre problem. I've got a crude system for applying forces to objects on 2D planes, and one of the simplest calculations seems to be causing one of my variables to overflow. I have the following line:
int ySign = m_Momentum.y / abs(m_Momentum.y);
Where Momentum has two data members, x y (m_Momentum is an SFML sf::Vector2 of floats). Now, normally the formula should always return either 1 or -1, depending on the sign of Momentum.y (unless I'm grossly mistaken).
However, it occasionally returns insanely high numbers such as -2147483648. In that particular case, the value of m_Momentum.y was 0.712165 (both values were obtained by sending to std::cout); I tried again, m_Momentum.y was -0.578988 and ySign was still -2147483648. There is a corresponding xSign that also flips out sometimes, often with the same final value. I can't confirm 100% that this is always the result, but at the moment that seems to be the case.
I'm sort of stumped as to why this is happening, and when it does, it basically invalidates my program (it instantly sends objects millions of pixels in the wrong direction). It seems logically impossible that the line above is returning such strange results.
Below is the function I am working on. Probably the wrong way to do it, but I didn't expect it to go so horribly wrong. The printout it produces reveals that all numbers look normal until the signs are printed out; one of them is invariably massive, and afterwards you see numbers like -2.727e+008 (which, as far as I'm aware, is scientific notation - i.e. -2.727 * 10 ^ 8).
///MODIFY MOMENTUM
//Reset, if necessary
if (Reset == true)
{
m_Momentum.x = 0;
m_Momentum.y = 0;
}
sf::Vector2<float> OldMoment = m_Momentum;
//Apply the force to the new momentum.
m_Momentum.x += Force.x;
m_Momentum.y += Force.y;
sf::Vector2<float> NewMoment = m_Momentum;
//Calculate total momentum.
float sqMomentum = m_Momentum.x * m_Momentum.x + m_Momentum.y * m_Momentum.y;
float tMomentum = sqrt(sqMomentum);
//Preserve signs for later use.
int xSign = m_Momentum.x / abs(m_Momentum.x);
int ySign = m_Momentum.y / abs(m_Momentum.y);
//Determine more or less the ratio of importance between x and y components
float xProp;
float yProp;
if (abs(tMomentum) > m_MaxVelocity)
{
//Get square of maximum velocity
int sqMax = m_MaxVelocity * m_MaxVelocity;
//Get proportion of contribution of each direction to velocity
xProp = (m_Momentum.x * m_Momentum.x) / sqMomentum;
yProp = (m_Momentum.y * m_Momentum.y) / sqMomentum;
//Reset such that the total does not exceed maximum velocity.
m_Momentum.x = sqrt(sqMax * xProp) * xSign;
m_Momentum.y = sqrt(sqMax * yProp) * ySign;
}
///SANITY CHECK
//Preserve old tMomentum
float tOld = tMomentum;
//Calculate current tMomentum
sqMomentum = m_Momentum.x * m_Momentum.x + m_Momentum.y * m_Momentum.y;
tMomentum = sqrt(sqMomentum);
//If it's still too high, print a report.
if (tMomentum > m_MaxVelocity)
{
std::cout << "\n\nSANITY CHECK FAILED\n";
std::cout << "-\n";
std::cout << "Old Components: " << OldMoment.x << ", " << OldMoment.y << "\n";
std::cout << "Force Components: " << Force.x << ", " << Force.y << "\n";
std::cout << "-\n";
std::cout << "New Components: " << NewMoment.x << ", " << NewMoment.y << "\n";
std::cout << "Which lead to...\n";
std::cout << "tMomentum: " << tOld << "\n";
std::cout << "-\n";
std::cout << "Found these proportions: " << xProp << ", " << yProp << "\n";
std::cout << "Using these signs: " << xSign << ", " << ySign << "\n";
std::cout << "New Components: " << m_Momentum.x << ", " << m_Momentum.y << "\n";
std::cout << "-\n";
std::cout << "Current Pos: " << m_RealPosition.x << ", " << m_RealPosition.y << "\n";
std::cout << "New Pos: " << m_RealPosition.x + m_Momentum.x << ", " << m_RealPosition.y + m_Momentum.y << "\n";
std::cout << "\n\n";
}
///APPLY FORCE
//To the object's position.
m_RealPosition.x += m_Momentum.x;
m_RealPosition.y += m_Momentum.y;
//To the sprite's position.
m_Sprite.Move(m_Momentum.x, m_Momentum.y);
Can somebody explain what's going on here?
EDIT: RedX helpfully directed me to the following post: Is there a standard sign function (signum, sgn) in C/C++? Which led me to write the following lines of code:
//Preserve signs for later use.
//int xSign = m_Momentum.x / abs(m_Momentum.x);
//int ySign = m_Momentum.y / abs(m_Momentum.y);
int xSign = (m_Momentum.x > 0) - (m_Momentum.x < 0);
int ySign = (m_Momentum.y > 0) - (m_Momentum.y < 0);
Thanks to the above, I no longer have the strange problem. For an explanation/alternative solution, see Didier's post below.
You should use fabs() instead of abs() to get the absolute value of a floating point number. If you use the integer absolute function, then the result is an integer ...
For instance, -0.5 / abs(-0.5) is treated as -0.5 / 0 which results in negative infinity (as a floating point value) that is converted to the minimum value of an int 0x80000000 = -2147483648
Taking absolute values and dividing sounds like an awful waste of cycles to me. What's wrong with
x > 0 ? 1 : -1
which you could always put in a function
template <class T>
inline int sgn(const T &x) { return x > 0 ? : 1; }