# yade-users team mailing list archive

## [Question #705953]: Problems with using the ServoPIDController() function

```New question #705953 on Yade:

Hello everyone,

I am writing to seek help with using the Yade from source code on Ubuntu 22.04. The source code was downloaded on February 23, 2023.The ServoPIDController() function was used in my code as follows: ServoPIDController(axis=[0,0,1],maxVelocity=2.0,iterPeriod=50,ids=[10],target=12000,kP=0.1,kI=1.0,kD=0.25).But the following two problems arise in my use of this function:
1. When the force on the plate with id [10] is close to the target value 12000, the velocity value of the plate still remains at maxVelocity.In other words, there is no decrease in speed as the force on this plate approaches the target value. Could you please explain the reason for this situation?
2.If I want to set the target in the ServoPIDController() function to be a sine function of time, how do I set the target?
The related code for this model is as follows：

***********************************************************************************
import numpy
from pprint import pprint
import random
from random import uniform
from random import randint
from math import *

matP = PolyhedraMat() #the material of wall
matP.density = 2800 #kg/m^3
matP.young = 5.5E8 #10 time biger
matP.poisson = 0.23
matP.fionAngle = 0.65
O.materials.append(matP)

steel = PolyhedraMat() #the material of plate
steel.density = 7850 #kg/m^3  in order to ignore the gravity of plate, according to the parameter in dez
steel.young = 1E9    #inital steel was ,try
steel.poisson = 0.21
O.materials.append(steel)

O.bodies[0].state.blockedDOFs='xyzXYZ'
O.bodies[1].state.blockedDOFs='xyzXYZ'
O.bodies[2].state.blockedDOFs='xyzXYZ'
O.bodies[3].state.blockedDOFs='xyzXYZ'
O.bodies[10].state.blockedDOFs='xyzXYZ'
O.bodies[4].state.blockedDOFs='xyzXYZ'
O.bodies[5].state.blockedDOFs='xyzXYZ'
O.bodies[6].state.blockedDOFs='xyzXYZ'
O.bodies[7].state.blockedDOFs='xyzXYZ'
O.bodies[8].state.blockedDOFs='xyzXYZ'
O.bodies[9].state.blockedDOFs='xyzXYZ'

O.engines=[
ForceResetter(),
InsertionSortCollider([Bo1_Polyhedra_Aabb(),Bo1_Wall_Aabb(),Bo1_Facet_Aabb(),Bo1_Sphere_Aabb()],verletDist=.000005),
InteractionLoop(
[Ig2_Wall_Polyhedra_PolyhedraGeom(),Ig2_Polyhedra_Polyhedra_PolyhedraGeom(),Ig2_Facet_Polyhedra_PolyhedraGeom(),Ig2_Sphere_Sphere_ScGeom(),Ig2_Sphere_Polyhedra_ScGeom(),Ig2_Facet_Sphere_ScGeom(),Ig2_Wall_Sphere_ScGeom()],
[Ip2_PolyhedraMat_PolyhedraMat_PolyhedraPhys(),Ip2_FrictMat_PolyhedraMat_FrictPhys(),Ip2_FrictMat_FrictMat_FrictPhys()],
[Law2_PolyhedraGeom_PolyhedraPhys_Volumetric(),Law2_ScGeom_FrictPhys_CundallStrack()]),
NewtonIntegrator(damping=0.3,gravity=(0,0,-9.81)),
ServoPIDController(axis=[0,0,1],maxVelocity=0.1,iterPeriod=50,ids=[10],target=12000,kP=0.1,kI=1.0,kD=0.25),#‘target’ is the target force for the top plate  the name of the top plate is idStone.
PyRunner(command='cycle()',iterPeriod=100,label='step'),
PyRunner(command='direct_cut()',iterPeriod=1,label='compact'),
PyRunner(command='save()',iterPeriod=500,label='save'),
PyRunner(command='savesave()',iterPeriod=2000,label='save')
]

def cycle():
for b in O.bodies:
if isinstance(b.shape,Polyhedra):
if b.state.pos[0] < -10 or b.state.pos[0] >10:
O.bodies.erase(b.id)
elif b.state.pos[1] <-10 or b.state.pos[1] > 10:
O.bodies.erase(b.id)
elif b.state.pos[2] < -0.15 or b.state.pos[2] > 0.85:
O.bodies.erase(b.id)
else:
pass

global StepNum
StepNum=1

def direct_cut():
global StepNum
topp=10#id of top plate
downle=1#id of left down plate
if StepNum ==1:
O.bodies[0].state.blockedDOFs='xyzXYZ'
O.bodies[1].state.blockedDOFs='xyzXYZ'
O.bodies[2].state.blockedDOFs='xyzXYZ'
O.bodies[3].state.blockedDOFs='xyzXYZ'
O.bodies[topp].state.blockedDOFs='xyzXYZ'
O.bodies[4].state.blockedDOFs='xyzXYZ'
O.bodies[5].state.blockedDOFs='xyzXYZ'
O.bodies[6].state.blockedDOFs='xyzXYZ'
O.bodies[7].state.blockedDOFs='xyzXYZ'
O.bodies[8].state.blockedDOFs='xyzXYZ'
O.bodies[9].state.blockedDOFs='xyzXYZ'#
plateF=O.forces.f(topp)[2]
print("Servo")
if plateF<11000 or plateF>13000:return
StepNum=StepNum+1
if StepNum ==2:
plateF=O.forces.f(topp)[2]
print("Plate forces = %.5f"%(plateF))
if O.bodies[downle].state.pos[1] < 0.02:
O.bodies[0].state.vel=(0,0.02,0)
O.bodies[1].state.vel=(0,0.02,0)
O.bodies[2].state.vel=(0,0.02,0)
O.bodies[3].state.vel=(0,0.02,0)
O.bodies[4].state.vel=(0,0.02,0)
O.bodies[5].state.vel=(0,0.02,0)
O.bodies[0].state.blockedDOFs='xyzXYZ'
O.bodies[1].state.blockedDOFs='xyzXYZ'
O.bodies[2].state.blockedDOFs='xyzXYZ'
O.bodies[3].state.blockedDOFs='xyzXYZ'
O.bodies[topp].state.blockedDOFs='xyzXYZ'
O.bodies[4].state.blockedDOFs='xyzXYZ'
O.bodies[5].state.blockedDOFs='xyzXYZ'
O.bodies[6].state.blockedDOFs='xyzXYZ'
O.bodies[7].state.blockedDOFs='xyzXYZ'
O.bodies[8].state.blockedDOFs='xyzXYZ'
O.bodies[9].state.blockedDOFs='xyzXYZ'#
else:
O.pause()
***********************************************************************************