Simulation time too slow with Matlab remote api

Typically: "How do I... ", "How can I... " questions
supergan
Posts: 7
Joined: 10 Apr 2015, 16:43

Simulation time too slow with Matlab remote api

Post by supergan » 24 Apr 2015, 16:22

Hi,

I'm currently using Matlab/Simulink to remote control my biped robot model in V-REP for simulation. But since I need to get the correct return values from functions such as simxGetJointPosition, simxGetObjectFloatParameter (with parameter 2012 for joint velocity), simxGetJointForce of the joint position, velocity and force for every simulation step, so I use the "simx_opmode_oneshot_wait" as the remote API function operation mode, this works but the simulation time is too slow: it takes me about 5 min. to simulate only 0.5s!

But if I change to other operation mode such as "simx_opmode_buffer" then I won't get the correct replies since this mode doesn't wait for the actual reply, so is there anything that I can do to accelerate the simulation while still guaranteeing me to get the right replies?

Btw, if it's important for any suggestions, my simulation step is 1ms now.

Any help is appreciated, thank you very much!

Best regards
Lin

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

Re: Simulation time too slow with Matlab remote api

Post by coppelia » 24 Apr 2015, 17:19

Hello Lin,

you should use the streaming mode for that! Make sure you have read and understood this page.
Here a simple Matlab example:

Code: Select all

% Make sure to have the server side running in V-REP: 
% in a child script of a V-REP scene, add following command
% to be executed just once, at simulation start:
%
% simExtRemoteApiStart(19999)
%
% then start simulation, and run this program.
%
% IMPORTANT: for each successful call to simxStart, there
% should be a corresponding call to simxFinish at the end!

function simpleTest()
	disp('Program started');
	% vrep=remApi('remoteApi','extApi.h'); % using the header (requires a compiler)
	vrep=remApi('remoteApi'); % using the prototype file (remoteApiProto.m)
	vrep.simxFinish(-1); % just in case, close all opened connections
	clientID=vrep.simxStart('127.0.0.1',19999,true,true,5000,5);

	if (clientID>-1)
		disp('Connected to remote API server');
	
		% Now retrieve streaming data (i.e. in a non-blocking fashion):
		t=clock;
		startTime=t(6);
		currentTime=t(6);
		vrep.simxGetIntegerParameter(clientID,vrep.sim_intparam_mouse_x,vrep.simx_opmode_streaming); % Initialize streaming
		while (currentTime-startTime < 5)	
			[returnCode,data]=vrep.simxGetIntegerParameter(clientID,vrep.sim_intparam_mouse_x,vrep.simx_opmode_buffer); % Try to retrieve the streamed data
			if (returnCode==vrep.simx_return_ok) % After initialization of streaming, it will take a few ms before the first value arrives, so check the return code
				fprintf('Mouse position x: %d\n',data); % Mouse position x is actualized when the cursor is over V-REP's window
			end
			t=clock;
			currentTime=t(6);
		end
			
		% Now close the connection to V-REP:	
		vrep.simxFinish(clientID);
	else
		disp('Failed connecting to remote API server');
	end
	vrep.delete(); % call the destructor!
	
	disp('Program ended');
end
Cheers

supergan
Posts: 7
Joined: 10 Apr 2015, 16:43

Re: Simulation time too slow with Matlab remote api

Post by supergan » 27 Apr 2015, 10:42

Hi Admin,

acutally I've already been using the streaming mode. Here is a piece of my code for reading values from one leg of my biped robot (3DoF):

Code: Select all

function readJntValue()

    disp('Program started');
    vrep = remApi('remoteApi'); % using the prototype file (remoteApiProto.m)
    vrep.simxFinish(-1); % just in case, close all opened connections

    clientID = vrep.simxStart('127.0.0.1',18888,true,true,5000,5); % Here I made a self-defined port to start V-REP through running Matlab script

    try
        %% check if client connection is successful
        if (clientID > -1)
            disp('Connected to V-REP');
            vrep.simxStartSimulation(clientID,vrep.simx_opmode_oneshot);
            % make matlab be able to send synchronous trigger
            vrep.simxSynchronous(clientID,true);

            %% retrieve all needed objects' handles
            obj_handle = zeros(1,3);
            obj_handleErr = zeros(1,3);

            [obj_handleErr(1), obj_handle(1)] = vrep.simxGetObjectHandle(clientID,'leftHipJoint',vrep.simx_opmode_oneshot_wait);
            [obj_handleErr(2), obj_handle(2)] = vrep.simxGetObjectHandle(clientID,'leftKneeJoint',vrep.simx_opmode_oneshot_wait);
            [obj_handleErr(3), obj_handle(3)] = vrep.simxGetObjectHandle(clientID,'leftAnkleJoint',vrep.simx_opmode_oneshot_wait);

            % Now streaming datas for the first call
            [e,l_hip_jntPos]   = vrep.simxGetJointPosition(clientID,obj_handle(1),vrep.simx_opmode_streaming);
            [e,l_knee_jntPos]  = vrep.simxGetJointPosition(clientID,obj_handle(2),vrep.simx_opmode_streaming);
            [e,l_ankle_jntPos] = vrep.simxGetJointPosition(clientID,obj_handle(3),vrep.simx_opmode_streaming);

            [e,l_hip_jntVel]   = vrep.simxGetObjectFloatParameter(clientID,obj_handle(1),2012,vrep.simx_opmode_streaming);
            [e,l_knee_jntVel]  = vrep.simxGetObjectFloatParameter(clientID,obj_handle(2),2012,vrep.simx_opmode_streaming);
            [e,l_ankle_jntVel] = vrep.simxGetObjectFloatParameter(clientID,obj_handle(3),2012,vrep.simx_opmode_streaming);

            jntCurrPos_r = zeros(1,3);
            jntCurrVel_r = zeros(1,3);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Here after are 2 ways I've tried for reading values from my V-REP robot model %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
           
           % Method 1: through reading values with "simx_opmode_buffer" operation mode

            for i = 1:3
                [e,jntCurrPos_l(i)] = vrep.simxGetJointPosition(clientID,obj_handle(i),vrep.simx_opmode_buffer);
                [e,jntCurrVel_l(i)] = vrep.simxGetObjectFloatParameter(clientID,obj_handle(i),2012,vrep.simx_opmode_buffer);
            end

            % Method 2: through reading values with "simx_opmode_oneshot_wait" operation mode

            for i = 1:3
                [e,jntCurrPos_l(i)] = vrep.simxGetJointPosition(clientID,obj_handle(i),vrep.simx_opmode_oneshot_wait);
                [e,jntCurrVel_l(i)] = vrep.simxGetObjectFloatParameter(clientID,obj_handle(i),2012,vrep.simx_opmode_oneshot_wait);
            end
        else
            disp('Failed connecting to V-REP');
        end
    catch err
        disp('Error while updating first touch down phase, please check!');
        msgString = getReport(err);
        disp(msgString);
        vrep.simxStopSimulation(clientID,vrep.simx_opmode_oneshot);
        pause(1)
        vrep.simxFinish(clientID);
        vrep.delete(); % call the destructor!
    end
My problem now is that the values I retrieved from both the 2 methods are not the same, and the correctness of these values is the most important issue for my task because I need to use the retrieved values to calculate other key information such as torques to be applied to each jont etc. So small error as torlence can be accepted, but the values of these 2 methods differ from each other significantly, especially for the read velocity issue.

The values from the second method, namely retrieved from "simx_opmode_oneshot_wait" mode are exactly the right ones that I need, but under this mode my simulation runs too slow...

On the other hand, if I change to the "simx_opmode_buffer" mode, there is no guarantee that I always get the right replies from V-REP, and as a result, what I see from simulations are sometimes it runs as expeted, but sometimes not, it seems so randomly...

I've also tried to combinely use both the two modes in my code, like after streaming all the functions, to ensure the first reading values' correctness with "simx_opmode_oneshot_wait", and then since a reasonable tolerance can be accepted, I switch to "simx_opmode_buffer" for the rest of retrieving value functions, but unfortunately this doesn't work, what I got was a total collapse of my model and the values were incorrect.

So again my question: Is there anything I can do to accelerate my simulation while keeping me receiving the right values that I need?

This problem has been annoying me for weeks, any help will be very appreciated!

Thank you very much!

Best Regards
Lin

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

Re: Simulation time too slow with Matlab remote api

Post by coppelia » 27 Apr 2015, 11:17

Lin, you are not using the streaming mode correctly!

Make sure you first understand how to use it. Again, here the example I previously provided:

Code: Select all

vrep.simxGetIntegerParameter(clientID,vrep.sim_intparam_mouse_x,vrep.simx_opmode_streaming); % Initialize streaming
while (currentTime-startTime < 5)   
    [returnCode,data]=vrep.simxGetIntegerParameter(clientID,vrep.sim_intparam_mouse_x,vrep.simx_opmode_buffer); % Try to retrieve the streamed data
    if (returnCode==vrep.simx_return_ok) % After initialization of streaming, it will take a few ms before the first value arrives, so check the return code
        fprintf('Mouse position x: %d\n',data); % Mouse position x is actualized when the cursor is over V-REP's window
    end
    t=clock;
    currentTime=t(6);
end
Notice that you need to check if the value is valid by doing:

Code: Select all

if (returnCode==vrep.simx_return_ok)
The reason is that the first set of data that are being streamed need an initial time to arrive. So right after initializing streaming, if you try to use simx_opmode_buffer, the result will NOT be simx_return_ok!!

Then, it seems you are using the synchronous mode, where you need to trigger yourself each individual simulation pass. The synchronous mode is obviously slower. Not sure you really need it.

Cheers

supergan
Posts: 7
Joined: 10 Apr 2015, 16:43

Re: Simulation time too slow with Matlab remote api

Post by supergan » 27 Apr 2015, 14:32

Hi Admin,

I've re-read the description of the link you gave me, and my understanding is that if I want to use a "get" function to retrieve values from V-REP correctly, then:

1. I need to initialize the function with the mode "simx_opmode_streaming" to make sure the function will be continously processed V-REP and sent back replies to a remote API like here in my case Matlab/Simulink.

2. After that if I want to retrieve the values from the "get" function I need to use the "simx_opmode_buffer" mode as a combination, and as you mentioned, there is a few ms' lag for V-REP to receive the datas for the first period, so I need to check the return flag to make sure whether it equals to "simx_return_ok", if yes, then it means the values I get from the functions are correct.

But, after reviewed my code and added the "check flag" part, it seems that the returnCode flag for the "simx_opmode_buffer"

Code: Select all

vrep.simxGetJointPosition(clientID,obj_handle(1),vrep.simx_opmode_streaming);

% here are some other rows of codes
%
%
[returnCode,hipPos_l] = vrep.simxGetJointPosition(clientID,obj_handle(1),vrep.simx_opmode_buffer);
if (returnCode==vrep.simx_return_ok)
    hipPos_l % just show the retrieved value in workspace
else
    disp('hip position not correctly retrieved!')
end
is correct since from the first loop of debugging I can see the value showed in Matlab workspace and the else-condition is none processed and the value of returnCode is 0 which corresponds the simx_return_ok.

But still, the result is not the right value that I want, with comparision to the value showed through the "Scene Object Properties" dialog of the joint in my scene, which corresponds to the values retrieved from "simx_opmode_oneshot_wait".

Actually I'm gonna explain you more in detail about what I'm done and may be this will help you to give me further suggestions:

I'm doing all my control work through Simulink S-functions, so in my work:
1. I build up an S-function called "Simulink V-REP interface" and inside the function I established the connection between the two softwares.
2. For every other S-function block, I initialize the streaming mode of all the "get-functions" I'll use to retrieve datas within the "Start" callback method, and in the "Update" callback method, I use the "simx_opmode_oneshot_wait" or "simx_opmode_buffer" mode to get values from V-REP. Next, I calculate the torques to be applied to each joint of my robot with the help of retrieved datas and apply them to my model through torque/force control mode in this way:

Code: Select all

            % apply torques to the robot
            vrep.simxPauseCommunication(clientID,1);
            for i=1:6
                vrep.simxSetJointTargetVelocity(clientID,obj_handle(i),vMax*sign(tau2Rob(i)),vrep.simx_opmode_oneshot);
                vrep.simxSetJointForce(clientID,obj_handle(i),abs(tau2Rob(i)),vrep.simx_opmode_oneshot);
            end
            vrep.simxPauseCommunication(clientID,0);

            % trigger synchronous mode
            vrep.simxSynchronousTrigger(clientID);
Hopefully that you can give me any further advices, thank you!

Best Regards
Lin

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

Re: Simulation time too slow with Matlab remote api

Post by coppelia » 28 Apr 2015, 09:12

The difference between simx_opmode_oneshot_wait and simx_opmode_buffer is that the first will retrieve a value that is slightly more fresh, since it will take longer to execute, and fetch a later value.

Are the values that you retrieve with simx_opmode_buffer completely wrong, or just slightly different from when you retrieve them with simx_opmode_oneshot_wait?

Cheers

supergan
Posts: 7
Joined: 10 Apr 2015, 16:43

Re: Simulation time too slow with Matlab remote api

Post by supergan » 28 Apr 2015, 15:33

Sometimes they are completely wrong, but sometimes there are only small differences.

I just noticed that under simx_opmode_buffer mode, with the same method you told me (e.g. returnCode==vrep.simx_return_ok), I got 2 different results for different functions:

1. for function simxGetObjectOrientation and simxGetObjectVelocity to retrieve an object's euler angle, angular & linear velocity, the returnCode is always 0 and the values are slightly different from the ones read from simx_opmode_oneshot_wait, or better to say, they are the values of the last simulation step, which means there is one simulation step lag, and this can be fully accepted and I already knew that before.

2. for function simxGetJointPosition, in the first loop - just after I start the simulation from Simulink, all returnCode are 0 and the values I get are also one simulation step delayed, then without changing anything, from the next loop, all the returnCode change to 1, which means simx_return_novalue_flag, and the values I get are 43.

3. for simxGetObjectFloatParameter, the first loop I get returnCode==0 and the velocity values are totally different from the ones retrieved from simx_opmode_oneshot_wait, and I don't know why they vary from each other so much. And after that, the returnCode changes to 1 and all retrieved velocities are 0.

What I'm done for my robot initialization is to set the intrinsic positions of each joint at simulation start with the function simxSetJointPosition, and then do the control work with all these get and set functions. So actually I can understand that in simx_opmode_buffer, the velocities I retrieved are all greater than 100 rad/s cause my intrinsic position is for example the hip joint -0.3450 rad, with my simulation step of dt=2ms, the velocity I get is -0.3450rad/2ms=-170rad/s, this is one problem that I have been stucked for a long time actually, but in the "simx_opmode_oneshot_wait", this problem is automatically solved since the value I get are something like 0.9222 rad/s for the hip joint. To be honest, I don't understand why this happens but the values suit my programm perfectly.

It looks complicated and I hope that I have explained my situation clear fot the 2 confusions I meet now, really looking forward for your help!

Best Regards

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

Re: Simulation time too slow with Matlab remote api

Post by coppelia » 29 Apr 2015, 08:32

When you receive a return code different from simx_return_ok, then the other values are random (basically not initialized). This is normal since there is nothing to return (yet).

For your strange behaviour, it is quite complicated to understand what is happening. Could you try to simplify your scene and code to a maximum, and send a simple example that illustrates the problem? A simple Matlab code example would be helpful, so that we can reproduce the behaviour here.

Cheers

supergan
Posts: 7
Joined: 10 Apr 2015, 16:43

Re: Simulation time too slow with Matlab remote api

Post by supergan » 30 Apr 2015, 08:55

Hi,

I've added all the files into this dropbox link:

https://www.dropbox.com/sh/f9yo7da90ld3 ... Iuo5a?dl=0

I'm sorry that I add a few files although I've tried my best to simplify my scripts... You can find a text file with detail explainations with the name of "explaination_readme".

Best Regards
Lin

perceptron
Posts: 1
Joined: 04 Mar 2015, 20:48

Re: Simulation time too slow with Matlab remote api

Post by perceptron » 23 Jun 2015, 11:44

I have the same problem for a visual servoing application:(

Post Reply