CODE GENRATION
The class Automatic Code Generation (ACG) creates a ready-to-use setup networked control system simulation by generating a Simulink model based on TrueTime blocks and corresponding configuration m-files. The Network model is specified by the number of actuators and sensors, while controller and plant should be customized by the user fulfilling the respective subsystem.
Contents
Class description
TrueTime is a very powerful tool which can handle simulation of a variety of tasks, with a particular focus on real-time implementation of controller and sensors/actuators codes. As a result of this plenty of possibilities offered, the user needs to set-up a lot of features, some of which might be out of scope for some needings.
This class permits to generate automatically all the configuration m-files needed to run a standard networked-control simulation. The user is asked to simply set the number of sensors and actuators that are desired to be in the network and a name for the Simulink model to be generated.
Then the code generation creates a Simulink model that contain two submodels, Plant and Controller, that can be customized by the user according to personal needing.
classdef ACG properties (Access=private) Ns %number of sensors Na %number of actuators name %destination file name end methods (Access = public)
Class costructor
USAGE
acg_obj=ACG(Ns,Na,name)
- Ns = number of sensors in the network (Optional: default value=1);
- Na = number of actuators in the network (Optional: default value=1);
- name = name of the simulink model file (Optional: default value='acg_default');
function acg = ACG(varargin) acg.Ns=1; acg.Na=1; acg.name='acg_default'; if(nargin>0) acg.Ns=varargin{1}; end if(nargin>1) acg.Na=varargin{2}; end if(nargin>2) acg.name=varargin{3}; end end
ans = ACG with no properties.
Code Generation Method
Generated the files required for performing a standard network-aware simulation using TrueTime
function GenerateCode(acg)
simulink; Ns=acg.Ns; Na=acg.Na; name=acg.name; % % Sensors Code offset=0; for i=1:Ns
ciR = num2str(2*i); ciS = num2str(2*i-1);
SensorsR init
str=['function SensorR' ciR '_init\n\n']; str=[str 'ttInitKernel(1, 1, ''prioFP'');\n']; str=[str 'ttSetKernelParameter(''energyconsumption'', 0.01'... '00);\n\n']; str=[str 'ttCreateMailbox(''Sens_signal' ciS ''', 10)\n\n']; str=[str 'data.y = 0;\noffset = ' num2str(offset) ';\nper'... 'iod = 0.010;\nprio = 1;']; str=[str 'ttCreatePeriodicTask(''SensR_task' ciR ''', of'... 'fset, period, prio, ''SensR' ciR ''', data);\n']; str=[str 'ttCreateInterruptHandler(''nw_handler'', prio,'... '''msgRcvActR' ciR ''');\n']; str=[str 'ttInitNetwork(' ciR ', ''nw_handler'');\n']; fid=fopen(['SensorR' ciR '_init.m'],'w'); fprintf(fid,str); fclose(fid);
%SensorsS init str=['function SensorS' ciS '_init\n\n']; str=[str 'ttInitKernel(1, 1, ''prioFP'');\n']; str=[str 'ttSetKernelParameter(''energyconsumption'', 0.'... '0100);\n\n']; str=[str 'ttCreateMailbox(''Sens_signal' ciS ''', 10)\n\n']; str=[str 'data.y = 0;\noffset = ' num2str(offset) ';\nper'... 'iod = 0.010;\nprio = 1;\n']; str=[str 'ttCreatePeriodicTask(''SensS_task' ciS ''', off'... 'set, period, prio, ''SensS' ciS ''', data);\n']; str=[str 'ttCreateInterruptHandler(''nw_handler'', prio'... ', ''msgRcvActR' ciR ''');\n']; str=[str 'ttInitNetwork(' ciS ', ''nw_handler'');\n']; fid=fopen(['SensorS' ciS '_init.m'],'w'); fprintf(fid,str); fclose(fid);
SensS
str=['function [exectime, data] = SensS' ciS '(seg, data)\n\n']; str=[str 'switch seg,\n case 1,\n data.msg.msg '... '= ttAnalogIn(1);\n']; str=[str ' exectime = 0.0005;\n case 2,\n '... 'data.msg.type = ''Sens_signal' ciS ''';\n']; str=[str ' ttSendMsg(' ciR ', data.msg, 80);\n '... 'exectime = 0.0004;\n']; str=[str ' case 3,\n exectime = -1;\nend\nend\n']; fid=fopen(['SensS' ciS '.m'],'w'); fprintf(fid,str); fclose(fid);
SensR
str=['function [exectime, data] = SensR' ciR '(seg, data)\n\n']; str=[str 'switch seg,\n case 1,\n temp = ttTry'... 'Fetch(''Sens_signal' ciS ''');\n']; str=[str ' while ~isempty(temp),\n dat'... 'a.y = temp;\n']; str=[str ' temp = ttTryFetch(''Sens_signal' ... ciS ''');\n end\n']; str=[str ' exectime = 0.0005;\n case 2,\n '... 'ttAnalogOut(1, data.y)\n']; str=[str ' exectime = -1;\nend\n']; fid=fopen(['SensR' ciR '.m'],'w'); fprintf(fid,str); fclose(fid);
msgRcvActR
str=['function [exectime, data] = msgRcvActR' ciR '(se'... 'g, data)\n\n']; str=[str 'temp = ttGetMsg;\nif ~isempty(temp)\n ttTry'... 'Post(temp.type, temp.msg);\n']; str=[str ' if strcmp(''Sens_signal' ciS ''', temp.type)\n']; str=[str 'ttCreateJob(''SensR_task' ciR ''');\n '... 'end\nend\nexectime = -1;\n']; fid=fopen(['msgRcvActR' ciR '.m'],'w'); fprintf(fid,str); fclose(fid);
end
Actuator Code
baseOff = offset+0.001;
for i=1:Na
ciR = num2str(2*Ns+2*i); ciS = num2str(2*Ns+2*i-1); str=['function ActR' ciR '_init\n\n']; str=[str 'ttInitKernel(1, 1, ''prioFP'');\n']; str=[str 'ttSetKernelParameter(''energyconsumption'', 0.'... '0100);\n\n']; str=[str 'ttCreateMailbox(''Act_signal' ciS ''', 10)\n\n']; str=[str 'data.y = 0;\noffset = ' num2str(offset) ';\np'... 'eriod = 0.010;\nprio = 1;\n']; str=[str 'ttCreatePeriodicTask(''ActR_task' ciR ''', of'... 'fset, period, prio, ''ActR' ciR ''', data);\n']; str=[str 'ttCreateInterruptHandler(''nw_handler'', pri'... 'o, ''msgRcvActR' ciR ''');\n']; str=[str 'ttInitNetwork(' ciR ', ''nw_handler'');\n']; fid=fopen(['ActR' ciR '_init.m'],'w'); fprintf(fid,str); fclose(fid);
ActS init
str=['function ActS' ciS '_init\n\n']; str=[str 'ttInitKernel(1, 1, ''prioFP'');\n']; str=[str 'ttSetKernelParameter(''energyconsumption'', 0'... '.0100);\n\n']; str=[str 'ttCreateMailbox(''Act_signal' ciS ''', 10)\n\n']; str=[str 'data.y = 0;\noffset = ' num2str(offset) ';\n'... 'period = 0.010;\nprio = 1;\n']; str=[str 'ttCreatePeriodicTask(''ActS_task' ciS ''', of'... 'fset, period, prio, ''ActS' ciS ''', data);\n']; str=[str 'ttCreateInterruptHandler(''nw_handler'', prio'... ', ''msgRcvActR' ciR ''');\n']; str=[str 'ttInitNetwork(' ciS ', ''nw_handler'');\n']; fid=fopen(['ActS' ciS '_init.m'],'w'); fprintf(fid,str); fclose(fid);
ActS
str=['function [exectime, data] = ActS' ciS '(seg, data)\n\n']; str=[str 'switch seg,\n case 1,\n data.msg.msg'... '= ttAnalogIn(1);\n']; str=[str ' exectime = 0.0005;\n case 2,\n '... 'data.msg.type = ''Act_signal' ciS ''';\n']; str=[str ' ttSendMsg(' ciR ', data.msg, 80);\n '... 'exectime = 0.0004;\n']; str=[str ' case 3,\n exectime = -1;\nend\nend\n']; fid=fopen(['ActS' ciS '.m'],'w'); fprintf(fid,str); fclose(fid);
ActR
str=['function [exectime, data] = ActR' ciR '(seg, data)\n\n']; str=[str 'switch seg,\n case 1,\n temp = tt'... 'TryFetch(''Act_signal' ciS ''');\n']; str=[str ' while ~isempty(temp),\n '... 'data.y = temp;\n']; str=[str ' temp = ttTryFetch(''Act_signal' ciS... ''');\n end\n']; str=[str ' exectime = 0.0005;\n case 2,\n '... 'ttAnalogOut(1, data.y)\n']; str=[str ' exectime = -1;\nend\n']; fid=fopen(['ActR' ciR '.m'],'w'); fprintf(fid,str); fclose(fid);
msgRcvActR
str=['function [exectime, data] = msgRcvActR' ciR '(seg,'... 'data)\n\n']; str=[str 'temp = ttGetMsg;\nif ~isempty(temp)\n ttTry'... 'Post(temp.type, temp.msg);\n']; str=[str ' if strcmp(''Act_signal' ciS ''', temp.type)\n']; str=[str 'ttCreateJob(''ActR_task' ciR ''');\n end'... '\nend\nexectime = -1;\n']; fid=fopen(['msgRcvActR' ciR '.m'],'w'); fprintf(fid,str); fclose(fid);
end
Configure the new system
close_system(name,0); open_system('baseWNet'); save_system('baseWNet',name); close_system('baseWNet',0);
Mux
set_param([name '/Mux1'],'inputs',num2str(Ns));
Controller plant, Wireless
set_param([name '/Controller'],'Position',[215 150 315 ... 200+max(Ns,Na)*30] ); set_param([name '/Plant'],'Position',[690 150 790 ... 200+max(Ns,Na)*30] ); set_param([name '/Wireless Network'],'Position',[1185 150 ... 1245 200+(Ns+Na)*30] ); set_param([name '/Wireless Network/TrueTime Wireless '... 'Network'],'nnodes',num2str(2*(Na+Ns)) ); set_param([name '/Wireless Network/Mux'],'Position',[120 16 ... 125 30+(Ns+Na)*30] ); set_param([name '/Wireless Network/Demux'],'Position',[390 16 ... 395 30+(Ns+Na)*30] );
Add sensors blocks
for i=2:Ns %1 sensor is already present
Receiver
ciS=num2str(2*i-1); ciR=num2str(2*i); add_block('simulink/Signal Routing/From',[name '/From' ciR]); set_param([name '/From' ciR],'Position',[40 200+30*(i-1) ... 40+50 200+30*(i-1)+10 ]); set_param([name '/From' ciR],'GotoTag',['Srcv' ciR]); add_block([name '/Sensor Receiver2'],[name '/Sensor Rec'... 'eiver' ciR]); set_param([name '/Sensor Receiver' ciR],'Position',[120 ... 200+30*(i-1) 180 210+30*(i-1)]); set_param([name '/Sensor Receiver' ciR '/TrueTime Kernel'... ],'sfun',['SensorR' ciR '_init']);
Sender
add_block('simulink/Signal Routing/Goto',[name '/Goto' ciS]); set_param([name '/Goto' ciS],'Position',[940 200+30*(i-1)... 990 210+30*(i-1)]); set_param([name '/Goto' ciS],'GotoTag',['Ssnd' ciS]); add_block([name '/Sensor Sender1'],[name '/Sensor Sender'... ciS]); set_param([name '/Sensor Sender' ciS],'Position',[840 ... 200+30*(i-1) 920 210+30*(i-1)]); set_param([name '/Sensor Sender' ciS '/TrueTime Kernel'],... 'sfun',['SensorS' ciS '_init']);
External Wireless
add_block('simulink/Signal Routing/Goto',[name '/Goto' ciR]); set_param([name '/Goto' ciR],'Position',[1280 200+30*(i-1)... 1280+50 200+30*(i-1)+10 ]); set_param([name '/Goto' ciR],'GotoTag',['Srcv' ciR]); add_block('simulink/Signal Routing/From',[name '/From' ciS]); set_param([name '/From' ciS],'Position',[1110 200+30*(i-1)... 1110+50 200+30*(i-1)+10 ]); set_param([name '/From' ciS],'GotoTag',['Ssnd' ciS]);
Internal Wireless
add_block('simulink/Sources/In1',[name '/Wireless Network'... '/snd' ciS]); set_param([name '/Wireless Network/snd' ciS],'Port',... num2str(i)); set_param([name '/Wireless Network/snd' ciS],'Position',... [30 60*(i-1)+23 60 60*(i-1)+37]); add_block('simulink/Sources/Ground',[name '/Wireless Net'... 'work/Ground' ciR]); set_param([name '/Wireless Network/Ground' ciR],'Position',... [30 60*(i-1)+53 60 60*(i-1)+67]); add_block('simulink/Sinks/Out1',[name '/Wireless Network'... '/rcv' ciR]); set_param([name '/Wireless Network/rcv' ciR],'Port',... num2str(i)); set_param([name '/Wireless Network/rcv' ciR],'Position',... [450 60*(i-1)+23 480 60*(i-1)+37]); add_block('simulink/Sinks/Terminator',[name '/Wireless '... 'Network/Terminator' ciS]); set_param([name '/Wireless Network/Terminator' ciS],... 'Position',[450 60*(i-1)+53 480 60*(i-1)+67]);
Controller and Plant
add_block('simulink/Sources/In1',[name '/Controller/Sensor'... ciS]); set_param([name '/Controller/Sensor' ciS],'Position',[110 ... 103+30*(i-1) 140 117+30*(i-1)]); add_block('simulink/Sinks/Out1',[name '/Plant/Sensor' ciS]); set_param([name '/Plant/Sensor' ciS],'Position',[410 ... 103+30*(i-1) 440 117+30*(i-1)]);
end
Rename actuator X1 with real number
ciS=num2str(2*Ns+1); ciR=num2str(2*Ns+2); set_param([name '/FromX2'],'Name',['From' ciR]); set_param([name '/From' ciR],'GotoTag',['Rrcv' ciR]); set_param([name '/Actuator ReceiverX2'],'Name',['Actuator '... 'Receiver' ciR]); set_param([name '/Actuator Receiver' ciR '/TrueTime Kernel'],... 'sfun',['ActR' ciR '_init']);
Sender
set_param([name '/GotoX1'],'Name',['Goto' ciS]); set_param([name '/Goto' ciS],'GotoTag',['Rsnd' ciS]); set_param([name '/Actuator SenderX1'],'Name',['Actuator Sender'... ciS]); set_param([name '/Actuator Sender' ciS '/TrueTime Kernel'],... 'sfun',['ActS' ciS '_init']);
External Wireless
set_param([name '/GotoX2'],'Name',['Goto' ciR]); set_param([name '/Goto' ciR],'Position',[1280 200+30*(Ns) ... 1280+50 200+30*(Ns)+10 ]); set_param([name '/Goto' ciR],'GotoTag',['Rrcv' ciR]); set_param([name '/FromX1'],'Name',['From' ciS]); set_param([name '/From' ciS],'Position',[1110 200+30*(Ns) ... 1110+50 200+30*(Ns)+10 ]); set_param([name '/From' ciS],'GotoTag',['Rsnd' ciS]);
Internal Wireless
set_param([name '/Wireless Network/sndX1'],'Name',['snd' ciS]); set_param([name '/Wireless Network/snd' ciS],'Port',... num2str(Ns+1)); set_param([name '/Wireless Network/snd' ciS],'Position',[30 ... 60*(Ns)+23 60 60*(Ns)+37]); set_param([name '/Wireless Network/GroundX1'],'Name',[... 'Ground' ciR]); set_param([name '/Wireless Network/Ground' ciR],'Position',[... 30 60*(Ns)+53 60 60*(Ns)+67]); set_param([name '/Wireless Network/rcvX1'],'Name',['rcv' ciR]); set_param([name '/Wireless Network/rcv' ciR],'Port',... num2str(Ns+2)); set_param([name '/Wireless Network/rcv' ciR],'Position',... [450 60*(Ns)+23 480 60*(Ns)+37]); set_param([name '/Wireless Network/TerminatorX1'],'Name',... ['Terminator' ciS]); set_param([name '/Wireless Network/Terminator' ciS],... 'Position',[450 60*(Ns)+53 480 60*(Ns)+67]);
Controller & plant
set_param([name '/Controller/ActuatorX1'],'Name',['Actuator'... ciS]); set_param([name '/Controller/Actuator' ciS],'Position',[410 ... 103 440 117]); set_param([name '/Plant/ActuatorX1'],'Name',['Actuator' ciS]); set_param([name '/Plant/Actuator' ciS],'Position',[110 103 ... 140 117]);
Actuators
for i=2:Na %1 actuator is already present
Receiver
ciS=num2str(2*Ns+2*i-1); ciR=num2str(2*Ns+2*i); add_block('simulink/Signal Routing/From',[name '/From' ... ciR]); set_param([name '/From' ciR],'Position',[520 200+30*(i-1)... 520+50 200+30*(i-1)+10 ]); set_param([name '/From' ciR],'GotoTag',['Arcv' ciR]); add_block([name '/Actuator Receiver' num2str(2*Ns+2)],... [name '/Actuator Receiver' ciR]); set_param([name '/Actuator Receiver' ciR],'Position',[600 ... 200+30*(i-1) 660 210+30*(i-1)]); set_param([name '/Actuator Receiver' ciR ... '/TrueTime Kernel'],'sfun',['ActR' ciR '_init']);
Sender
add_block('simulink/Signal Routing/Goto',[name '/Goto' ciS]); set_param([name '/Goto' ciS],'Position',[440 200+30*(i-1)... 480 210+30*(i-1)]); set_param([name '/Goto' ciS],'GotoTag',['Asnd' ciS]); add_block([name '/Actuator Sender' num2str(2*Ns+1)],[name... '/Actuator Sender' ciS]); set_param([name '/Actuator Sender' ciS],'Position',[350 ... 200+30*(i-1) 410 210+30*(i-1)]); set_param([name '/Actuator Sender' ciS '/TrueTime Kernel'... ],'sfun',['ActS' ciS '_init']);
External Wireless
add_block('simulink/Signal Routing/Goto',[name '/Goto' ciR]); set_param([name '/Goto' ciR],'Position',[1280 ... 200+30*(Ns+i-1) 1280+50 200+30*(Ns+i-1)+10 ]); set_param([name '/Goto' ciR],'GotoTag',['Arcv' ciR]); add_block('simulink/Signal Routing/From',[name '/From'... ciS]); set_param([name '/From' ciS],'Position',[1110 ... 200+30*(Ns+i-1) 1110+50 200+30*(Ns+i-1)+10 ]); set_param([name '/From' ciS],'GotoTag',['Asnd' ciS]);
Internal Wireless
add_block('simulink/Sources/In1',[name ... '/Wireless Network/snd' ciS]); set_param([name '/Wireless Network/snd' ciS],'Port',... num2str(i+Ns)); set_param([name '/Wireless Network/snd' ciS],'Position',... [30 60*(Ns+i-1)+23 60 60*(Ns+i-1)+37]); add_block('simulink/Sources/Ground',[name ... '/Wireless Network/Ground' ciR]); set_param([name '/Wireless Network/Ground' ciR],... 'Position',[30 60*(Ns+i-1)+53 60 60*(Ns+i-1)+67]); add_block('simulink/Sinks/Out1',[name ... '/Wireless Network/rcv' ciR]); set_param([name '/Wireless Network/rcv' ciR],'Port',... num2str(i+Ns)); set_param([name '/Wireless Network/rcv' ciR],'Position',... [450 60*(Ns+i-1)+23 480 60*(Ns+i-1)+37]); add_block('simulink/Sinks/Terminator',[name ... '/Wireless Network/Terminator' ciS]); set_param([name '/Wireless Network/Terminator' ciS],... 'Position',[450 60*(Ns+i-1)+53 480 60*(Ns+i-1)+67]);
Controller and Plant
add_block('simulink/Sources/In1',[name '/Plant/Actuator' ciS]); set_param([name '/Plant/Actuator' ciS],'Position',[110 ... 103+30*(i-1) 140 117+30*(i-1)]); add_block('simulink/Sinks/Out1',[name ... '/Controller/Actuator' ciS]); set_param([name '/Controller/Actuator' ciS],'Position',... [410 103+30*(i-1) 440 117+30*(i-1)]);
end set_param([name '/Wireless Network/Mux'],'inputs',... num2str(2*Ns+2*Na)); set_param([name '/Wireless Network/Demux'],'outputs',... num2str(2*Ns+2*Na));
Connected previously added blocks
for i=2:Ns ciS=num2str(2*i-1); ciR=num2str(2*i); ciSn=num2str(2*i-1+Ns*2); ciRn=num2str(2*i+Ns*2); add_line(name,['From' ciR '/1'],['Sensor Receiver' ciR '/1']); add_line(name,['Sensor Receiver' ciR '/1'],['Controller/'... num2str(1+i)]); add_line(name,['Plant/' num2str(i)],['Sensor Sender' ciS '/1']); add_line(name,['Sensor Sender' ciS '/1'],['Goto' ciS '/1']); add_line(name,['Plant/' num2str(i)],['Mux1/' num2str(i)]); add_line(name,['From' ciS '/1'],['Wireless Network/'... num2str(i)]); add_line(name,['Wireless Network/' num2str(i)],['Goto'... ciR '/1']); add_line([name '/Wireless Network'],['snd' ciS '/1'],... ['Mux/' ciS]); add_line([name '/Wireless Network'],['Demux/' ciR],... ['rcv' ciR '/1']); add_line([name '/Wireless Network'],['Ground' ciR '/1'],... ['Mux/' ciR]); add_line([name '/Wireless Network'],['Demux/' ciS],... ['Terminator' ciS '/1']); end for i=2:Na ciS=num2str(2*i-1); ciR=num2str(2*i); ciSn=num2str(2*i-1+Ns*2); ciRn=num2str(2*i+Ns*2); add_line(name,['From' ciRn '/1'],['Actuator Receiver'... ciRn '/1']); add_line(name,['Actuator Receiver' ciRn '/1'],['Plant/'... num2str(i)]); add_line(name,['Controller/' num2str(i)],[... 'Actuator Sender' ciSn '/1']); add_line(name,['Actuator Sender' ciSn '/1'],[... 'Goto' ciSn '/1']); add_line(name,['From' ciSn '/1'],['Wireless Network/' ... num2str(Ns+i)]); add_line(name,['Wireless Network/' num2str(Ns+i)],['Goto'... ciRn '/1']); add_line([name '/Wireless Network'],['snd' ciSn '/1'],... ['Mux/' ciSn]); add_line([name '/Wireless Network'],['Demux/' ciRn],... ['rcv' ciRn '/1']); add_line([name '/Wireless Network'],['Ground' ciRn '/1'],... ['Mux/' ciRn]); add_line([name '/Wireless Network'],['Demux/' ciSn],... ['Terminator' ciSn '/1']); end i=1; ciSn=num2str(2*i-1+Ns*2); ciRn=num2str(2*i+Ns*2); add_line([name '/Wireless Network'],['snd' ciSn '/1'],... ['Mux/' ciSn]); add_line([name '/Wireless Network'],['Demux/' ciRn],... ['rcv' ciRn '/1']); add_line([name '/Wireless Network'],['Ground' ciRn '/1'],['Mux/' ciRn]); add_line([name '/Wireless Network'],['Demux/' ciSn],... ['Terminator' ciSn '/1']); save_system(name);
end
Remove generated code
function RemoveOldCode(acg)
Remove all the code generated automatically
delete('Act*'); delete('msg*'); delete('Sens*'); delete([acg.name '.mdl']);
end
end end