c++ Variable values not updated correctly on GUI - c++

I am debugging some simulation software that has been written partly in C++ and partly in Ada. On the GUI, there are two values displaying the ETA & TimeToGo of an entity moving in the simulation on any given leg of its journey, and for the remainder of the whole journey. The TimeToGo & ETA values that are displayed for the current leg are correct (i.e. how long it will take the entity to reach its current target destination from its current location). However, the TimeToGo & ETA values for the remainder of the whole journey are incorrect- approximately 40-50s lagging behind.
I have come across a couple of assignments in the code, and I am wondering if they are the wrong way round:
if(some condition){
mFlightPlanData[0] = fpMiniToteData;
} else {
mFlightPlanData[1] = fpMiniToteData;
}
mFlightPlanData[] is an array of flightPlans, of size 2- because each aircraft can have up to two flight plans at any one time- a primary and a secondary. fpMiniToteData is the variable used to display the flight plan data on the GUI.
Now, it appears to me that these assignments are the wrong way round- these seem to be saying:
Set the first element in the flight plan array equal to the value of the display data
else
Set the second element in the flight plan array equal to the value of the display data
However, what should be happening is that the display data should be being set to the value of either the first or second element in the flight plan array...
I tried to do this, by switching the assignments around, i.e.
if(some condition){
fpMiniToteData = mFlightPlanData[0];
} else {
fpMiniToteData = mFlightPlanData[1];
}
But I now get a compile error that says:
error C2678: binary '=': no operator found which takes a left-hand operand of type 'const...' or there is no acceptable conversion)
What does this error mean? Do I need to have defined a function that will convert the data type held in the array to the data type of the fpMiniToteData?
Any help would be much appreciated.
Edit 12/02/2015 # 1645
fpMiniToteData is defined in the function definition- the function that the code above belongs to:
void FlightPlanInterface::setFlightPlanData(
const FlightPlanMinitoteTypes::FlightPlanPerformanceDataViewId_Type viewId,
const FlightPlanMinitoteTypes::FlightPlanMinitoteData_Variant& fpMiniToteData)
{
and mFlightPlanData is defined in a header file as follows:
private:
FlightPlanMinitoteTypes::FlightPlanMinitoteData_Variant mFlightPlanData[2];

Related

Storing timepoints or durations

I want to make a simple editor to shift subtitle times around. A Subtitle of WebVTT is made of chunks like this:
1
00:02:15.000 --> 00:02:20.000
- Hello World!
So as you can see there is a time that the subtitle will apear and a time that it dissapears. This time is also can be clicked to jump to that specific point of the video file.
Now I want to create a simple application that can shift these times by a given amount to left or right in time domain. What would be the best way to store these timepoints for making easy calculation and changes?
For example:
struct SubtitleElement {
std::chrono< ?????? > begin; // What is a good candidate here?
std::chrono< ?????? > end; // What is a good candidate here?
std::string text;
}
Later I want to have functions that operate on these elements. E.g.:
void shiftTime(SubtitleElement element, int millisecs) {
// reduce begin and end of the element by millisecs
}
DURATION getDuration(SubtitleElement& element) {
//return end - begin
}
DURATION totalDuration(vector<SubtitleElement> elements) {
// sum all the durations of the elements in vector
}
So what would the most clean and modern way of doing this? Also important is that it will be easy to convert the string "hh:mm:ss:ZZZ" to that member. Please note that I think the hh can be much more than 24, because its amount of time, not time of the day! E.g. a vido file can be 120 hours long!!
Since these are time points relative to the beginning of the video, not to some clock, I suggest keeping it simple and using std::chrono::milliseconds. They support all operations you require, except im not sure there is an existing implementation for parsing them from a string. But that should be very easy to build.

Is there a way to pass which "level" of structure is desired to a formula in (Arduino) C++?

I am not hugely experienced in C++ coding, but I learn pretty well as I go. But, I have not been able to properly query how to do this, may be using wrong terms or insufficiently expressing my desire. Here's the situation.
I have a lot of variables (3x12) that I have set up under a structure:
struct Tracking
{
String Title;
BoolArray n24hr;
bool State;
unsigned char Days, Weeks;
uint16_t Minutes, TotalMinutes, Daily, Weekly, Monthly, n7d[7], n4w[4];
} Components[3];
I also have code that performs basically the same thing 3 times but on different "levels", e.g. daily, weekly, monthly. It keeps tracks of status over those time periods, filling arrays, finding totals, and duty cycles, etc. It fills the minutes into days, and when that reaches a week, it puts the totals into a week format, and repeats until it reaches monthly levels. So basically, I have it doing something like:
in my main loop:
//calls status formula
StatusFormula();
in a separate file:
//status formula defined
void StatusFormula()
{
// for each element of Components:
//determine current status
//for daily
//add it to the correct spot in the array
//perform calculations on it
//when it reaches a week:
//add it to the correct spot in the next array
//perform calculations on it
//when it reaches a month:
//add it to the correct spot in the next array
//perform calculations on it
}
These calculations are all basically the same, the only differences are the structure member names & the constants for the calculations (i.e., MinsADay, DaysAWk, etc.).
I can get it to work this way, it just means a lot more lines and if I want to change something, I have to repeat it 3 times. What I want is something like this:
in my main loop:
//calls status formula
StatusFormula("Daily"); //sends the status formula information to decide which level (daily, weekly, monthly), it supposed to work on
if (Components[i].Minutes == MinsADay)
{
StatusFormula("Weekly"); //sends the status formula information to decide which level (daily, weekly, monthly), it supposed to work on
if (Components[i].Daily == DaysAWk)
{
StatusFormula("Monthly");
}
}
in a separate file:
//status formula defined
void StatusFormula()
{
//determine which level & variables to use (I would probably use case for this), then
//add it to the correct spot in the correct array
//perform calculations on it
}
I tried passing the level using a string, but it didn't work:
in my main loop:
StatusFormula(i, "Daily"); //sending data to formula, where i is value 0 to 2 for the Components array & defined earlier in the for loop.
in a separate file:
//formula defined as:
void StatusFormula(uint8_t counter, string level)
{Components[counter].level -= //etc... performing calculations as desired.
//so I thought this should evaluate to "Components[i].Daily -=" (& i would be a value 0 to 2) & treat it like the structure, but it doesn't work that way apparently.
I tried passing the structure & variable itself, but that didn't work either:
in my main loop:
StatusFormula(i, Components[i].Daily); //sending data to formula
in a separate file:
//formula defined as:
void StatusFormula(uint8_t counter, Tracking& level)
{level -= //etc... //(level should be Components[i].Daily -=" (& i would be a value 0 to 2)) this didn't work either.
I couldn't find any google searches to help me, and I trialed-and-errored a bunch of ways, but I couldn't figure out how to do that in C++, let alone on the Arduino platform. In Excel VBA, I would just have the variable passed as a string to the formula, which would substitute the word and then treat it like the variable that it is, but I couldn't make that happen in C++. Also to note, I am going to try and define this a separate file/tab so that my massive code file is easier to read/edit, in case that makes a difference. I would paste my code directly, but it is long and super confusing.
I guess what I am asking is how would I pass the structure and/or structure member to the formula in a way that would say the equivalent of:
case 1: //"Daily"
//use Components[i].Daily & Components[i].Minutes & MinsaDay
break;
case 2: //"Weekly"
//use Components[i].Weekly & Components[i].Days & DaysaWk
break;
//etc.
I feel like there should be a way & that I am just missing a small, vital piece. Several people in the comments suggested enums, and after researching, it might possibly be what I want, but I am having trouble visualizing it at the moment and need to do more research and examples. Any suggestions or examples on how to send the appropriate structure & members to the formula to be modified in it?

Change variable value of the already running program

I think it is impossible, but I should try.
I have a program, that is doing a physical simulation and recording frames to files. It is recording until the breakup value is not achieved, like:
int counter=0; //global variable
void SomeFunction()
{
...
if(counter == 400) //written exactly by this way, i.e. 400 is not a variable, just a number
PostQuitMessage(0);
else
MakeScreenshot();
counter++;
...
}
The problem is that I forgot to change if(counter == 400) to if(counter == 1000) and now program will be finished with 400 frames, although I need exactly 1000.
I can’t just recompile the program because calculations are very heavy and the program is already running for 2 days, I can’t wait.
It is very important for me, is there any way to change the if statement, or exactly the variable value during the program running?
The only hope I have, is, as far as I remember there was programs that could like change money/health/another stuff in games, and there user exactly could search a variable by value, and change it
Currently it is on about 200-300 frame, I have so little time to fix it.
You can use the Windows functions ReadProcessMemory and WriteProcessMemory.
But you need to determine the position of the value 400. Looking for the value in the running program can be done with the above functions. Depending on the size of the constant, it should be either a USHORT or an UINT.
So you can use the following steps:
Look for the value in a second instance
Isolate the surrounding OpCode sequence.
For example, a cmp xxx, 400
Look for this OpCode sequence in the running executable to find the unique location and replace the crucial value by 1000.
This can be called "hot-patch". It's how simple in-memory cheats do work and requires root privileges.
I downloaded Cheat engine and found address of the counter variable by its value. Through all addresses, the address I need was colored in green.
I changed the value stored at that address to 401, and now all is ok.

Sequential draw commands with glVertexAttribBinding not working as expected

I have a struct Vertex{glm::vec4 t,n,v;}. I have written a obj loader that takes two parameters, obj file path as string and reference to a vector of 'Vertex'es. This function populates my vector and returns the number of indices(In my case indices are just sequential numbers, anyway).
As I have 6 objects to render, after using that function 6 times I have the following
vector<Vertex> objects[6];
GLint SIZES[6],OFFSETS[6],SIZES_I[6],OFFSETS_I[6];
filled. SIZES are number of 'Vertex'es(object[i].size()) and SIZES_I are number of indices. The offsets are calculated as below
for(int i=0;i<6;i++)
{
if(i==0)
{
OFFSETS[0]=0;OFFSETS_I[0]=0;
}
else
{
OFFSETS[i]=OFFSETS[i-1]+SIZES[i-1];
OFFSETS_I[i]=OFFSETS_I[i-1]+SIZES_S[i-1];
}
}
I transferred vectors of Vertex into a single VBO all back to back. Similarly for indices, transferred into buffer bound to element array buffer. That part is shown below.
glBufferData(GL_ARRAY_BUFFER,(OFFSETS[5]+SIZES[5])*sizeof(Vertex),data,GL_STATIC_DRAW);
for(int i=0;i<6;i++)
{
glBindVertexBuffer(i,buffer[0],OFFSETS[i]*sizeof(Vertex),sizeof(Vertex));
}
glBufferData(GL_ELEMENT_ARRAY_BUFFER,(OFFSETS_I[5]+SIZES_I[5])*sizeof(GLuint),indices,GL_STATIC_DRAW);
glVertexAttribFormat(0,4,GL_FLOAT,GL_FALSE,offsetof(Vertex,v));
Now comes my problem. Of the two rendering codes shown below the first one doesn't work but the second works perfectly.
for(int i=0;i<6;i++)
{
glVertexAttribBinding(0,i);
glDrawElements(GL_TRIANGLES,SIZES_I[i],GL_UNSIGNED_INT,reinterpret_cast<void*>(OFFSETS_I[i]*sizeof(GLuint));
}
//second
glVertexAttribBinding(0,0);
for(int i=0;i<6;i++)
glDrawElementsBaseVertex(GL_TRIANGLES,SIZES_I[i],GL_UNSIGNED_INT,reinterpret_cast<void*>(OFFSETS_I[i]*sizeof(GLuint)),OFFSETS[i]);
To summarily say what I have done so u guys can understand whats going on here, in the first case i created 6 buffer bindings on the same buffer with 6 offsets. In the second case there is only one binding, but I used base vertex to offset 6 times. Btw both are compiling, so ignore any typos as I typed all this in my tab.
My first attempt at debugging: Since base vertex approach is working, obj loader is fine. Anyway to make sure of it, I just loaded a single model. Its working fine.
My second attempt at debugging: My suspicion naturally fell on binding calls and offsets. To resolve this, I removed the for loop in the first method and initialized i with 0(Since second method i.e. base vertex method works, we dont bother with it). My first model appeared on screen. Next I initialized 'i' variable with 1. My second model was displayed on screen. This I repeated till i=5. Each of my 6 models were displayed correctly. So my models were displayed individually. But when I combine my calls sequentially, I get some full models, some partial models and some not at all.
My third attempt at debugging: It seems that only last 2 models and so are displayed. Remaining are not drawn or partially drawn. So I reversed my for loop starting with i=5 and decrementing. Now first 2 models and so are displayed(Here 'first two' and 'last two' refers to the order in which models are loaded in obj reader. I did not change that). It is as if the subsequent drawing commands are somehow making the work of earlier drawing commands vanish. Sort of.
Thats it. Here I hit a dead end. Any ideas what might be wrong or how I might proceed with further debugging?
Turned out that it is due to a bug in my driver. The same code worked in my colleague's computer.

Recursively created linked lists with a class, C++

I'm using C++ to recursively make a hexagonal grid (using a multiply linked list style). I've got it set up to create neighboring tiles easily, but because I'm doing it recursively, I can only really create all 6 neighbors for a given tile. Obviously, this is causing duplicate tiles to be created and I'm trying to get rid of them in some way. Because I'm using a class, checking for null pointers doesn't seem to work. It's either failing to convert from my Tile class to and int, or somehow converting it but not doing it properly. I'm explicitly setting all pointers to NULL upon creation, and when I check to see if it still is, it says it's not even though I never touched it since initialization. Is there a specific way I'm supposed to do this? I can't even traverse the grid without NULLs of some kind
Here's some of my relevant code. Yes, I know it's embarassing.
Tile class header:
class Tile
{
public:
Tile(void);
Tile(char *Filename);
~Tile(void);
void show(void);
bool LoadGLTextures();
void makeDisplayList();
void BindTexture();
void setFilename(char *newName);
char Filename[100];
GLuint texture[2];
GLuint displayList;
Tile *neighbor[6];
float xPos, yPos,zPos;
};`
Tile Initialization:
Tile::Tile(void)
{
xPos=0.0f;
yPos=0.0f;
zPos=0.0f;
glEnable(GL_DEPTH_TEST);
strcpy(Filename, strcpy(Filename, "Data/BlueTile.bmp"));
if(!BuildTexture(Filename, texture[0]))
MessageBox(NULL,"Texture failed to load!","Crap!",MB_OK|MB_ICONASTERISK);
for(int x=0;x<6;x++)
{
neighbor[x]=NULL;
}
}
Creation of neighboring tiles:
void MakeNeighbors(Tile *InputTile, int stacks)
{
for(int x=0;x<6;x++)
{
InputTile->neighbor[x]=new Tile();
InputTile->neighbor[x]->xPos=0.0f;
InputTile->neighbor[x]->yPos=0.0f;
InputTile->zPos=float(stacks);
}
if(stacks)
{
for(int x=0;x<6;x++)
MakeNeighbors(InputTile->neighbor[x],stacks-1);
}
}
And finally, traversing the grid:
void TraverseGrid(Tile *inputTile)
{
Tile *temp;
for(int x=0;x<6;x++)
if(inputTile->neighbor[x])
{
temp=inputTile->neighbor[x];
temp->xPos=0.0f;
TraverseGrid(temp);
//MessageBox(NULL,"Not Null!","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
}
The key line is "if(inputTile->neighbor[x])" and whether I make it "if(inputTile->neighbor[x]==NULL)" or whatever I do, it just isn't handling it properly. Oh and I'm also aware that I haven't set up the list fully. It's only one direction now.
If you want to create a hexagonal grid you should remember that it easily can be simulated using a normal grid!
__ __ __
\__/2 \__/4 \__/6 \
/1 \__/3 \__/5 \__/
\__/8 \__/10\__/12\
/7 \__/9 \__/11\__/
\__/ \__/ \__/ \
This will make life MUCH simpler :)
Hence the easiest way would be
set up a temporary square grid m*n
fill it with tiles
traverse the grid and connect properly
Now the connections, based on the diagram above:
A) Connect to previous and next [x-1,y], [x+1,y]
B) Connect to row above and row below [x,y-1], [x,y+1]
C) Connect to row above previous and next [x-1,y-1], [x+1,y-1]
... and you have all desired connections (just remember to check bounds to decide if the tile isn't on the edge) -- if you hold the tiles in another way, you can even remove the grid :).
I'm only guessing at what MakeNeighbors() does, but instead of blindly doing InputTile->neighbor[x]=new Tile();, you could check to see if neighbor[x] is non-NULL before creating a new one and initializing it. E.g. if its parent creates it and sets all of its neighbor information, then it shouldn't go and create its parent.
When the parent creates the children, it should also define the children's other neighbors appropriately, as far as it knows them. So, it should make sure that child[i] also is neighbors with child[i-1] and child[i+1].
Creation. Recursion is a neat and elegant way to solve some problems, but it isn't perfect for every problem. I suspect that a purely recursive solution to creating the nodes would be much more complicated (i.e. less elegant) than Kornel Kisielewicz's straightforward iterative solution. That's because the Tile constructor needs to know the layout of all tiles in its immediate vicinity, in order to avoid recreating nodes that are already there.
Traversal. The main problem in your node-traversal code is similar in that you will wind up with an infinite loop and blow the stack because every node will eventually "traverse" back to its parent, beginning the cycle again. I presume you're trying to visit every tile exactly once, right? In that case TraverseGrid() needs to have a parameter telling it which direction we are entering the node from, so that we avoid traversing back that way.
But that's not enough -- you also need more discipline in deciding which directions to go. Simply spreading out in all directions except the direction we entered from will still wind up in an infinite loop and stack overflow, since any three adjacent tiles will cycle endlessly. In order to do this recursively you need to really think about which strategies will wind up visiting each node once and only once.
One possibility would be changing the signature of TraverseGrid() to TraverseGrid(Tile *inputTile, int fromDir, bool leftmost) and then using the following rules:
If we entered from above-left, traverse only to above-right, passing leftmost = false.
If we entered from below-left or above-right, traverse only to below-right, passing leftmost = false.
If leftmost, and there is a node to our lower left, then also traverse to that node, passing leftmost = true.
Of course fromDir and leftmost could be combined into a single parameter, but this gives the general idea.
Another alternative would be keeping a visited flag in each tile which is checked before traversing to that tile. Then your traversal will be a flood fill. But again, a simple iterative traversal is likely to be much simpler and easier to understand, and has the additional benefit of using constant stack space.
In the class declaration there is a second constructor Tile(char *Filename);. Maybe this constructor is used to create the main node, but doesn't initialize neighbor properly? (Its implementation isn't shown.)
And on an unrelated node, you have a duplicate strcpy() in the constructor that doesn't serves any purpose and might only lead to problems:
strcpy(Filename, strcpy(Filename, "Data/BlueTile.bmp"));
I actually did the same thing but my pattern was more like this:
00 01 02 03 04
10 11 12 13 14
20 21 22 23 24
30 31 32 33 34
This makes it pretty easy to figure out what can be reached, but forces a strange offset pattern. I just got rid of (in the above example) 00,01,10 and 20 to make it more of a hex pattern like this:
02 03 04 05 06
11 12 13 14 15
21 22 23 24 25
30 31 32 33 34
So if you look at the pattern above, reachable is always the same:
from 23 (call 2 "a" and 3 "b") you can get to:
NW(a-1, b), NE(a-1, b+1), W(a, b-1), E(a, b+1), SW(a+1, b-1), SE(a+1,b)
This pattern should hold correct for the entire grid.
EDIT:
I was going to do this in a comment but it got too long. I can see two approaches.
1) Allocate the array of nodes (null, don't allocate them). Whenever you need to allocate a node, just do so, but use the array address whenever you need to reference a node, if it's null populate it, if it has a value use that value. Huge empty arrays shouldn't take up that much memory, but if they do...
2) Create a HashSet to hold your nodes where the Hash value of the node class is calculated like this: (a << 32 || b). In this way you can instantly look up to see if a previous node existed or not. Remember to overload "equals" as well (it should return true only if the compared object is the same type and a and b are equal).
In a mostly populated system where bounds are known, 1 will save memory, but if your system is sparse (as you claim) then #2 could save a LOT of memory with no cost to efficiency.