C/C++ declared and defined variable turns invisible - c++

The entirety of my code is a bit too much to post on to here so I'll try to show the essentials.
I am coding a simple graphically represented analogue clock (12-hour with three hands).
Currently my code works if I let the clock run from default i.e. all hands start at 12.
However I have added a feature that allows editing of the time shown and inherent to this, regardless of starting position of the hand, when it hits 12, the larger respective hand should then tick once. My code is below.
for (psi = 0; psi<6.28318530718-0.5236; psi+=0.5235987756) {
float xply = sin(psi);
float yply = cos(psi);
int hhx = x0 + (circleRad-100)*xply;
int hhy = y0 - (circleRad-100)*yply;
float phi;
for (phi = 0; phi<6.28318530718-0.10472; phi+=0.1047197551) {
float Multx = sin(phi);
float Multy = cos(phi);
int mhx = x0 + (circleRad-50)*Multx;
int mhy = y0 - (circleRad-50)*Multy;
float theta;
for (theta= 0; theta<6.28318530718-0.104720; theta+=0.1047197551) {
// If seconds are given then the if condition is tested
if (secPhase > 0) {
float angle = theta+secPhase;
// If second hand reach top, for loop breaks and enters a new loop for next minute, secphase is erased as new minute start from 0 secs.
if (angle > 6.28318530718-0.104720) {
plotHands(angle, x0, y0, circleRad, a, mhx, mhy, hhx, hhy, bytes);
capture.replaceOverlay(true, (const unsigned char*)a);
sleep(1);
secPhase = 0;
break;
}
// if second hand has not reached top yet, then plotting continues
plotHands(angle, x0, y0, circleRad, a, mhx, mhy, hhx, hhy, bytes);
capture.replaceOverlay(true, (const unsigned char*)a);
sleep(1);
}
// if there were no seconds given, plotting begins at 12.
else {
plotHands(theta, x0, y0, circleRad, a, mhx, mhy, hhx, hhy, bytes);
capture.replaceOverlay(true, (const unsigned char*)a);
sleep(1);
}
}
}
}
Currently my code works for seconds. There are declared and defined values, that I have not included here, that I can alter that will change the starting position of each hand and wherever the second hand is, when it hits 12 the minute hand will tick once.
This is the problem. Logically, I could just apply the same concept that I used for the second hand but migrate it to the minute hand and change the respective variable names involved so that when the minute hand does strike 12, the hour hand will move. This is the code that breaks:
for (phi = 0; phi<6.28318530718-0.10472; phi+=0.1047197551) {
if (minPhase > 0) {
float minAngle = phi + minPhase;
if (minAngle > 6.28318530718-0.10472) {
minPhase = 0;
break;
}
float Multx = sin(minAngle);
float Multy = cos(minAngle);
int mhx = x0 + (circleRad-50)*Multx;
int mhy = y0 - (circleRad-50)*Multy;
}
else {
float Multx = sin(phi);
float Multy = cos(phi);
int mhx = x0 + (circleRad-50)*Multx;
int mhy = y0 - (circleRad-50)*Multy;
}
}
I have taken only the middle for loop involving the minute hand. These loops and statements ensure that if there is no given starting point of the minute hand, the else statement will run, but if there is a starting point, the starting point will tick until it strikes twelve and which point it breaks to the hour for loop, ticks once, whilst clearing the starting point of the minute hand to start afresh in the new hour.
However once I attempt to compile the code, the compiler tells me:
error: 'mhx' was not declared in this scope
error: 'mhy' was not declared in this scope
it shows this everytime this variable is called in the function to draw the minute hands and is as if these variables have simply disappeared. They have clearly been declared and defined in my code by when attempted to be called in the for loop below it, it claims that these variables are missing.
I found also that if I removed the 'else' statement, the code compiled and run, but was broken, i.e. the minute hand was not in its supposed position.
Can anyone enlighten me please? I am still very new to C and C++.
Thank you in advance.

The variables go out of scope when they hit the closing brace of either the if or the else. Declare them outside of the scope and assign their values inside the if/else blocks.
for (phi = 0; phi<6.28318530718-0.10472; phi+=0.1047197551) {
if (minPhase > 0) {
float minAngle = phi + minPhase;
if (minAngle > 6.28318530718-0.10472) {
minPhase = 0;
break;
}
float Multx = sin(minAngle);
float Multy = cos(minAngle);
int mhx = x0 + (circleRad-50)*Multx;
int mhy = y0 - (circleRad-50)*Multy;
// Multx, Multy, mhx, mhy will go out of scope when the following brace is reached
}
else {
float Multx = sin(phi);
float Multy = cos(phi);
int mhx = x0 + (circleRad-50)*Multx;
int mhy = y0 - (circleRad-50)*Multy;
// Multx, Multy, mhx, mhy will go out of scope when the following brace is reached
}
}
You should instead do this:
for (phi = 0; phi<6.28318530718-0.10472; phi+=0.1047197551) {
float Multyx, Multy;
int mhx, mhy;
// These variables will now be visible in the entire for loop's scope not just the if or else statement they were declared into.
if (minPhase > 0) {
float minAngle = phi + minPhase;
if (minAngle > 6.28318530718-0.10472) {
minPhase = 0;
break;
}
Multx = sin(minAngle);
Multy = cos(minAngle);
mhx = x0 + (circleRad-50)*Multx;
mhy = y0 - (circleRad-50)*Multy;
}
else {
Multx = sin(phi);
Multy = cos(phi);
mhx = x0 + (circleRad-50)*Multx;
mhy = y0 - (circleRad-50)*Multy;
}
}

You need to move mhx and mhy to the scope above the if statement to be visible outside the if/else.
for (phi = 0; phi<6.28318530718-0.10472; phi+=0.1047197551) {
int mhx, mhy; // move declaration here
if (minPhase > 0) {
float minAngle = phi + minPhase;
if (minAngle > 6.28318530718-0.10472) {
minPhase = 0;
break;
}
float Multx = sin(minAngle);
float Multy = cos(minAngle);
mhx = x0 + (circleRad-50)*Multx; // no longer a declaration, just assignment
mhy = y0 - (circleRad-50)*Multy;
}
else {
float Multx = sin(phi);
float Multy = cos(phi);
mhx = x0 + (circleRad-50)*Multx; // no longer a declaration, just assignment
mhy = y0 - (circleRad-50)*Multy;
}
}
I assume you have other code in the body of your for loop after this if statement that you haven't shown.

Related

R crashes when calling a Rcpp function in a loop

So I have this Rcpp function in a .cpp file. You'll see that it is calling other custom functions that I don't show for simplicity, but those don't show any problem whatsoever.
// [[Rcpp::export]]
int sim_probability(float present_wealth , int time_left, int n, float mu, float sigma, float r, float gamma, float gu, float gl){
int i;
int count = 0;
float final_wealth;
NumericVector y(time_left);
NumericVector rw(time_left);
for(i=0;i<n;i++){
rw = random_walk(time_left, 0);
y = Y(rw, mu, sigma, r, gamma);
final_wealth = y[time_left-1] - y[0] + present_wealth;
if(final_wealth <= gu && final_wealth >= gl){
count = count + 1;
}
}
return count;
}
Then I can call this function from a .R seamlessly:
library(Rcpp)
sourceCpp("functions.cpp")
sim_probability(present_wealth = 100, time_left = 10, n = 1e3, mu = 0.05, sigma = 0.20, r = 0, gamma = 2, gu = 200, gl = 90)
But, if I call it inside a for loop, no matter how small it is, R crashes without popping any apparent error. The chunk below would make R crash.
for(l in 1:1){
sim_probability(present_wealth = 100, time_left = 10, n = 1e3, mu = 0.05, sigma = 0.20, r = 0, gamma = 2, gu = 200, gl = 90)
}
I've also tried to execute it manually (Ctrl + Enter) many times as fast as I could, and I'm fast enough it also crashes.
I have tried smaller or bigger loops, both out and within the function. It also crashes if it's called from another Rcpp function. I know I shouldn't call Rcpp functions in a R loop. Eventually I intend to call it from another Rcpp function (to generate a matrix of data) but it crashes all the same.
I have followed other cases that I've found googling and tried a few things, as changing to [] brackets for the arrays' index (this question), playing with the gc() garbage collector (as suggested here).
I suspected that something happened with the NumericVector definitions. But as far as I can tell they are declared properly.
It is been fairly pointed out in the comments that this is not a reproducible exaxmple. I'll add down here the missing functions Y() and random_walk():
// [[Rcpp::export]]
NumericVector Y(NumericVector path, float mu, float sigma, float r, float gamma){
int time_step, n, i;
time_step = 1;
float theta, y0, prev, inc_W;
theta = (mu - r) / sigma;
y0 = theta / (sigma*gamma);
n = path.size();
NumericVector output(n);
for(i=0;i<n;i++){
if(i == 0){
prev = y0;
inc_W = path[0];
}else{
prev = output[i-1];
inc_W = path[i] - path[i-1];
}
output[i] = prev + (theta / gamma) * (theta * time_step + inc_W);
}
return output;
}
// [[Rcpp::export]]
NumericVector random_walk(int length, float starting_point){
if(length == 1){return starting_point;}
NumericVector output(length);
output[1] = starting_point;
int i;
for(i=0; i<length; i++){output[i+1] = output[i] + R::rnorm(0,1);}
return output;
}
Edit1: Added more code so it is reproducible.
Edit2: I was assigning local variables when calling the functions. That was dumb from my part, but harmless. The same error still persists. But I've fixed that.
Edit3: As it's been pointed out by Dirk in the comments, I was doing a pointless exercise redefining the rnorm(). Now it's removed and fixed.
The answer has been solved in the comments, by #coatless. I put it here to keep it for future readers. The thing is that the random_walk() function wasn't properly set up correctly.
The problem was that the loop inside the function allowed i to go out of the defined dimension of the vector output. This is just inefficient when called once, yet it works. But it blows up when it's called many times real fast.
So in order to avoid this error and many others, the function should have been defined as
// [[Rcpp::export]]
NumericVector random_walk(int length, float starting_point){
if(length == 0){return starting_point;}
NumericVector output(length);
output[0] = starting_point;
int i;
for(i=0; i<length-1; i++){output[i+1] = output[i] + R::rnorm(0,1);}
return output;
}

OpenACC present clause update data

I am trying to do openACC optimizations for many body simulations. Currently, I am facing a problem which lead to memory problem in below
call to cuStreamSynchronize returned error 700: Illegal address during kernel execution
call to cuMemFreeHost returned error 700: Illegal address during kernel execution
srun: error: jrc0017: task 0: Exited with exit code 1
I am using pgc++ compiler and my compiler flags are -acc -Minfo=accel -ta=tesla -fast -std=c++11 and I don't want to use -ta=tesla:managed because I want to organise memory by myself.
#pragma acc kernels present(sim.part.rx, sim.part.ry, sim.part.rz, sim.part.vx, sim.part.vy, sim.part.vz)
{
for(int idx = 0; idx < sim.num; ++idx) { // Loop over target particle
float
prx = sim.part.rx[idx], // my position
pry = sim.part.ry[idx],
prz = sim.part.rz[idx];
float Fx = 0.f, Fy = 0.f, Fz = 0.f; // Force
#pragma acc loop
for(int jdx = 0; jdx < sim.num; ++jdx) { // Loop over interaction partners
if(idx != jdx) { // No self-force
const float dx = prx - sim.part.rx[jdx]; // Distance to partner
const float dy = pry - sim.part.ry[jdx];
const float dz = prz - sim.part.rz[jdx];
const float h = 1.f/sqrt(dx*dx + dy*dy + dz*dz + eps);
const float h3 = h*h*h;
Fx += dx*h3; // Sum up force
Fy += dy*h3;
Fz += dz*h3;
}
}
sim.part.vx[idx] += sim.mass*dt*Fx; // update velocity
sim.part.vy[idx] += sim.mass*dt*Fy;
sim.part.vz[idx] += sim.mass*dt*Fz;
}
}
If I delete the code in below
sim.part.vx[idx] += sim.mass*dt*Fx; // update velocity
sim.part.vy[idx] += sim.mass*dt*Fy;
sim.part.vz[idx] += sim.mass*dt*Fz;
my code is able to run without problem. But I got memory problem if I un-comment them. It seems that sim.part.vx are try to update the data but compiler don't know which lead to the memory problem.
Does anyone know how to fix this problem?
I suspect the problem is that sim and sim.part are not on the device (or the compiler doesn't realize that they're on the device. As a workaround, can you try introducing pointers to those arrays directly?
float *rx = sim.part.rx, *ry = sim.part.ry, *rz = sim.part.rz,
*vx = sim.part.vx, *vy = sim.part.vy, *vz = sim.part.vz;
#pragma acc kernels present(rx, ry, rz, vx, vy, vz)
{
for(int idx = 0; idx < sim.num; ++idx) { // Loop over target particle
float
prx = rx[idx], // my position
pry = ry[idx],
prz = rz[idx];
float Fx = 0.f, Fy = 0.f, Fz = 0.f; // Force
#pragma acc loop
for(int jdx = 0; jdx < sim.num; ++jdx) { // Loop over interaction partners
if(idx != jdx) { // No self-force
const float dx = prx - rx[jdx]; // Distance to partner
const float dy = pry - ry[jdx];
const float dz = prz - rz[jdx];
const float h = 1.f/sqrt(dx*dx + dy*dy + dz*dz + eps);
const float h3 = h*h*h;
Fx += dx*h3; // Sum up force
Fy += dy*h3;
Fz += dz*h3;
}
}
vx[idx] += sim.mass*dt*Fx; // update velocity
vy[idx] += sim.mass*dt*Fy;
vz[idx] += sim.mass*dt*Fz;
}
}
How are sim and sim.part allocated? It's possible to use unstructured data directives in the constructor and destructor to make sure that sim and sim.part are on the device too. If you've already done this, then another possible solution is to add present(sim, sim.part) to your existing present clause so the compiler knows that you've already taken care of those data structures too.

Xbox Controller Thumb Input

I am working on moving a small rectangle around a screen using the thumbstick on the xbox controller. I have it perfect for the mouse Input but I seem to have run into a problem with the controller. The square appears on the screen at (0,0) the deadzone for the controller. When I move the thumbstick the square move a specific amount and no further, when I lift my finger off the stick it goes back to (0,0). The code is below, its pretty simple code but cant get it to work. Thanks for any help.
Here is the first part.
void Graphics::rectangle(int x, int y)
{
{
r1.x1 = x;
r1.y1 = y;
r1.x2 = r1.x1 + 50;
r1.y2 = r1.y1 + 50;
}
}
Here is the second part.
LONG x = input->getGamepadThumbRX(0);
LONG y = input->getGamepadThumbRY(0);
float x1 = x/32767;
float y1 = y/32767;
if(x1 > 0 && x1 < 0.2f || x1 < 0 && x1 > -0.2f){
x1 = 0;
}
if(y1 > 0 && y1 < 0.2f || y1 < 0 && y1 > -0.2f){
y1 = 0;
}
float factor = 10;
int dx = int(factor * x1);
int dy = int(factor * y1);
graphics->rectangle(dx,dy);
I finally got a solution to this problem. I added the variables xNew and yNew that take the values of x and y and add them on to the existing values. This allowed me to move the square around the screen. xNew and yNew are initialize at the top of the class below is the code for the input from controller and the result in rectangle.
`
void Graphics::rectangle(int x, int y)
{
xNew += x;
yNew += -y;
{
r1.x1 = xNew;
r1.y1 = yNew;
r1.x2 = r1.x1 + 50;
r1.y2 = r1.y1 + 50;
}
}
void Game::update()
{
LONG x = input->getGamepadThumbRX(0);
LONG y = input->getGamepadThumbRY(0);
float x1 = x/32767;
float y1 = y/32767;
float factor = 10;
int dx = int(factor * x1);
int dy = int(factor * y1);
graphics->rectangle(dx,dy);
}`
The problem is the mouse is a "Relative Movement" Input and the thumb-stick is a "Absolute Movement" input. What you need to do is when you are working with the thumb-sticks your final line needs to be something like
graphics->rectangle(xOld + dx, yOld + dy);
where xOld and yOld is the location of the square before you applied the function.
Might be a little late, but I do have a very easy-to-use C++ XInput wrapper. Have a look here
It literally takes a few lines of code and you have full support for XInput controllers in your app :)

Getting NAN when only dealing with integer and float

I am working on an opengl assignment where I have to make a creature (I chose a snowman) move around some terrain. I am trying to make it move around, and I am getting the strangest errors. After printing the numbers out, I frequently get "-1.#QNAN0" as a number. I don't even know what that means. Below is the snowman's update function, constructor, and the header file. I am trying to get 2 numbers to use as velocity and add them to the position while it is set to animate (randomly changing), but I don't understand what errors are causing me to not get numbers out of rand().
Each time that the probability check succeeds, it prints out:
DEBUG: probability check succeeded
-1.#QNAN0 0.000000
or
DEBUG: probability check succeeded
0.000000 0.000000
with about 50% chance of each.
From Snowman.cpp
void Snowman::update(canvas_t texture){
//randomly toggle the walking variable
int probability = rand() % 100;
//printf("DEBUG: probability = %d\n", probability);
if(probability <= 10){
printf("DEBUG: probability check succeeded\n");
walking = !walking;
dx = static_cast<float>(( (rand() % 10) - 5));
dy = static_cast<float>(( (rand() % 10) - 5));
printf("%f %f\n", dx, dy);
}
//code to control movement
if(walking){
animate = true;
x += dx;
y += dy;
constrain(x, 0, texture.width);
constrain(y, 0, texture.height);
}else{
animate = false;
}
//set the height after x and y are resolved
z = getHeight(texture);
}
Snowman::Snowman(canvas_t terrain)
{
wireFrame = false;
animate = false;
armSegments = 2;
animationFrameNumber = 0;
manualUserOffset = 0;
//set its initial position
x = rand() % terrain.width;
y = rand() % terrain.height;
dx = 0;
dy = 0;
}
From Snowman.h
class Snowman
{
public:
Snowman(canvas_t);
~Snowman(void);
void setWireframe(bool);
void toggleWireframe(void);
void setAnimate(bool);
void toggleAnimate(void);
void setArmSegments(int);
void addArmSegment(void);
void subtractArmSegment(void);
void update(canvas_t);
void draw(void);
private:
bool wireFrame;
bool animate;
bool walking;
int armSegments;
int animationFrameNumber;
float manualUserOffset;
float x, y, z;
int dx, dy;
inline float f(void);
inline void drawMouth(int headRadius);
inline void drawFace(int headRadius);
void drawArm(int remainingSegments);
inline void drawBody();
inline float getHeight(canvas_t);
};
dx and dy are ints, but your format specifier %f requires a double or a float. So you have undefined behaviour.

Why does calling a method on a pointer to an object have different behaviour from calling the method on the object itself?

I have some code where I have a pointer to an object. I call a method on that pointer but the behaviour of the method is wrong in this case. I tried calling a method on the object itself and this actually gives the desired behaviour of the method.
Why does this cause different behaviour?
Also is there a way of assigning an object to a new variable without using pointers because I want the behaviour for the method called on the object itself?
Thanks.
EDIT:
Hopefully a sufficient example:
In a Robot class:
std::vector<ProjectOne::R_ID> Robot::positions;
int Robot::ID = -1;
Robot::Robot(double x, double y)
{
++ID;
robot_ID = ID;
initialX = x;
initialY = y;
// Placeholder. Doesn't actually get used properly atm.
fWidth = 0.35;
px = x;
py = y;
ProjectOne::R_ID msg;
msg.R_ID = robot_ID;
msg.x = x;
msg.y = y;
positions.push_back(msg);
string robotOdom = "robot_" + int2str(robot_ID) + "/odom";
string robotVel = "robot_" + int2str(robot_ID) + "/cmd_vel";
RobotOdometry_sub = n.subscribe<nav_msgs::Odometry>(robotOdom,1000,&Robot::ReceiveOdometry,this);
RobotVelocity_pub = n.advertise<geometry_msgs::Twist>(robotVel,1000);
ros::spinOnce();
}
void Robot::ReceiveOdometry(nav_msgs::Odometry msg)
{
//This is the call back function to process odometry messages coming from Stage.
px = initialX + msg.pose.pose.position.x;
py = initialY + msg.pose.pose.position.y;
ptheta = angles::normalize_angle_positive(asin(msg.pose.pose.orientation.z) * 2);
}
int Robot::selectLeader()
{
int leader_ID = robot_ID;
double lowestDistance = 9999999999.9;
for (unsigned int i=0;i<positions.size();i++)
{
double distance = calculateDistance(positions[i].x, positions[i].y, 0.0, 0.0);
if (distance < lowestDistance && distance != 0.0)
{
leader_ID = positions[i].R_ID;
lowestDistance = distance;
}
}
ROS_INFO("leader is: %d", leader_ID);
return leader_ID;
}
double Robot::calculateDistance(double x1, double y1, double x2, double y2)
{
double deltax = x2 - x1;
double deltay = y2 - y1;
double distanceBetween2 = pow(deltax, 2) + pow(deltay, 2);
double distanceBetween = sqrt(distanceBetween2);
return distanceBetween;
}
double Robot::calculateHeadingChange(double x, double y)
{
double deltax = x - px;
double deltay = y - py;
double angleBetween = atan2(deltay, deltax);
double headingChange = angleBetween - ptheta;
return headingChange;
}
void Robot::align(double x, double y)
{
ros::Rate loop_rate(10);
double headingChange = calculateHeadingChange(x, y);
double angularv = headingChange / 5;
double heading = ptheta + headingChange;
while (heading > 2 * M_PI)
{
heading -= 2 * M_PI;
}
while (heading < 0)
{
heading += 2 * M_PI;
}
geometry_msgs::Twist msg;
msg.linear.x = 0;
msg.angular.z = angularv;
while (ros::ok())
{
RobotVelocity_pub.publish(msg);
ros::spinOnce();
ROS_INFO("Heading Change %f pthea is %f %f %f", headingChange, ptheta, px, py);
loop_rate.sleep();
}
}
And this is the code that calls the method:
int main(int argc, char **argv) {
ros::init(argc, argv, "robotNode");
Robot r1(5,10);
Robot r2(15,20);
Robot r3(10,30);
Robot r4(25,16);
Robot r5(5,28);
Robot r6(10,10);
Robot Group[6] = {r1, r2, r3, r4 ,r5, r6};
std::vector<Robot> Herd;
int leaderID = r1.selectLeader();
Robot * leader;
for (int i=0;i<6;i++) {
if (Group[i].robot_ID == leaderID) {
leader = &Group[i];
} else {
Herd.push_back(Group[i]);
}
}
(*leader).align(0.0, 0.0); //Problem area
}
The problem is that your array (Group) and vector (Herd) both contain copies of the automatic objects (r1 and friends); so anything you do to those will not affect the originals.
You probably want to work with pointers instead:
Robot * Group[6] = {&r1, &r2, &r3, &r4, &r5, &r6};
std::vector<Robot*> Herd;
In general, you need to be careful not to dereference these pointers after the objects are destroyed; in this case you're fine, since the lifetimes of the array and vector are contained within those of the objects.
It might make sense to make the Robot class uncopyable, to prevent this kind of mistake.
In C++11, you do this by deleting the copy constructor and copy assignment:
Robot(Robot const &) = delete;
void operator=(Robot const &) = delete;
In older language versions, declare them private, with no implementation; or (better still) derive from a base class that does that.
Here's your problem:
Robot Group[6] = {r1, r2, r3, r4 ,r5, r6};
int leaderID = r1.selectLeader();
The group contains copies of the items. You didn't show us the Robot copy constructor, but I assume it assigns a unique ID to the newly constructed Robot. If so, none of the elements in the group will have an ID equal to your leaderID, and thus your leader pointer is never set.
One solution is to make your Group an array of Robot* pointers rather than an array of Robot objects. A similar problem occurs with your Herd of robots.