Programmatically add Actors to sim3d world in Simulink

Hi everyone,
My language might be a bit non-technical, but I will try to explain myself clearly. I have a project in which I am trying to simulate a drone in a 3D environment. I would like to build that environment programmatically in Matlab, but run the simulation in Simulink (because there are various nice function blocks for camera sims, etc in Simulink). I would like to be able to Add and Remove Actors from the environment using Matlab functions or based on some struct/cell array/object list in Matlab. This is proving to be quite a challenge.
Unfortunately, it doesn't seem that I can create a 3D world object outside of Simulink that interfaces nicely with the aforementioned blocks (they require the inclusion of a '3D Scene Configuration' block in the same model, and I think it is this block that creates the sim3d world object).
I am now hoping that I can somehow get the name or handle of the world created by this scene config block and pass it to a Matlab function block, in which I can add the 3D actors. However, I have no idea how to find the handle or name. I've tried combing through the Model Explorer. Is there some version of "findObj" that works in Simulink?
Does anyone have a better suggestion? I'm sure this is a problem faced by many before me, and it is possible that my approach is not the best way.

 Réponse acceptée

Nishan Nekoo
Nishan Nekoo le 30 Août 2024
Hi Alyssa,
There are a few different approaches you can take here and I think this example could be very relevant for you: https://www.mathworks.com/help/sl3d/automate-virtual-assembly-line.html
" I would like to build that environment programmatically in Matlab, but run the simulation in Simulink"
The example above uses the Simulation 3D Actor block (labelled "Prepare World") to load in a .m file that contains several 3D Actors. This is how an environment built programmatically in MATLAB can be loaded into Simulink. Note that the .m file should not contain any notion of a sim3d.World. An alternative is to create a .mat file instead. This can be done by creating a world programmatically in MATLAB then while the simulation is running, right click in the Simulation 3D Viewer window and click "Save as MAT file".
"I would like to be able to Add and Remove Actors from the environment using Matlab functions or based on some struct/cell array/object list in Matlab"
If you use a .mat file instead of a .m file in the first step above, you can use the Simulation 3D Actor block and the "Inputs" tab to create input ports for any of the properties of the Actors that you added programmatically. This includes the "Hidden" property which you can use to effectively add or remove an actor from the environment.
I think this should help you get started, but please feel free to respond if you have any additional questions.
Nishan

12 commentaires

Hi Nishan
Thank you for your help! I am trying to mimic this example, with a much simpler starting case. However, I am finding that the second object created in the block does not show in the 3D simulation viewer. Is there some command I need to run to force it to render? It is not Hidden, according to its properties.
Here is my "loadActors.m" file:
function loadActors(Actor, World)%Load actors
%Actor.load('Actor1_scene.mat')
Actor1 = Actor;
createShape(Actor1, 'box', [0.2, 0.2, 1]);
Actor2 = sim3d.Actor('ActorName','Actor2');
%Actor2.load('Actor2_scene.mat');
createShape(Actor2, 'cylinder', [0.5, 0.5, 0.75]);
add(World, Actor2);
It is called as follows:
And the output is:
Thank you!
just a follow up question related to the query above, i am trying to implement a means to reset all of the postions of the actors in my 3Dworld, the world has been created via the 3d actor block and scene configuration within simulink. i have programmed it so that when a certain actor is clicked, it inititates a call back 'OnClick' which pass out to function in my matlab script only the handle of the actor which was clicked, i am then able to programmatically interact with the actor properties via the handle. However what i want to do is once that actor is clicked, i want to interact with more than just one but i want to reset the position of the clicked actor and all of the other actors in the scene, but i have not been able to find a way to obtain the handles or communicate with all of the other actors.
so basically how can i obtain the handles of all of the actors in the scene to communicate with them when a call back is intitate, "Onclick" or even "onHit".
thanks for the help in advance.
Hi Iyanuoluwa, assuming your Actor has the root as its parent, it is possible to access all the actors in the scene through the Parent property. If your actor is several layers deep in an actor hierarchy, you could iterate upward through the "Parents" as necessary.
>> Actor.Parent.Children
or
>> Actor.Parent.Parent.Children
etc..
The above should give you a list of the Actors in the world that you can manipulate in any way you need.
Nishan
i have not managed to get it working, So for example if my 3d actor block is named Sim3dActor10, and i have a component within it called Chamber1, would the syntax be Actor.Sim3dActor10.Chamber1.Translation?
my actor hierachy in the simulink generated 3d world is:
and the script which i am calling up for example when the Heatgun actor is clicked is using the OnClick callback and @PosRESET handle:
function PosRESET(~)
Actor.Sim3dActor10.Chamber1.Translation = [0 -9 0];
end
could you let me know where i am going wrong
thanks.
forget the last question i figured it out;
just for anyone who comes across this in the future;
this would be the example function you would use; use the Assign in workspace lines to get the correct names incase you are unsure.
function PosRESET(id) %id is the handle of the clicked actor
v = id.Parent.Name;
y = id.Parent.Children;
assignin("base","v",v);
assignin("base","y",y);
id.Parent.Children.Chamber1.Translation= [0 -9 0];
end
thanks for the help @Nishan Nekoo
Hi @iyanuoluwa Adeoye, glad you managed to figure it out and apologies if my guidance was a little unclear before :)
Please don't hesitate to post a question if you run into anything else, we'd love to hear from you.
Nishan
As a followup, and out of curiousity incase i need it, is there a way to programmatically interact with the simulink 3d world environment without the need for a callback to acquire an actors handle first, so currently using the OnClick or onHit the callbacks provides the handle of an actor within the 3d world and using that actor you can access all other actors using the parent/children properties, but if i wanted to access the actors without using a callback the commands i have tried so far have not worked, i have tried the following;
sim3d.internal.RootObject.Children.Sim3dActor10.Children.Heatgun;
sim3d.World.Actors.Sim3dActor10.Children.Heatgun;
a screenshot of my rootobject is below;
as seen in the screen shot, when i hover my cursor over the RootObject hyperlink, it show sim3d.Internal.RootObject which i assume is the toplevel, and from there tracing the Children and Actor relationships i would think i should be able to communicate with the actors from the matlab command prompt with this command(note: i traced the children/actor relationships to create the line of code): sim3d.internal.RootObject.Children.Sim3dActor10.Children.Heatgun;
but i get the following error: Unrecognized method, property, or field 'sim3d' for class 'sim3d.internal.RootObject'.
thanks for the help.
Hi Iyanuoluwa,
This is a good question and is not a currently documented workflow so some things may not work as expected. The default world created in Simulink has the name "untitled", so if you run the following command, you should get a handle to the World object that contains all the actors too.
worldHandle = sim3d.World.getWorld("untitled");
actorHandles = worldHandle.Actors;
Let me know if that works for you, or if you run into any issues. Again, note that this is not a documented workflow, so some behavior might be unexpected.
Nishan
The function works :), the name of the world is the name of the simulink model within which the the simulink actor blocks have been saved so in my case "Static_MiniRig_Model", after getting the handle i was able to easily access the actor properties just by following the relationships.
worldH= sim3d.World.getWorld("Static_MiniRig_Model");
worldH.Actors.Heatgun.Translation = [0 -9 0];
i have not tried anything extravagent apart from simple translations so i cant say how robust this method of interaction is, but its has given me the correct translation results so far. i'm sure knowing function will come in handy down the line, will it be further developed and properly documented in future releases?
thanks for the help.
Ah that's good to know that it takes on the name of the Simulink model, thanks for letting me know :)
We'll consider documenting the function and workflow in a future release but I can't say for sure whether we will or when it will happen!
Nishan

Connectez-vous pour commenter.

Plus de réponses (0)

Community Treasure Hunt

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

Start Hunting!

Translated by