AHDL dff resets to it default value - hdl

I'm doing variable frequency clock on AHDL. Algoritm is: one counter (trigger) counts from 0 to x, and when it reaches x - we have pulse. I have another trigger which is used to store that X. Also I have two inputs plus and minus which are used to change frequency (increase or decrease X value).
And I have following code:
constant maximum = 9;
constant minimum = 1;
constant default = 5;
subdesign generator(
plus, minus, clk: input;
pulse, level[3..0], curr_val[3..0]: output;
)
variable
level[3..0]: dff;
curr_val[3..0]: dff;
begin
defaults
level[].d = default; % load 5 as default X value %
end defaults;
level[].clk = clk;
curr_val[].clk = clk;
pulse = (curr_val[] == level[]); % if main counter reached X - send one pulsation %
% main counter %
if curr_val[] < level[] then
curr_val[] = curr_val[] + 1;
elsif curr_val[] == level[] then
curr_val[] = 0;
end if;
% buttons %
if plus then
if (level[].q > minimum) then % if X == maximum ignore button %
level[].d = level[].q - 1;
end if;
end if;
if minus then
if (level[].q < maximum) then
level[].d = level[].q + 1;
end if;
end if;
end;
The problem is - after one tick when I change X (level[]) value - it goes back to default value. Am I missing something?
Syntax highlighting is wrong since wrong tag. % text % is commentary.

Found the problem.
The defaults block works everytime if value was not set. So, if you want to store same value you should set it at every time.

Related

How to calculate fall velocity of an object in Openmodelica

I'm developing a simulation of a swarm of drones in OpenModelica. The problem is that a lot of scenary can happen in the simulation, and two of the most common are
battery at 0%
collision with other objects.
In both cases, i want the drone to fall, until it reaches the floor, which in my simulation is equal to z = 0, and it won't change its position.
I don't know how to do it because my code calculate velocity with derivative functions, here is an example of how my code works:
block drone
if(battery[i] <= 0 or droneDead)
Trustx := (tmpFx/K.m);
Trusty := (tmpFy/K.m);
Trustz := (tmpFz/K.m);
else
Trustx := if(z > 5) then -(K.m * K.g) else 0;
Trusty := if(z > 5) then -(K.m * K.g) else 0;
Trustz := if(z > 5) then -(K.m * K.g) else 0;
end if;
equation
der(Vx) = Trustx;
der(Vy) = Trusty;
der(Vz) = Trustz;
der(x) = Vx;
der(y) = Vy;
der(z) = Vz;
end drone;
If this example is not explaing the question or is not good to read, i will edit it soon or i will link the .mo file

How to shift the column in a SI image

In order to perform drift correction in a SI image as shown in the following figure:
I write the code :
number max_shift=5
image src := GetFrontImage()
number sx, sy, sz
src.Get3DSize(sx, sy, sz)
result("sx: "+sx+"\n")
result("sy: "+sy+"\n")
result("sz: "+sz+"\n")
// assume a random shift in x
image shift := IntegerImage("xcorrd",4,0, 1, sy)
shift = max_shift*Random()
// make a coordinate table
image col := IntegerImage("col",4,0, sx, sy)
image row := IntegerImage("row",4,0, sx, sy)
image plane := IntegerImage("plane",4,0, sx, sy)
col = icol
row = irow
plane = iplane
// to expand the shift as the same size with source image
image ones := IntegerImage("ones",4,0, sx, sy)
ones = 1
// create a random column shift of the source SI image
for(number i=0; i<sy; i++) {
col[i,0,i+1,sx] = col[i,0,i+1,sx]+shift.GetPixel(0,i)*ones[i,0,i+1,sx]
};
// drift corrected
image im := RealImage("test si", 4, sx+max_shift, sy, sz)
im=0
im[col, row, plane] = src[icol,irow,iplane]
im.ImageGetTagGroup().TagGroupCopyTagsFrom(src.ImageGetTagGroup())
im.ImageCopyCalibrationFrom(src)
im.SetName(src.GetName()+"-drift corrected")
im.showimage()
The image can be corrected, however the spectrum cannot be transferred to the corrected SI as shown :
I am just wondering what's wrong with my script.
Thank you in advance.
im[col, row, plane] = src[icol,irow,iplane]
The intrinsic variables icol, irow, iplane will be evaluated by the only fixed size image expression in the line. In your case col, row and plane (all of same size)
However, they are all 2D so what is internally happening is that you iterate over X & Y and then write the values:
im[ col(x,y), row(x,y), plane(x,y) ] = src[x,y,0] // iterated over all x/y
As Don I was mentioning in the comments, you would want to iterate over the z dimension.
Alternatively, you could make all of your images of size (sx,sy,sz) in your script.
This would work for the expression, but is horrifically inefficient.
In general, the best solution here is to no t use icol,irow,iplane at all, but make use of the Slice commands. see this answer:
I would possibly code a line-wise x-shift for an SI like below:
The script utilizes the fact that one can shift whole "blocks" (X x 1 x Z) in x-direction, iterating over y.
number sx = 256
number sy = 256
number sz = 100
image testSI := realImage("SI",4,sx,sy,sz)
testSI = sin(itheta/(idepth-iplane)*idepth) + (iplane % (icol+1))/idepth
testSI.ShowImage()
image xdrift := RealImage("XDrift per line",4,sy)
xdrift = trunc(random()*5 + 20*sin(icol/iwidth*3*PI()))
xdrift.ShowImage()
// Apply linewise Drift to SI, assuming xDrift holds this data
xDrift -= min(xDrift) // ensure only positive shifts
image outSI := realImage("SI shifted",4,sx+max(xDrift),sy,sz)
outSI.ShowImage()
for( number y=0; y<sy; y++ ){
number yShift = sum(xDrift[y,0])
outSI.slice2( yShift,y,0, 0,sx,1, 2,sz,1 ) = testSI.slice2(0,y,0,0,sx,1,2,sz,1)
}
The script below performs the iteration "plane by plane", but does not have a restriction on the plane-wise shift.
In fact, here each pixel gets an assigned XY shift.
Note that you can use warp(source, xexpr, yexpr ) instead of 2D addressing source[ xexpr, yexpr ] if you want to use bilinear interploation of values (and 0 truncation outside the valid range).
number sx = 256
number sy = 256
number sz = 100
image testSI := realImage("SI",4,sx,sy,sz)
testSI = sin(itheta/(idepth-iplane)*idepth) + (iplane % (icol+1))/idepth
testSI.ShowImage()
image xdrift := RealImage("pixelwise XDrift",4,sx,sy)
xdrift = irow%10*random() + 20*cos(irow/iheight*5*PI())
xdrift.ShowImage()
image ydrift := RealImage("pixelwise yDrift",4,sx,sy)
ydrift = 10*abs(cos(icol/iwidth* (irow/iheight) * 10 * PI())) + irow/iheight * 10
ydrift.ShowImage()
// Apply pixelwise Drift to SI
xDrift -= min(xDrift) // ensure only positive shifts
yDrift -= min(yDrift) // ensure only positive shifts
number mx = max(xDrift)
number my = max(yDrift)
image outSI := realImage("SI shifted",4,sx+mx,sy+my,sz)
outSI.ShowImage()
for( number z=0;z<sz;z++){
image outPlane := outSI.Slice2( 0,0,z, 0,sx+mx,1,1,sy+my,1)
image srcPlane := testSI.Slice2( 0,0,z, 0,sx,1,1,sy,1)
outPlane = srcPlane[ icol + xdrift[icol,irow] - mx, irow + ydrift[icol,irow] - my ]
// outPlane = srcPlane.warp( icol + xdrift[icol,irow] - mx, irow + ydrift[icol,irow] - my)
}

Processing: conditional to test for variable change

My question pertains to the environment of Processing 2.0.
I need to write a conditional (or set of conditionals) in void draw() that tests if the variable x has increased by 1 or decreased by 1 and adjust the variable y depending on the increase/decrease in x. For example if x decreases 1, y should increase by 10, and if x increases by 1 y should decrease by 10. How would I accomplish this?
The most obvious answer is to try to think of y as a multiple of x plus maybe an offset? So if you have your x going up and down every time you enter the draw() method you should do y = x * 10; or y = 400 + x * 10 if you have an offset (int this case 400) of some sorts...
If you absolutely have to do it like that, then the way is to store the previous value of x and check each at each draw() call. So create a new variable int prevX and in your draw() method do:
y = y + (x-prevX) * 10;
or
int diff = x - prevX;
if(diff == -1) y = y - 10;
else if (diff == 1) y = y + 10;

What is the most efficient way to get a random odd or even number?

So off the top of my head, I can think of a few solutions (focusing on getting random odd numbers for example):
int n;
while (n == 0 || n % 2 == 0) {
n = (arc4random() % 100);
}
eww.. right? Not efficient at all..
int n = arc4random() % 100);
if (n % 2 == 0) n += 1;
But I don't like that it's always going to increase the number if it's not odd.. Maybe that shouldn't matter? Another approach could be to randomize that:
int n = arc4random() % 100);
if (n % 2 == 0) {
if (arc4random() % 2 == 0) {
n += 1;
else {
n -= 1;
}
}
But this feels a little bleah to me.. So I am wondering if there is a better way to do this sort of thing?
Generate a random number and then multiply it by two for even, multiply by two plus 1 for odd.
In general, you want to keep these simple or you run the risk of messing up the distribution of numbers. Take the output of the typical [0...1) random number generator and then use a function to map it to the desired range.
FWIW - It doesn't look like you're skewing the distributions above, except for the third one. Notice that getting 99 is less probable than all the others unless you do your adjustments with a modulus incl. negative numbers. Since..
P(99) = P(first roll = 99) + P(first roll = 100 & second roll = -1) + P(first roll = 98 & second roll = +1)
and P(first roll = 100) = 0
If you want a random set of binary digits followed by a fixed digit, then I'd go with bitwise operations:
odd = arc4random() | 1;
even = arc4random() & ~ 1;

Why when I print a variable outside a for loop it adds 1 to it?

int main (int argc, const char * argv[]){
#autoreleasepool {
int x = 1;
for (x = 1; x <= 10; x++) {
NSLog(#"%i",x); //the answer here is 10.
}
NSLog(#"Number %i",x); //the answer here is 11.
}
return 0;
}
So my question is, why when I print 'x' outside the for loop it adds 1 to the initial 10?
thanks in advance.
The loop ends once x is greater than 10. Therefore, it goes through the loop 10 times, adds one, which is 11 and breaks out of the loop.
It's not, the loop declaration adds it.
for (x = 1; x <= 10; x++) {
// some code
}
is like
x = 1;
while(x <= 10) {
// some code
x++;
}
When x = 11, the loop stops.
Your loop is equal to
x = 1;
while(x <= 10)
{
// log x
x++;
}
As you can see, on the last iteration (x = 10) x is incremented and only then the loop breaks.
Because "for" loop first increments the value of variable x and then compares with the condition!
It because step clause x++ is run after the last successful loop iteration. That's how it knows to stop.
x = 1, then we loop 10 times, incrementing it each time.
You get to x = 10 and your loop body runs its last time.
The step clause then runs x++ and now x = 11
Check loop condition x <= 10, which is now false and the loop exits.
If x never got to 11, you would never know when to exit this loop.
The loop iterates for 10 times from 1 to 10 and when the loops ends the value of x becomes 11.