Matlab Coder: How can I implement a tracker with seperate functions for initialization and predict/update?

2 views (last 30 days)
The tutorial "How to Generate C Code for a Tracker" implemented the tracker as a one function with a persistant variable.
My problem is that I would like to pass arguments from a configuration file for the initialization, and predict to specific time for prediction only without a detection to fuse, but I would rather like to avoid passing the initialization arguments and some empty detection just to predict every call. Is there some infrustructure that will allow me to maintain a persistant tracker and a few functions that interact with it without the problem of incompatiblity of handle classes.
Thanks!

Answers (1)

Elad Kivelevitch
Elad Kivelevitch on 26 Aug 2021
The short answer is - not directly. When you generate code, you cannot pass handle classes to or from the top-level class, which means that you cannot interact with that object outside of the top-level class.
A couple of things you can try to see if they help get what you want, even if it's in a different way.
First, you can make sure that you setup the tracker with a dummy detection so that it is fully ready for any call even if you don't have a detection on the next call. To do that:
function outTracks = tracker_kernel(detections, time)
persistent tracker
if isempty(tracker)
tracker = % Define whatever you want to define the tracker here
% Make sure to define a detection in the exact same format as the
% inputs you expect to get in detections
dummyDetection = % Whatever
setup(tracker, dummyDetection, 0);
reset(tracker);
% After that, the tracker is locked and fully defined
end
outTracks = tracker(detections, time);
The second thing that might work, but I am not sure if it would is to add an input to define what method you want to call:
function outTracks = tracker_kernel(method, detections, time)
persistent tracker
if isempty(tracker)
tracker = % Define whatever you want to define the tracker here
% Make sure to define a detection in the exact same format as the
% inputs you expect to get in detections
dummyDetection = % Whatever
setup(tracker, dummyDetection, 0);
reset(tracker);
% After that, the tracker is locked and fully defined
end
switch lower(method)
case 'step'
% That is the usual step call
outTracks = tracker(detections, time);
case 'predict'
% Note that you will still have to pass an empty detections cell as
% the 2nd input argument for this to work even though it is not
% used by the predict call. You cannot change the input arguments
% after compilation.
outTracks = predictTracksToTime(tracker, 'all', time);
otherwise
% This will let coder know that it's OK not to set outTracks when
% the method name is not one of the above options. It's OK because
% coder will know not to expect outTracks in such a case
assert(false)
end
Please note: I have not prototyped it, so it may or may not work. I would appreciate it if you could let me know if it did work.
  2 Comments
Idan goldman
Idan goldman on 26 Aug 2021
Thank you for the answer.
Another problem I have is that I would like to pass initialization arguments (for example transition probablities of IMM) from a configuration file. Can I read from a configuration file(like xml) with the matlab coder? (Is it a good practice?). As I understand it, the xmlread is not supported by coder so I thought of passing it as arguments but it would be inefficient to pass initialization paramaters for each call of predict and update.
Elad Kivelevitch
Elad Kivelevitch on 26 Aug 2021
I think the bigger question is why would you want to reinitialize the filter that is already set up and tracking during the run at every step? That does not sound like a good idea to me.
If you want to try various sets of values for each run (but use the same values for the entire run), I suggest using the filter initialization function for that. You can do something like that:
function imm = myIMMInitFcn(detection)
% First save the parameters from the XML file to a regular mat file
params = coder.load('myFileName.mat');
% Initialize your IMM in the same way you always do. For example, use
% initekfimm.
imm = initekfimm(detection);
imm.TransitionProbabilities = params.TransitionProbabilities;
end
If you do want to modify filter properties at each step, then there is a cumbersome way of doing it. In the top-level function of the tracker from above, you can add a 'reinitialize' case, where you would again load the parameters from the file and then set the filter properties. It would look something like:
function outTracks = tracker_kernel(method, detections, time)
persistent tracker
if isempty(tracker)
tracker = % Define whatever you want to define the tracker here
% Make sure to define a detection in the exact same format as the
% inputs you expect to get in detections
dummyDetection = % Whatever
setup(tracker, dummyDetection, 0);
reset(tracker);
% After that, the tracker is locked and fully defined
end
switch lower(method)
case 'step'
% That is the usual step call
outTracks = tracker(detections, time);
case 'predict'
% Note that you will still have to pass an empty detections cell as
% the 2nd input argument for this to work even though it is not
% used by the predict call. You cannot change the input arguments
% after compilation.
outTracks = predictTracksToTime(tracker, 'all', time);
case 'reinitialize'
% Here you load your params from mat file.
% Aletrnatively, you can pass them as a 4th input argument but
% you'll need to define it and generate code for the the function
% to allow that.
params = coder.load('myFileName');
% You need to find all the tracks that the tracker maintains and
% then set each one's filter to your new parameters. The "easiest"
% way is to predict the tracks to the time of the previous tracker
% call. Remember to pass an empty detections cell to the top level
% function.
outTracks = predictTracksToTime(tracker, 'all', time);
% You can set the values of publicly settable properties on the
% filter but you have to do it for each track one-by-one. Note:
% This will not impact new filters that are initialized when a
% detection is unassigned in the next step. To affect those, you
% will need to modify the filter initialization function as well.
for i = 1:numel(outTracks)
setTrackFilterProperties(tracker, outTracks(i).TrackID, ...
'Prop1', params.Prop1, 'Prop2', params.Prop2);
end
otherwise
% This will let coder know that it's OK not to set outTracks when
% the method name is not one of the above options. It's OK because
% coder will know not to expect outTracks in such a case
assert(false)
end
As before, this is completely hypothetical and unvetted. Please make sure that it works.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!