Possible function that makes a value in a variable wait a specified amount of time each time a condition becomes true - anylogic

With the delay function in Anylogic, is there a way to not take the delay time from the start of the simulation, but from the point at which the delay is "triggered"?
Picture of my SystemDyamics System
My code:
complexity <= 2 ?
(stressresponse + boredom) <= 2 && wellbeing >= 0.8 ?
delay(0.3, 10)
:0
:complexity > 2 && complexity <= 5 ?
(Stressreaktion + Langeweile) <= 2 && Wohlbefinden >= 0.8 ?
delay(0.6, 4)
:0
:complexity > 5 && complexity <= 8 ?
(stressresponse + boredom) <= 2 && wellbeing >= 0.8 ?
delay(0.8, 3)
:0
:complexity > 8 && complexity <= 10 ??
(stressresponse + boredom) <= 2 && wellbeing >= 0.8 ?
delay(1, 2)
:0
:0
I want the respective value (0.3 ; 0.6 ; 0.8 or 1) to take effect only after a certain time. The problem is that the delay time in the respective function does not restart every time the previous conditions become true. I need it so that the delayTime is waited every time the conditions become true.

Related

I would like to change candle colors using the offset function with a variable/conditional offset time

Version 5.0. iff_17 determines whether my conditions are met. It then sets the candlecolor and the offset time (pasttime) which is either -4 or 0. However, it seems that pasttime is not recognized as a numerical value (also using int pasttime = iff_17 == 2 ? -4 : 0) does not work Help would be greatly appreciated. Thanks
iff_17 = va1 == 1 and ((_hh or _lh) or (_hl or _ll)) ? 2 : 0
candleColor2 = iff_17 == 2 ? candleColor1 : candleColor
pasttime = iff_17 == 2 ? -4 : 0
barcolor(candleColor2, offset = pasttime)

How do i format time into seconds in lua?

So basically I'm confused on how I'd make it so that I can convert DD:HH:MM:SS to only seconds while taking into account the amount of numbers there are. (Sorry if I make 0 sense, you should definitely know what I mean by the example below.)
print("05:00":FormatToSeconds()) -- 5 minutes and 0 seconds
-- 300
print("10:30:15":FormatToSeconds()) -- 10 hours, 30 minutes and 15 seconds
-- 37815
print("1:00:00:00":FormatToSeconds()) -- 1 day
-- 86400
print("10:00:00:30":FormatToSeconds()) -- 10 days, 30 seconds
-- 864030
So on and so forth. I think that maybe using gmatch would work but still idk. Help would be greatly appreciated.
Edit:
So I've tried doing it with gmatch, but I don't know if this is the most fastest way of doing this (which it probably isn't), so any help would still be appreciated.
(My code)
function ConvertTimeToSeconds(Time)
local Thingy = {}
local TimeInSeconds = 0
for v in string.gmatch(Time, "%d+") do
if tonumber(string.sub(v, 1, 1)) == 0 then
table.insert(Thingy, tonumber(string.sub(v, 2, 2)))
else
table.insert(Thingy, tonumber(v))
end
end
if #Thingy == 1 then
TimeInSeconds = TimeInSeconds + Thingy[1]
elseif #Thingy == 2 then
TimeInSeconds = TimeInSeconds + (Thingy[1] * 60) + Thingy[2]
elseif #Thingy == 3 then
TimeInSeconds = TimeInSeconds + (Thingy[1] * 60 * 60) + (Thingy[2] * 60) + Thingy[3]
elseif #Thingy == 4 then
TimeInSeconds = TimeInSeconds + (Thingy[1] * 24 * 60 * 60) + (Thingy[2] * 60 * 60) + (Thingy[3] * 60) + Thingy[4]
end
return TimeInSeconds
end
print(ConvertTimeToSeconds("1:00:00:00"))
Don't worry about execution speed before doing any actual measurements unless you're designing a time-critical program. In any extreme situation you'd probably want to offload risky parts to a C module.
Your approach is just fine. There are parts you can clean up: you can just return the results of calculations as TimeInSeconds doesn't actually act as accumulator in your case; tonumber handles '00' just fine and it can ensure decimal integers with an argument (since 5.3).
I'd go the other way and describe factors in a table:
local Factors = {1, 60, 60 * 60, 60 * 60 * 24}
local
function ConvertTimeToSeconds(Time)
local Components = {}
for v in string.gmatch(Time, "%d+") do
table.insert(Components, 1, tonumber(v, 10))
end
if #Components > #Factors then
error("unexpected time component")
end
local TimeInSeconds = 0
for i, v in ipairs(Components) do
TimeInSeconds = TimeInSeconds + v * Factors[i]
end
return TimeInSeconds
end
Of course, both implementations have problem with pattern being naïve as it would match e.g., '00 what 10 ever 10'. To fix that, you could go another route of using string.match with e.g., '(%d+):(%d+):(%d+):(%d+)' and enforcing strict format, or matching each possible variant.
Otherwise you can go all in and use LPeg to parse the duration.
Another way would be to not use strings internally, but instead convert them into a table like {secs=10, mins=1, hours=10, days=1} and then use these tables instead - getting seconds from that representation would be straight-forward.

Best way to find time segments in a time frame

I am currently making an app where I have to retrieve allowances for certain hours worked.
For example, I work from 3:00 pm to 10:00 pm.
Between this time an allowance would be given between 8:00 pm - 10:00 pm 20% and from 10:00 pm to 11:00 pm 35%.
Until now I did not get much further than a rather complicated if construction.
if startUur <= 20 && eindUur >= 22 || 20..<22 ~= startUur || 20..<22 ~= eindUur || startUur > 20 && eindUur <= 22 && startMinuut > 0 || startUur < 20 {
//code to calculate allowance
}
I have been looking for a good and better way to do this, but I cannot find it.
Is there a better way or am I bound to such a way with an if construction?
struct TimeAndMoneyFrame {
var timeHourStart:Int = 0
var timeHourEnd:Int = 0
var percentage: Double = 0
}
extension TimeAndMoneyFrame {
func timeLength() -> Int {
return timeHourEnd - timeHourStart
}
}
let 2000to2200 = TimeAndMoneyFrame(timeHourStart = 20, timeHourEnd = 22, percentage = 0.2)
let 2200to2300 = TimeAndMoneyFrame(timeHourStart = 22, timeHourEnd = 23, percentage = 0.35)
let timeArray:[TimeAndMoneyFrame] = [2000to2200]
//Assuming 'startUur' means startingHour
//Assuming 'eindUur' means endingHour
let startUur:Int = someHour // You define some hour
let eindUure:Int = someHour // You define some hour
let hourlyRateOfPay: Double = somePay // You define some pay
var totalPay: Double = 0
for time in timeArray {
let start = time.timeHourStart
let end = time.timeHourEnd
let percent = time.percentage
//Encompasses entirely
if(start > startUur && end < eindUur) {
totalPay += (hourlyRateOfPay * (1 + percent) * time.timeLength())
}
//Only encompassed the left side - i.e., their time worked ends within this time frame
else if(start > startUur) {
let timeWithinThisFrame = eindUur - start
totalPay += (hourlyRateOfPay * (1 + percent) * (timeWithinThisFrame/time.timeLength())
}
//Only encompassed right side - i.e., the beginning of the starts within this time frame
else if(eindUur < end) {
let timeWithinThisFrame = end - startUur
totalPay += (hourlyRateOfPay * (1 + percent) * (timeWithinThisFrame/time.timeLength())
}
}
So, we can break this problemn up into a couple problems.
1) Defining a struct/class that encompasses a time frame with an associated percentage
2) The algorithm necessary to calculate the total pay
I have a base assumption.
1) You say allowances - a person gets 35% if they work from 2200-2300 - I took this as a bonus so say 1.35% of the normal hourly rate. If this is not the case, the idea of consuming time frames one at a time would be the same. The only difference might be the totalPay calculation.
My algorithm goes through each time frame and determines if the current time intercepts any of the time frames. If it does, I calculate how much it intercepts and calculate the rate of pay.
Note: I coded all of this on SO - there might be some syntax issues.

Compare the time duration of two movies

I am going to make a function that takes starting timing of two movies: hr1,hr2,min1,min2, and their durations, durmin1,durmin2 and decides whether we can binge and watch both movies.
The criteria are that they must not overlap and that we are not going to wait more than 30 minutes between the end of one and the beginning of the next. It returns true if the criteria are both met and returns false otherwise. Movie start times are always after 1 pm and before midnight. The first one always starts earlier. The order of the input arguments is: hr1, min1, durmin1, hr2, min2, durmin2
I am unable to understand what will my function will do. What are these timing hr1,hr2? Why duration has been given?
I have tried this:
function mymovies=movies(hr1,min1,dur1,hr2,min2)
h1=hr1+min/60+dur1;
h2=hr2+min/60;
if h2-h1>=30/60 && h2-h1~=0
disp('Ture')
else
disp('False')
end
end
well, with proper variables and a little thinking just one if is sufficient to solve this problem.As far as I have understood, you definitely do not need to consider the duration for the second movie. you only need to worry about the details of the first movie and the start time of the second movie. You also need to "return" the boolean result not display it. So here is what you should do, given the instructions in your question:
First: Convert the total time from when movie one starts till it ends to minutes
Second: convert the total start time of movie two to minutes
Finally, just use the difference to meet the conditions given in the instructions in a simpe if statement. Try that with your grader then let me know what happens then. (preferably of movie2 - movie1) since you are free to assume that movie1 will always start first)
Given your level, this should suffice.
-step 1: convert hr, min to only minutes (past 1pm if you want...)
so:
start_movie_1 = hr1*60 + min1
end_movie_1 = start_movie_1 + durmin1
Similar for movie 2.
-step 2: find if they overlap.
if start_movie_1 < start_movie_2 and end_movie_1 > end_movie_2 => there is overlapping (whole movie 2 is inside movie 1)
if start_movie_1 < start_movie_2 and end_movie_1 > start_movie_2 => there is overlapping (movie 2 will start before movie 1 finish)
if start_movie_2 < start_movie_1 and end_movie_2 > end_movie_1 => there is overlapping (whole movie 1 is inside movie 2)
if start_movie_2 < start_movie_1 and end_movie_2 > start_movie_1 => there is overlapping (movie 1 will start before movie 2 finish)
-step 3: now we know they don't overlap, so we need to check the time inbetween
if start_movie_1 < start_movie_2 => return (start_movie_2 - end_movie_1) <= 30
else (start_movie_2 < start_movie_1)
return (start_movie_1 - end_movie_2) <= 30
Edited for an even more simple answer
function mymovies=movies(hr1,min1,dur1,hr2,min2,dur2)
start_movie_1 = hr1*60 + min1;
end_movie_1 = start_movie_1 + dur1;
start_movie_2 = hr2*60 + min2;
end_movie_2 = start_movie_2 + dur2;
if start_movie_1 < start_movie_2 && end_movie_1 > end_movie_2
disp('FALSE');
else if start_movie_1 < start_movie_2 && end_movie_1 > start_movie_2
disp('FALSE');
else if start_movie_2 < start_movie_1 && end_movie_2 > end_movie_1
disp('FALSE');
else if start_movie_2 < start_movie_1 && end_movie_2 > start_movie_1
disp('FALSE');
else
if start_movie_1 < start_movie_2 && (start_movie_2 - end_movie_1) <= 30
disp('TRUE');
else if (start_movie_2 < start_movie_1) && (start_movie_1 - end_movie_2) <= 30
disp('TRUE');
else
disp('FALSE');
end
end
end

VHDL Saving input value into another signal

I have a question for my VHDL code. My entire code has to do the following:
input = Minutes + hours + clk
output = AFTER 1 minute: minuten = minuten + 1 (and if needed hours += 1)
So I built a counter, which counts (well for simulation easyness to 1/10th of a second instead of a minute) clock periods untill one minute is over. Then it raises the minute by 1, and send that to the output. I got one problem however: due to setup violation I can't simulate the synthesis well. I thought this violation was in the line: min_save = minutes. I think that it's impossible to save the input minutes immediately, so I thought: let's build another counter, which counts 1 clock period, and then saves it.
So my 2 questions:
Does this indeed solve the setup violation?
If so: why does the signal setup have no value. It has a value of undefined. What do i do wrong?
If not: why not, and how can I solve this then?
CODE:
architecture behaviour of internclk_u is
begin
process (minuten)
begin -- switching input minutes to binary.
minintern(6) <= minuten(0);
minintern(5) <= minuten(1);
minintern(4) <= minuten(2);
minintern(3) <= minuten(3);
minintern(2) <= minuten(4);
minintern(1) <= minuten(5);
minintern(0) <= minuten(6);
end process;
process (uren)
begin -- switching input hours to binary
uurintern(5) <= uren(0);
uurintern(4) <= uren(1);
uurintern(3) <= uren(2);
uurintern(2) <= uren(3);
uurintern(1) <= uren(4);
uurintern(0) <= uren(5);
end process;
process (clk)
begin
setup <= '0';
if(clk'event and clk = '1') then
if(setup < '1') then
setup <= '1';
else
setup <= setup;
if(min_save = minutes) then
count <= new_count;
else
min_save <= minutes;
count <= (others => '0');
end if;
end if;
end if;
end process;
process (count, minintern)
begin -- count one minute (now its 0.1 second)
if(count < F/10 ) then
new_count <= count + 1;
intern_out <= minintern;
uurintern_out <= uurintern;
else
case minintern is -- Calculate new value for output
when "0001001" => intern_out <= "0010000";
uurintern_out <= uurintern;
when "0011001" => intern_out <= "0100000";
uurintern_out <= uurintern;
when "0101001" => intern_out <= "0110000";
uurintern_out <= uurintern;
when "0111001" => intern_out <= "1000000";
uurintern_out <= uurintern;
when "1001001" => intern_out <= "1010000";
uurintern_out <= uurintern;
when "1011001" => intern_out <= "0000000";
case uurintern is
when "001001" => uurintern_out <= "010000";
when "011001" => uurintern_out <= "100000";
when others => uurintern_out <= uurintern + 1;
end case;
when others => intern_out <= minintern + 1;
uurintern_out <= uurintern;
end case;
new_count <= count;
setup <= '0';
end if;
end process;
process (intern_out) -- Reversing signals for next blocks in system
begin
interne_tijd_m(6) <= intern_out(0);
interne_tijd_m(5) <= intern_out(1);
interne_tijd_m(4) <= intern_out(2);
interne_tijd_m(3) <= intern_out(3);
interne_tijd_m(2) <= intern_out(4);
interne_tijd_m(1) <= intern_out(5);
interne_tijd_m(0) <= intern_out(6);
end process;
process (uurintern_out)
begin -- Reversing signals for next blocks in system
interne_tijd_u(5) <= uurintern_out(0);
interne_tijd_u(4) <= uurintern_out(1);
interne_tijd_u(3) <= uurintern_out(2);
interne_tijd_u(2) <= uurintern_out(3);
interne_tijd_u(1) <= uurintern_out(4);
interne_tijd_u(0) <= uurintern_out(5);
end process;
end behaviour;
Remarks:
ignore the 2 case statements; this is because the inputsignals are not binary coded; they are reversed. Besides that: it doesnt count 1,2,4,8,16 etc; it counts: 1,2,4,8,10,20 etc.
EDIT
I put in the whole architecture now.
The error message I received was something like: "Setup time violations occured(?)". So I believe I cant save the input minutes immediately when I receive minutes. Thats why I tried to program in the setup signal. Hope you guys can help. This error gave me a headache and lots of frustration already:(
EDIT 2
Forget about the whole "setup" signal. A student-assistent pointed out to me that the saving of the input doesnt make any sense. So my updated question is: How can I properly save the input signal/value into another signal?
Your code is really a mess, and it's very difficult to debug... :-(
I think that the problem is due to the fact that you have a multiple definition of the signal setup. Moreover the first time is defined inside a clocked process (even if the setup <= '0' is outside the if statement). The second time is defined inside another process that is not clocked. I think that the synthesis tool doesn't know how to proceed exactly. In the simulation of the RTL code you should normally see some glitches on the setup signal. I also think that the type of setup is set_logic. Try to change it to std_ulogic. The simulation tool will not compile your code since this type is unresolved. Fix the code and then go back to std_logic.
Another thing: you wrote if setup < '1' then: this sounds very strange to me (I didn't know that it was accepted). I prefer to write if setup /= '1' then: it is much more easier to read this kind of code...