← Back to team overview

yade-users team mailing list archive

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

 

New question #705953 on Yade:
https://answers.launchpad.net/yade/+question/705953

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:

***********************************************************************************
from yade import pack,qt,plot,utils,polyhedra_utils,ymport,export,pack,timing
from yade import *
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
steel.frictionAngle = 0.5 #rad
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()
***********************************************************************************

Please help me to solve the above mentioned problem.
Thanks in advance,
Regards,
Wang



-- 
You received this question notification because your team yade-users is
an answer contact for Yade.