MATLAB - Simulations and Collecting Data

Typically: "How do I... ", "How can I... " questions
Post Reply
codycichosz
Posts: 22
Joined: 06 Dec 2020, 00:39

MATLAB - Simulations and Collecting Data

Post by codycichosz »

Hello,

I'm using MATLAB code to run simulations in Coppelia of a UR10 and a person to check for collisions between the two. I am looking to run the scene, collect data points, change the position of the person, and restart the scene and grab the same data. I would like to grab the position of the person and the UR10, and even check between the two if a collision occurred. I have used an XY graph to extract the position data into a .csv file but the file is limited to 1000 points or roughly 50 seconds of simulation time. Or would it be better to collect this data inside of MATLAB? I am looking to get some guidance on how I should set this up, the most efficient way to collect the data (and store it), as well as any other tips.

Thanks,
Cody

coppelia
Site Admin
Posts: 8986
Joined: 14 Dec 2012, 00:25

Re: MATLAB - Simulations and Collecting Data

Post by coppelia »

Hello Cody,

you can easily change the number of points a graph is recording, in the graph properties dialog (i.e. Buffer size).

Graphs are convenient to display data directly within CoppeliaSim. Of course you can also export that data, but since you have several different type of data you want to record at the same time, you better handle this in a different way. The most direct would be to call simxGetObjectPosition and similar, directly from Matlab. But probably better would be to read all the data inside of a script function, e.g.:

Code: Select all

function sysCall_init()
    robotJoints={}
    for i=1,6,1 do
        sim.getObjectHandle('robotJoint'..i)
    end
    humanModel=sim.getObjectHandle('human')
    humanCollection=sim.createCollection(0)
    sim.addItemToCollection(humanCollection,sim.handle_tree,humanModel,0)
end

function getData(inInts,inFloats,inStrings,inBuffer)
    local robotAngles={}
    for i=1,#robotJoints,1 do
        robotAngles=sim.getJointPosition(robotJoints[i])
    end
    local humanPosition=sim.getObjectPosition(humanModel)
    local isColliding=sim.checkCollision(humanCollection,sim.handle_all)
    
    local outInts={isColliding}
    local outFloats={}
    for i=1,#robotAngles,1 do
        outFloats[#outFloats+1]=robotHandles[i]
    end
    for i=1,#humanPosition,1 do
        outFloats[#outFloats+1]=humanPosition[i]
    end
 	return outInts,outFloats,{},''
end
then call above getData function with simxCallScriptFunction.

Additionally, you probably want to run in synchronous mode, so that you can exactly record one set of data in each simulation step.

Cheers

codycichosz
Posts: 22
Joined: 06 Dec 2020, 00:39

Re: MATLAB - Simulations and Collecting Data

Post by codycichosz »

Hello Coppelia,

I am able to change the graph buffer size, which helps immensely, but it looks like there is only 1 way to extract that data, which is manually. After the simulation has stopped by selecting "File", "Export", and then "Selection (graphs)". I do not see any remote API function to help with this.

It looks like the better way to do this is creating the script function as you said. I am new to CoppeliaSim and Lua Script writing. For the following code:

Code: Select all

--lua
for i=1,#humanPosition,1 do
    outFloats[#outFloats+1]=humanPosition[i]
end
It looks like it will output the [x,y,z] of the human position once for every time this function is called. Is there a way to build this position data in a matrix/table and pull it at the end of my simulation?

Thanks,
Cody

coppelia
Site Admin
Posts: 8986
Joined: 14 Dec 2012, 00:25

Re: MATLAB - Simulations and Collecting Data

Post by coppelia »

It is an indirection to save data via graphs. Graphs are mainly meant for visualization. If you need to export data, then simply record that data inside of a script, then write it to a file at the end of the simulation. e.g. from within a child script, here a very very simple example:

Code: Select all

function sysCall_init()
    humanHandle=sim.getObjectHandle('myHumanModel')
    recordedPositions={}
end

function sysCall_sensing()
    local p=sim.getObjectPosition(humanHandle,-1)
    recordedPositions[#recordedPositions+1]=p[1]
    recordedPositions[#recordedPositions+1]=p[2]
    recordedPositions[#recordedPositions+1]=p[3]
end

function sysCall_cleanup()
    -- Here you can store/export the recorded data
end
Cheers

Post Reply