If-Else Statement of Time in Matlab - matlab

Hi I successfully made the code in which I have the input of my computer time and date that goes like this
function [Y, M, D, H, MN, S] = fcn()
coder.extrinsic('now');
coder.extrinsic('datevec');
Y = 0;
M = 0;
D = 0;
H = 0;
MN = 0;
S = 0;
[Y, M, D, H, MN, S] = datevec(now);
end
it works perfectly fine. Then I tried to make another block for the controller that will have an output of 1 between 7AM-5PM and output 0 if not within this time and my code goes like this
function y = fcn(u)
u = datestr(7:00AM:5:00PM)
if u = datestr(7:00AM:5:00PM)
y=1;
else
y=0;
end
but an error occured. Please help me figure out what's wrong. Thank you

First of all, the first function that you've made is already built in MATLAB as clock.
Regarding your problem, there are plenty of possible approaches to the problem, but I think the easiest one would be count seconds passed from the beginning of the day.
Using clock command you would get vector of current time in format: [year month day hour minute second]. So, the time passed from the beginning of day is 3600*time(4) + 60*time(5) + time(6), i.e. 3600 times hours plus 60 times minutes and plus seconds. From 00:00:00 to 7:00:00 7*3600 seconds passed. Similarly from 00:00:00 to 17:00:00 17*3600 seconds passed. Therefore, you can just compare these values to find whether it's between 7AM and 5PM or not:
function y = IsBetween5AMand7PM
time = clock;
current = 3600*time(4) + 60*time(5) + time(6); %seconds passed from the beginning of day until now
morning = 3600*7; %seconds passed from the beginning of day until 7AM
evening = 3600*17; %seconds passed from the beginning of day until 5PM
y = current > morning && current < evening;
Hope that helps.

Related

How to increase time by 1s and replace old DT_i with the new one

I'm trying to calculate the DT value from a model I set up on Sim4Life. Firstly, i'd like to say that I am a complete beginner and I am trying to understand how programming works in general.
Now, I have a function with some constants and two variables, the one being time Dt (starting from 1 sec to 900 secs) and the other being the initial DT_i value. I want to calculate the increase of temperature for every second and create a loop that replaces the DT_i value with the DT_1_i value and also calculates the increased temperature DT_i_1. The function looks like this: DT_1_i=DT_i+Dt.
I know it is a very simple problem but I couldn't work my way through other similar questions. Any help would be appreciated.
Temperature variation:
You need initial temperature variation , I used 0
T(i+1) stands for Next temperature variation
T(i) stands for present temperature variation
i stands for time step, dt
Read through comment in my code
Time
Use for loop to set the time for i = 1 : 900 %Temperature increase end
i =1:900 just means
first run use time = 1s,
second run time = 1+1 = 2
so on till 900
The code is as follow
% Initial Temperature variation is set to zero, unless you have some data
d = 1.3;
c = 3.7;
S_i = 3*10^3;
t_reg = 900;
%Time
t = 1:900;
% Length oftime to help me know the size of the variable needed to
% initialize
l = length(t);
% Initialize variable that used to store DT it helps speed up
% comutation
% Initial Temperature variation is set to zero, unless you have some data
DT = zeros(1, l);
for i = 1:900
% the value of i represent dt, first run i = 1, dt = 1, second run
% i = 2 and dt = 2 so on
if i == 900
%do nothing already reached the last index 900, i+1 = 901 will be
%out of range
else
DT(i+1) = DT(i) + (i./t_reg).*(d.*sqrt(c*S_i)-DT(i+1));
end
end

Getting the correct output units from the PLOMB (Lomb-scargle periodogram) function

I am trying to analyze timeseries of wheel turns that were sampled at 1 minute intervals for 10 days. t is a 1 x 14000 array that goes from .1666 hours to 240 hours. analysis.timeseries.(grp).(chs) is a 1 x 14000 array for each of my groups of interest and their specific channels that specifize activity at each minute sampled. I'm interested in collecting the maximum power and the frequency it occurs at. My problem is I'm not sure what units f is coming out in. I would like to have it return in cycles per hour and span to a maximum period of 30 hours. I tried to use the Galileo example in the documentation as a guide, but it didn't seem to work.
Below is my code:
groups = {'GFF' 'GMF' 'SFF' 'SMF'};
chgroups = {chnamesGF chnamesGM chnamesSF chnamesSM};
t1 = (t * 3600); %matlab treats this as seconds so convert it to an hour form
onehour = seconds(hours(1));
for i = 1:4
grp = groups{1,i};
chn = chgroups{1,i};
for channel = 1:length(chn)
chs = chn{channel,1};
[pxx,f]= plomb(analysis.timeseries.(grp).(chs),t, 30/onehour,'normalized');
analysis.pxx.(grp).(chs) = pxx;
analysis.f.(grp).(chs) = f;
analysis.lsp.power.(grp).(chs) = max(pxx);
[row,col,v] = find(analysis.pxx.(grp).(chs) == analysis.lsp.power.(grp).(chs));
analysis.lsp.tau.(grp).(chs) = analysis.f.(grp).(chs)(row);
end
end
Not really an answer but it is hard to put a image in a comment.
Judging by this (plomb manual matlab),
I think that pxx is without dimension as for f is is the frequency so 1/(dimension of t) dimension. If your t is in hours I would say h^-1.
So I'd rather say try
[pxx,f]= plomb(analysis.timeseries.(grp).(chs),t*30.0/onehour,'normalized');

Convert milliseconds into hours and plot

I'm trying to convert an array of milliseconds and its respective data. However I want to do so in hours and minutes.
Millis = [60000 120000 180000 240000....]
Power = [ 12 14 12 13 14 ...]
I've set it up so the data records every minute, hence the 60000 millis (= 1 minimte). I am trying to plot time on the x axis and power on the y. I would like to have the x axis displayed in hours and minutes with each respective power data corresponding to its respective time.
I've tried this
for i=2:length(Millis)
Conv2Min(i) = Millis(i) / 60000;
Time(i) = startTime + Conv2Min(i);
if (Time(i-1) > Time(i) + 60)
Time(i) + 100;
end
end
s = num2str(Time);
This in attempt to turn the milliseconds into hours starting at 08:00 and once 60 minutes have past going to 09:00, the problem is plotting this. I get a gap between 08:59 and 09:00. I also cannot maintain the 0=initial 0.
In this scenario it is preferable to work with datenum values and then use datetick to set the format of the tick labels of your plot to 'HH:MM'.
Let's suppose that you started taking measurements at t_1 = [HH_1, MM_1] and stopped taking measurements at t_2 = [HH_2, MM_2].
A cool trick to generate the array of datenum values is to use the following expression:
time_datenums = HH_1/24 + MM_1/1440 : 1/1440 : HH_2/24 + MM_2/1440;
Explanation:
We are creating a regularly-spaced vector time_datenums = A:B:C using the colon (:) operator, where A is the starting datenum value, B is the increment between datenum values and C is the ending datenum value.
Since your measurements have been taken every minute (60000 milliseconds), then the increment between datenum values should be of 1 minute too. As a day has 24 hours, that makes 1440 minutes a day, so use B = 1/1440 as the increment between vector elements, to get 1 minute increments.
For A and C we simply need to divide the hour digits by 24 and the minute digits by 1440 and sum them up like this:
A = HH_1/24 + MM_1/1440
C = HH_2/24 + MM_2/1440
So for example, if t_1 = [08, 00], then A = 08/24 + 00/1440. As simple as that.
Notice that this procedure doesn't use the datenum function at all, and still, it manages to generate a valid array of datenum values only taking into consideration the time of the datenum, without needing to bother about the date of the datenum. You can learn more about this here and here.
Going back to your original problem, let's have a look at the code:
time_millisec = 0:60000:9e6; % Time array in milliseconds.
power = 10*rand(size(time_millisec)); % Random power data.
% Elapsed time in milliseconds.
elapsed_millisec = time_millisec(end) - time_millisec(1);
% Integer part of elapsed hours.
elapsed_hours_int = fix(elapsed_millisec/(1000*60*60));
% Fractional part of elapsed hours.
elapsed_hours_frac = (elapsed_millisec/(1000*60*60)) - elapsed_hours_int;
t_1 = [08, 00]; % Start time 08:00
t_2 = [t_1(1) + elapsed_hours_int, t_1(2) + elapsed_hours_frac*60]; % Compute End time.
HH_1 = t_1(1); % Hour digits of t_1
MM_1 = t_1(2); % Minute digits of t_1
HH_2 = t_2(1); % Hour digits of t_2
MM_2 = t_2(2); % Minute digits of t_2
time_datenums = HH_1/24+MM_1/1440:1/1440:HH_2/24+MM_2/1440; % Array of datenums.
plot(time_datenums, power); % Plot data.
datetick('x', 'HH:MM'); % Set 'HH:MM' datetick format for the x axis.
This is the output:
I would use datenums:
Millis = [60000 120000 180000 240000 360000];
Power = [ 12 14 12 13 14 ];
d = [2017 05 01 08 00 00]; %starting point (y,m,d,h,m,s)
d = repmat(d,[length(Millis),1]);
d(:,6)=Millis/1000; %add them as seconds
D=datenum(d); %convert to datenums
plot(D,Power) %plot
datetick('x','HH:MM') %set the x-axis to datenums with HH:MM as format
an even shorter approach would be: (thanks to codeaviator for the idea)
Millis = [60000 120000 180000 240000 360000];
Power = [ 12 14 12 13 14 ];
D = 8/24+Millis/86400000; %24h / day, 86400000ms / day
plot(D,Power) %plot
datetick('x','HH:MM') %set the x-axis to datenums with HH:MM as format
I guess, there is an easier way using datetick and datenum, but I couldn't figure it out. This should solve your problem for now:
Millis=6e4:6e4:6e6;
power=randi([5 15],1,numel(Millis));
hours=floor(Millis/(6e4*60))+8; minutes=mod(Millis,(6e4*60))/6e4; % Calculate the hours and minutes of your Millisecond vector.
plot(Millis,power)
xlabels=arrayfun(#(x,y) sprintf('%d:%d',x,y),hours,minutes,'UniformOutput',0); % Create time-strings of the format HH:MM for your XTickLabels
tickDist=10; % define how often you want your XTicks (e.g. 1 if you want the ticks every minute)
set(gca,'XTick',Millis(tickDist:tickDist:end),'XTickLabel',xlabels(tickDist:tickDist:end))

clock Time on x-axis in matlab

I need some help related to plots in MATLAB.
I want to plot my data with respect to clock time on x-axis. I have an occupancy information data for every 15 minutes interval. I want to plot it against time. How can i do it? The problem is with the x-axis, how can i handle time and uniform intervals e.g data is of the form
data=[1 0 0 0 0 1 1 1 1 0 0 0 .............]
value of time is from 9 AM to 9 PM and the interval is 15 minutes
How can i set the intervals on the x-axis?
Thank you
The following code solves the problem. you enter Integer values for starting hour and minute, the ending time and the time steps between the measurements. Further enter/change the steps_x value. This shows how many time values are skipped on the x-axis. 7=skip6 values. Below the for-loop is my y-data. I just used random-function.
The resulting x-axis is a cell-array. This could be a problem for some applications. Further I used some 'unneccessary' variables. These i used for verifing my code. I didn't change it, because i thought that it would be easier to understand that way.
The biggest problem of my so
clc; clear all; close all;
%%//Variable declaration
start_hour = 9; %in hours
start_min = 5; %//in minutes
steps_min = 10; %//in minutes
end_hour = 21.0; %//in hours
end_min= 0; %//in minutes
steps_x = 7; %//how many times are displayed on the axis, doesn't change data
%%// code for computing internal values, steps and transforming to am/pm
%//changes the entries above to hour display(9.75=9h45min)
start_time= (start_hour+start_min/60);
%//changes the entries above to hour display(9.75=9h45min)
end_time=(end_hour+end_min/60);
%//changes steps to hour
steps_hour= steps_min/60;
%//array of hours
mytest_timeline = start_time:steps_hour:end_time;
%//array of minutes(copied and modified from #natan)
mytest_minutes = mod((0:steps_min:(steps_min*(length(mytest_timeline)-1)))+start_min,60);
%//cell array for am/pm display
mytest_timeline_ampm = num2cell(mytest_timeline);
%//if hour is smaller 12 write am otherwise pm
for k=1:length(mytest_timeline);
if mytest_timeline(k) < 12
mytest_ampm = {'am'};
%//converting the down rounded hour to str
helper_hour=num2str(mod(floor(mytest_timeline(k)),12));
%//converting the minute to str and giving it 2 digits eg. 05 for 5min
helper_minute = num2str(mytest_minutes(k),'%02d');
%//joining strings
mytest_timeline_ampm(k)= strcat(helper_hour,{'.'}, helper_minute, mytest_ampm);
%//same as for am just for pm
else
mytest_ampm = {'pm'};
helper_hour=num2str(mod(floor(mytest_timeline(k)),12));
helper_minute = num2str(mytest_minutes(k),'%02d');
mytest_timeline_ampm(k)= strcat(helper_hour,{'.'}, helper_minute, mytest_ampm);
end
end
%%// generated y data so that i could test the code
mytest_y = rand(size(mytest_timeline));
%%// changing display
%//x-coordinates(for displaying x,y)
mytest_x= 1:length(mytest_timeline);
%//x-axis label
mytest_x_axis = 1:steps_x:length(mytest_timeline);
%//plots the data mytest_y in uniform distances (mytest_x)
plot(mytest_x, mytest_y, 'b')
%//changes the x-label accordingly to mytest_x_axis to the am/pm timeline
set(gca, 'XTick',mytest_x_axis, 'XTickLabel',mytest_timeline_ampm(mytest_x_axis))

Five dimensional matrix manipulation

I have made the following changes to the code but still get the "Index exceeds matrix dimensions" error on the line where the "if statement" is called and I am for looping the "h" starting from 2:25. I still have net figured out how I can use an element from the previous dimension in the current dimension equation expression
number_of_days = 3;
number_of_hours = 24*number_of_days;
number_panels = 1:5;
for idx_number_panels = 1:length(number_panels) % range of PV panel units examined
for number_turbines = 0:1 % range of wind turbine units examined
for number_batteries = 1:2 % range of battery units examined
for h=2:25 %# hours
battery_capacity(:,:,:,1,1) = max_battery_capacity*number_batteries;
for d = 1:number_of_days %# which day
n = h + 24*(d-1);
if (max_battery_capacity*number_batteries) - (battery_capacity(idx_number_panels, number_turbines+1 ,number_batteries, h-1,d)*number_batteries) >0
storage_availability(idx_number_panels, number_turbines+1 ,number_batteries, h,d) = (max_battery_capacity*number_batteries) - (battery_capacity(idx_number_panels, number_turbines+1 ,number_batteries, h-1,d)) ;
else
storage_availability(idx_number_panels, number_turbines+1 ,number_batteries, h,d) = 0;
end
Let's look at this just by hours.
for h = 1:24
battery_capacity(1) = initial_battery_capacity*number_batteries
if hourly_total_RES(h) > hourly_annual_demand(n), % battery charging
battery_capacity(h) = battery_capacity(h-1);
else
battery_capacity(h) = battery_capacity(h-1);
end
end
First off, the both sides of the if statement are the same as written. I assume that your actual code does some sort of work with the previous data. If not, that's a problem.
It also might make the code a little easier to think about if you switch the order of the day and hour loops. To me, looking through all the hours of one day at a time makes better sense than looking at the first hour of each day, then the second hour of each day...
As for the indexing, one definite error is that you index battery_capacity(h-1) on the first iteration of the loop. That is, when h is 1, you define battery_capacity(1) and then try to look at battery_capacity(0), which is probably what's throwing the error.
To fix this, you could check to see if h == 1, but I think a more elegant way would be to loop through h = 2:24 and set battery_capacity(1) before entering that loop. See if this code works:
for d = 1:number_of_days
battery_capacity(1) = initial_battery_capacity*number_batteries
for h = 2:24
if hourly_total_RES(h) > hourly_annual_demand(n), % battery charging
battery_capacity(h) = battery_capacity(h-1);
else
battery_capacity(h) = battery_capacity(h-1);
end
end
end
From what I understand, the last two dimensions store the hour and day respectively. So to set the value for first day at hour=1 (I assume this means midnight start of day):
battery_capacity(:,:,:,1,1) = 2; %# 2kWh
This will set the value 2 for all "panels" and all "turbines" and all "batteries".
I assume you have the matrix already pre-allocated somewhere in your code.
For what its worth, I think you have a typo where you first mention battery_capacity in the code (there is a missing h parameter)