Enabling spring-damper mode through regular API?

Typically: "How do I... ", "How can I... " questions
FrankVeen
Posts: 7
Joined: 15 Mar 2016, 16:01

Enabling spring-damper mode through regular API?

Post by FrankVeen » 18 Aug 2016, 12:55

Hi,

Can the "Spring-damper mode" of a joint be activated through the regular API?

I would normally activate the control loop of a joint with: simSetObjectInt32Parameter(joint_handle, 2001,1);
However, this automatically enables the PID position control mode and I am not able to switch to the spring-damper mode.

Thanks in advance.

Cheers, Frank

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

Re: Enabling spring-damper mode through regular API?

Post by coppelia » 18 Aug 2016, 13:09

Hello Frank,

you can still use simSetObjectInt32Parameter(joint_handle, sim_jointintparam_ctrl_enabled,1). But in that case, you should have prepared the spring-damper mode ahead (via GUI, before the simulation start), then disabled the control loop (also via the GUI).

Otherwise you can set your joint into spring-damper mode, and adjust via API the K and C parameters:

Code: Select all

simSetObjectFloatParameter(joint_handle, sim_jointfloatparam_kc_k,kValue)
simSetObjectFloatParameter(joint_handle, sim_jointfloatparam_kc_c,cValue)
Yet another option is to keep your joint with a custom control (i.e. using a joint control callback script). In there, you can then dynamically change the control as it pleases you. But you'll have to write the spring/damping controller yourself (not difficult).

Cheers

FrankVeen
Posts: 7
Joined: 15 Mar 2016, 16:01

Re: Enabling spring-damper mode through regular API?

Post by FrankVeen » 19 Aug 2016, 13:49

you should have prepared the spring-damper mode ahead (via GUI, before the simulation start)


I am using a generative algorithm to create objects that are connected to each other so in my case I would like to avoid using the GUI.

However, it was easy to write a small custom controller for joints that need spring-like properties (I just wrote it directly in the plugin I am working on).

Thanks!

Cheers, Frank

streets
Posts: 8
Joined: 18 Dec 2017, 17:25

Re: Enabling spring-damper mode through regular API?

Post by streets » 18 Jan 2018, 18:33

Hi,

I'm facing the same issue (not being able to enable the spring-damper mode programmatically). I am also trying to generate everything from a script, mainly because v-rep doesn't provide a text-based format for the scenes yet (according to another post this feature is delayed to an unknown future). Unfortunately I am not familiar with writing spring damper controllers, maybe somebody can provide me with some hints/links to where I can find information that will enable me to do so.

Thanks in advance.

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

Re: Enabling spring-damper mode through regular API?

Post by coppelia » 22 Jan 2018, 09:21

Hello,

use the following example script-damper: Models/examples/spring-damper.ttm

Attach a non-threaded child script to the joint with following content:

Code: Select all

if (sim_call_type==sim_childscriptcall_initialization) then
    local joint_handle=simGetObjectAssociatedWithScript(sim_handle_self)
    simSetObjectFloatParameter(joint_handle, sim_jointfloatparam_kc_k,250)
    simSetObjectFloatParameter(joint_handle, sim_jointfloatparam_kc_c,6.25)
    simSetJointForce(joint_handle,250)
    simSetJointTargetVelocity(joint_handle,100)
end
Then you can play with the various parameters and see the effect. The two last parameters are parameters needed by the physics engine. For an ideal spring-damper, the joint force and target veloicity should be quite high. But you can obtain interesting effects by reducing them.

Cheers

streets
Posts: 8
Joined: 18 Dec 2017, 17:25

Re: Enabling spring-damper mode through regular API?

Post by streets » 22 Jan 2018, 13:38

Hello and thanks for the quick answer,

the setting of the K and C parameters is not the issue that I am facing.

What I need is an example joint-script that realizes the spring-damper functionality. Since I can't enable the spring-damper mode from the LUA-api (only the predefined PID control is available), I need to write this on my own (as pointed out in the previous posts).

That is my problem. I don't know how to write a joint-child-script that makes it act like a spring-damper although it is in PID-mode.

What I found is this the following code. I guess I would need to read out K and C and set them where it says

Code: Select all

k = 1
forceOrTorqueToApply = k*errorValue/dynStepSize 
and also set respective references to my own objects and joints. I don't see the C-value in the code though.

Code: Select all

-- This example script performs a PID control
-- Be very careful when calling V-REP API functions from here:
-- 1. This routine gets called often, so it might slow down simulation (this is called at each dynamic simulation step, by default 10x more often than a child script)
-- 2. Some API functions are not meant to be called from here

-- Following data is handed over from V-REP: init,revolute,cyclic,jointHandle,passCnt,totalPasses,currentPos,targetPos,errorValue,effort,dynStepSize,lowLimit,highLimit,targetVel,maxForceTorque,velUpperLimit=...

-- init: true when this callback is called for the first time (if the joint is dynamically reset during the simulation, this might be true more often)
-- revolute: true if the joint is revolute
-- cyclic: true if the joint is revolute and cyclic (i.e. no lower/upper limits)
-- passCnt: the current dynamics calculation pass. 0-9 by default. See next item for details.
-- totalPasses: the number of dynamics calculation passes for each "regular" simulation pass. 10 by default (i.e. 10*5ms=50ms which is the default simulation time step)
-- currentPos: the current position of the joint
-- targetPos: the desired position of the joint
-- errorValue: targetPos-currentPos (with revolute cyclic joints we take the shortest cyclic distance)
-- effort: the last force or torque that acted on this joint along/around its axis. With Bullet, torques from joint limits are not taken into account
-- dynStepSize: the step size used for the dynamics calculations (by default 5ms)
-- lowLimit: the joint lower limit
-- highLimit: the joint upper limit
-- targetVel: the joint target velocity (as set in the user interface)
-- maxForceTorque: the joint maximum force/torque (as set in the user interface)
-- velUpperLimit: the joint velocity upper limit (as set in the user interface)

-- The control happens here:
-- 1. PID parameter def:
if not PID_P then
  PID_P=0.1
  PID_I=0
  PID_D=0
end
-- 2. Clear some values when the dynamic joint calls this the first time (this can happen several times, if the joint is reset dynamically):
if init then
  pidCumulativeErrorForIntegralParam=0
    pidLastErrorForDerivativeParam = 0
    pJointPosPrev = 0
    pJoint = simGetObjectHandle("PowerProvider")
    lCuboid = simGetObjectHandle("LightCuboid")
    hCuboid = simGetObjectHandle("HeavyCuboid")
    myConsole = simAuxiliaryConsoleOpen("Debugger", 1000, 7)
end
-- 3. Proportional part:
ctrl=errorValue*PID_P
-- 4. Integral part:
if PID_I~=0 then
  pidCumulativeErrorForIntegralParam=pidCumulativeErrorForIntegralParam+errorValue*dynStepSize
else
  pidCumulativeErrorForIntegralParam=0
end
ctrl=ctrl+pidCumulativeErrorForIntegralParam*PID_I
-- 5. Derivative part:
if not init then
  ctrl=ctrl+(errorValue-pidLastErrorForDerivativeParam)*PID_D/dynStepSize
end
errorDot = errorValue-pidLastErrorForDerivativeParam
pidLastErrorForDerivativeParam=errorValue
-- 6. Calculate the velocity needed to reach the position in one dynamic time step:
maxVelocity=PID_P*errorValue/dynStepSize
if (maxVelocity>velUpperLimit) then
  maxVelocity=velUpperLimit
end
if (maxVelocity<-velUpperLimit) then
  maxVelocity=-velUpperLimit
end
forceOrTorqueToApply=maxForceTorque

-- Somebodies Code start
pJointPos = simGetJointPosition(pJoint)
pJointSpeed = (pJointPos - pJointPosPrev)/dynStepSize
--pJointSpeed = simGetObjectVelocity(pJoint)
pJointPosPrev = pJointPos

hCuboidSpeed = simGetObjectVelocity(hCuboid)
lCuboidSpeed = simGetObjectVelocity(lCuboid)

simAuxiliaryConsolePrint(myConsole, errorDot)
simAuxiliaryConsolePrint(myConsole, ", ")
simAuxiliaryConsolePrint(myConsole, pJointSpeed)
simAuxiliaryConsolePrint(myConsole, "\n")

k = 1
forceOrTorqueToApply = k*errorValue/dynStepSize
-- End of My Code

-- Following data must be returned to V-REP:
return forceOrTorqueToApply,maxVelocity

-- forceOrTorqueToApply: the maximum force/torque that the joint will be able to exert
-- maxVelocity: max. velocity allowed.

streets
Posts: 8
Joined: 18 Dec 2017, 17:25

Re: Enabling spring-damper mode through regular API?

Post by streets » 22 Jan 2018, 14:39

I just found out that even if I was able to write a custom control loop script for the joint, I wouldn't be able to add this script to the joint (only adding of childscripts is allowed) and also I couldn't change from "PID control" to "Custom control" anyway.

I'll try to add the feature myself to the V-Rep source.

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

Re: Enabling spring-damper mode through regular API?

Post by coppelia » 22 Jan 2018, 15:10

Do not try to change the source code yet, since there should be the beta version of next release out this week. And joint control callbacks will still be supported, but in a different way (simpler). Then we can have a look at your problem again.

Cheers

streets
Posts: 8
Joined: 18 Dec 2017, 17:25

Re: Enabling spring-damper mode through regular API?

Post by streets » 22 Jan 2018, 16:54

Thank you again for the quick reply.

Meanwhile I figured some ways to make changes to the source but I didn't actually include and compile it. So I'm happy that I didn't start with that and read your message beforehand.

Since I think I found a quick (and admittedly a little dirty) way to realize the feature, I thought I might still publish this here.

The easiest way for the "spring damper mode by API"-feature might go like this (in v_rep/sourceCode/interfaces/v_rep_internal.cpp):

Code: Select all

//snip
simInt simCreateJoint_internal(simInt jointType,simInt jointMode,simInt options,const simFloat* sizes,const simFloat* colorA,const simFloat* colorB)
{
    C_API_FUNCTION_DEBUG;

    if (!isSimulatorInitialized(__func__))
    {
        return(-1);
    }

    IF_C_API_SIM_OR_UI_THREAD_CAN_WRITE_DATA
    {
        CJoint* it=new CJoint(jointType);
        it->setJointMode(jointMode);
        it->setHybridFunctionality(options&1);
        //-------------------- ADDED
        it->setEnableTorqueModulation(options&2);
	//-------------------- ADDED
        if (sizes!=NULL)
        //snip
This way a call from LUA might look like this:

Code: Select all

local spring_damper_mode = 2
local objectHandle = simCreateJoint(sim_joint_prismatic_subtype, sim_jointmode_force, spring_damper_mode, {}, nil, nil)
The more appropriate way is probably by extending the parameterset by something like sim_jointintparam_ctrlmode and then have a value defining the mode as custom control, PID or spring-damper.

Cheers

streets
Posts: 8
Joined: 18 Dec 2017, 17:25

Re: Enabling spring-damper mode through regular API?

Post by streets » 29 Jan 2018, 14:39

Hi,

I installed the new beta but I'm not sure how I could handle the issue with the new version. I would need some pointers to see what I need to do in order to create spring-damper joints from lua code.

cheers

Post Reply