Simulink 내의 Matlab Level-2 S 함수에서 객체를 가져올 수 있는지 궁금합니다.Simulink에서 Matlab Level 2 S 함수의 Matlab 객체 가져 오기
이전에는 Matlab의 동적 모델에 강화 학습을 적용했습니다. 결과적으로 정책 생성 및 업데이트를 다루는 클래스를 만들었습니다. 이제는 더 복잡한 동적 시스템을 가지고 있으므로 Simulink로 이동해야합니다. 저는 C S- 함수에 익숙하지만, 이미 두 클래스의 Matlab 코드를 가지고 있기 때문에 이러한 객체를 사용하는 Matlab S 함수를 사용하려고 생각하고있었습니다.
내 작업 흐름은 다음과 같습니다. 정책 개체가 초기화되는 주 Matlab 함수는 동적 모델로 Simulink 파일을 호출합니다. S- 기능에서, 정책 객체는 액션 (컨트롤 시스템의 출력)을 선택하라는 호출입니다. Simulink 파일을 여러 번 시뮬레이션 한 후에 정책 객체 (실제로는 가중치)가 Matlab 함수에서 업데이트됩니다.
따라서 Simulink의 Matlab S-function에서 policy
개체를 가져 오는 방법이 필요합니다. 매개 변수로 가져 오기를 시도했지만 숫자 값만 허용됩니다. 기본 Matlab 스크립트의 가중치를 업데이트해야하기 때문에 S 함수 내에서만 객체를 유지할 수 없습니다 (따라서 초기화 함수 내에서 객체 초기화).
이것이 가능합니까? 어떤 제안이라도 대단히 감사하겠습니다! 다음과 같이
정책 클래스의 예는 다음과 같습니다
classdef Policy
%% Accessible properties:
properties
a; % selected action index
actions; % actions list
basis; % type of basis function
centres; % list of centres of the RBFs
exploration_rate; % exploration rate
mu; % width of each RBF
nbasis; % no. basis functions overall
states; % list of discrete states
weights; % weights of the linear function approximation
end
%% Protected properties:
properties (Access = protected)
na; % no. actions
ns; % no. discrete states
nrbf; % no. radial basis functions per action
state; % current state
Q; % Q value for each action-state pair
end
%% Accessible methods:
methods %(Access = protected)
%% Initialization function:
function obj = Policy(actions,states,epsilon,basis,mu)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Input:
% actions: actions list
% states: states list or centres of the RBFs
% epsilon: initial exploration rate
% delta: discount factor
% basis: type of basis functions
% mu: width of each RBF
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if nargin<4
basis = 'basis_exact';
end
obj.actions = actions;
obj.states = states;
obj.exploration_rate = epsilon;
switch basis
case 'basis_exact'
obj.basis = basis;
obj.states = states;
obj.ns = size(states,1);
case 'basis_rbf'
obj.basis = basis;
obj.centres = states;
obj.mu = mu;
obj.nrbf = size(states,1);
otherwise
error(['Only exact and radial basis functions',...
'supported']);
end
end
%% Setter function for the features' weights:
function obj = set_weights(obj,weights)
obj.weights = weights;
end
%% Update the exploration rate with the given rate:
function obj = update_epsilon(obj,rate)
obj.exploration_rate = obj.exploration_rate*rate;
end
%% Select an action:
function obj = select_action(obj,state)
% Store the current state:
obj.state = state;
% Compute the state-action values for the current state:
obj = obj.qvalues();
% Get the current action with an epsilon-greedy policy:
obj.a = obj.eGreedy();
end
%% Evaluate the features:
function phi = get_features(obj,state,action)
% Store the current state:
obj.state = state;
% Get the features:
phi = feval(obj.basis,action);
end
end
%% Protected methods:
methods (Access=protected)
%% Find the discrete state:
function s = discretizeState(obj,x)
% Copy the row vector entries (continuous states) to all rows:
x = repmat(x,obj.ns,1);
% Select the row using the minimum Eucledian distance:
[~,s] = min(sum((obj.states-x).^2,2).^0.5);
end
%% Get the Q-value function for current state and action:
function q = qvalue(obj,action)
phi = feval(obj.basis,action);
q = phi' * obj.weights;
end
%% Get the Q-value functions for the current state:
function obj = qvalues(obj)
% Initialize the Q-values for the current state:
obj.Q = zeros(obj.na,1);
% Calculate the state-action values for the current state:
for a=1:obj.na
obj.Q(a) = obj.qvalue(a);
end
end
%% Get an action with an epsilon-greedy exploration policy:
function a = eGreedy(obj)
% Generate a random number:
r = rand;
% Select the action that maximises Q(s)
if (r>obj.exploration_rate)
[~,a] = max(obj.Q); % value, action
% Choose a random action:
else
a = randi(obj.na); % random integer based on a uniform
end % distribution
end
%% Find the features for the exact basis functions:
function phi = basis_exact(obj,action)
%Initialize the features:
phi = zeros(obj.nbasis,1);
% Find the current discrete state:
s = discretizeState(obj.state);
% Find the starting position of the block:
base = (action-1) * obj.ns;
% Set the indicator:
phi(base+s) = 1;
end
%% Find the features for the radial basis functions:
function phi = basis_rbf(obj, action)
%Initialize the features:
phi = zeros(obj.nbasis,1);
% Find the starting position:
base = (action-1) * (obj.nbasis/obj.na);
% This is because the matrix Theta is converted into a line
% vector
% Compute the RBFs:
for i=1:obj.nrbf
phi(base+i) = exp(-norm(obj.state-obj.centres(i,:))^2/...
(2*obj.mu));
end
% ... and the constant:
phi(base+obj.nrbf+1) = 1;
end
end
end
MATLAB 명령 프롬프트에서'sfundemos'를 입력하십시오. 좋은 예를 찾아 볼 수 있습니다. 'msfuntmpl'과'msfuntmpl_basic'과 같은 템플릿도 있습니다. 이 둘을 입력하고 Ctrl + D를 누릅니다. 일반적으로 레벨 2 MATLAB-S-Function에서 모든 MATLAB Object를 사용할 수 있습니다. 소스 파일이 MATLAB 경로에 있는지 확인하십시오. –
고맙습니다! 따라서 주 파일과 Matlab S 함수에서 동일한 Matlab 객체를 사용하려면 매개 변수로 가져올 필요가 없습니다. –
이것이 까다로워지고 더 이상 확실하지 않습니다. 변수를'global'으로 선언 할 수도 있고, S-Function 내부에서'obj = evalin ('base', 'OBJ')'를 통해 기본 작업 공간에서 객체를 가져 와서 작업 할 수도 있고'assignin ('base' 'OBJ', obj)'. 이 코드가 MATLAB-Script를 가지고 있고 Simulink-Model이 메모리의 같은 개체를 참조하기에 충분한 지 모르겠습니다.시도해보십시오! ... –