4.8.2.12. SCREW_FORCE

This subroutine generates a user- defined screw force.

Table 4.35 Function Name

Language type

Subroutine

FORTRAN

screw_force (TIME, UPAR, NPAR, JFLAG, IFLAG, RESULT)

C/C++

screw_force (double time, double upar[], int npar, int jflag, int iflag, double result[6])

Table 4.36 Parameter information

Variable Name

Size

Description

time

double

Current simulation time of RecurDyn/Solver.

upar

double[100]

Parameters defined by the user. The maximum size of array is 100.

npar

int

Number of user parameters.

jflag

int

When RecurDyn/Solver evaluates the Jacobian, the flag is true. Otherwise, the flag is false.

iflag

int

When RecurDyn/Solver makes its initial call to this routine, the flag is true. Otherwise, the flag is false.

result

double[6]

Returned force vector and six-dimensional array.

Example

This subroutine returns forces to a wheel for standing on the ground, as shown in Figure 4.116.

../_images/image328.gif

Figure 4.116 Wheels and Screw forces

Note

If the user wants to run this model using a user subroutine, the user can refer it in the directory (<install dir>\Help\usub\**).

Listing 4.23 Fortran code for Screw Force
 C---- SUB. SCREW_FORCE
       SUBROUTINE SCREW_FORCE
     &          (TIME,UPAR,NPAR,JFLAG,IFLAG,RESULT)
 C---- TO EXPORT * SUBROUTINE
       !DEC$ ATTRIBUTES DLLEXPORT,C::SCREW_FORCE

 C---- INCLUDE SYSTEM CALL
       INCLUDE 'SYSCAL.F'

 C---- DEFINE VARIABLES
 C     Parameter Information
 C     TIME   : Simulation time of RD/Solver. (Input)
 C     UPAR   : Parameters defined by user. (Input)
 C     NPAR   : Number of user parameters. (Input)
 C     JFLAG  : When RD/Solver evaluates a Jacobian, the flag is true. (Input)
 C     IFLAG  : When RD/Solver initializes arrays, the flag is true. (Input)
 C     RESULT : Returned screw force vector. (Output, Size : 6)

       DOUBLE PRECISION TIME, UPAR(*)
       INTEGER NPAR
       LOGICAL JFLAG, IFLAG
       DOUBLE PRECISION RESULT[REFERENCE](6)

 C---- USER STATEMENT
 C---- USER DECLARED VARIABLES
       INTEGER MKID(2)
       DOUBLE PRECISION VALUE1, VALUE2, FORCE, ISIGN, L, MU, K, C
       LOGICAL ERRFLG

       L = 200.0D0
       MU = 0.3D0
       K = 1000.0D0
       C = 10.0D0

 C--- COMPUTE A NORMAL FORCE
 C---- AFTER CASTING DOUBLE PRECISION TYPE ‘UPAR’INTO INTEGER TYPE ‘MKID’
 C---- ASSIGNS ‘UPAR(1), (3)’INTO 'MKID(1),(2)'.
       MKID(1) = INT(UPAR(1))
       MKID(2) = INT(UPAR(3))

 C---- BY CALLING ‘SYSFNC’, USER CAN OBTAIN 'VALUE1' WHICH MEANS 'DY'.
       CALL SYSFNC('DY',MKID,2,VALUE1,ERRFLG)

 C---- LIKEWISE, USER CAN OBTAIN 'VALUE2' WHICH MEANS 'VY'.
       CALL SYSFNC('VY',MKID,2,VALUE2,ERRFLG)

 C---- WHEN THE WHEEL PENETRATES INTO THE GROUND, THE ‘RESULT(2)’WHICH MEANS ‘FY’HAS A VALUE.
       RESULT(2) = -K*(VALUE1-L) - C*VALUE2
       IF ( RESULT(2) .LE. 0.0D0 ) RESULT(2) = 0.0D0

 C--- COMPUTE A FRICTION FORCE
       CALL SYSFNC('VX',MKID,2,VALUE1,ERRFLG)
       CALL SYSFNC('WZ',MKID,2,VALUE2,ERRFLG)

       IF ( VALUE1+VALUE2*L .LT. -0.01D0 ) THEN
         ISIGN = -1.0D0
       ELSE IF ( VALUE1+VALUE2*L .GT. 0.01D0 ) THEN
         ISIGN = 1.0D0
       ELSE
         ISIGN = 0.0D0
       ENDIF

       MKID(1) = INT(UPAR(1))
       MKID(2) = INT(UPAR(2))

       CALL SYSFNC('FY',MKID,2,FORCE,ERRFLG)
       RESULT(1) = -MU*DABS(FORCE)*ISIGN

 C---- COMPUTE A TORQUE GENERATED BY THE FRICTION FORCE
       CALL SYSFNC('FX',MKID,2,FORCE,ERRFLG)
       RESULT(6) = L*DABS(FORCE)

       RETURN
       END
Listing 4.24 C/C++ code for Screw Force
 #include "stdafx.h"
 #include "DllFunc.h"
 #include "math.h"

 ScrewForce_API void __cdecl screw_force
   (double time, double upar[], int npar, int jflag, int iflag, double result[6])
 {
   using namespace rd_syscall;
   // Parameter Information
   //   time   : Simulation time of RD/Solver. (Input)
   //   upar   : Parameters defined by user. (Input)
   //   npar   : Number of user parameters. (Input)
   //   jflag  : When RD/Solver evaluates a Jacobian, the flag is true. (Input)
   //   iflag  : When RD/Solver initializes arrays, the flag is true. (Input)
   //   result : Returned screw force vector. (Output, Size : 6)

   // User Statement
   // SER DECLARED VARIABLES
   int mkid[2];
   double value1, value2, force, isign, l, mu, k, c;
   int errflg;

   l = 200.0;
   mu = 0.3;
   k = 1000.0;
   c = 10.0;

   // OMPUTE A NORMAL FORCE
   // FTER CASTING DOUBLE PRECISION TYPE ‘UPAR’INTO INTEGER TYPE ‘MKID’
   // SSIGNS ‘UPAR[0], [2]’INTO 'MKID[0],[1]'.
   mkid[0] = (int) upar[0];
   mkid[1] = (int) upar[2];

   // Y CALLING ‘SYSFNC’, USER CAN OBTAIN 'VALUE1' WHICH MEANS 'DY'.
   sysfnc("DY",mkid,2,&value1,&errflg);

   // IKEWISE, USER CAN OBTAIN 'VALUE2' WHICH MEANS 'VY'.
   sysfnc("VY",mkid,2,&value2,&errflg);

   // HEN THE WHEEL PENETRATES INTO THE GROUND, THE ‘RESULT(2)’WHICH MEANS ‘FY’HAS A VALUE.
   result[1] = -k*(value1-l) - c*value2;
   if ( result[1] <= 0.0 ) result[1] = 0.0;

   // OMPUTE A FRICTION FORCE
   sysfnc("VX",mkid,2,&value1,&errflg);
   sysfnc("WZ",mkid,2,&value2,&errflg);

   if ( value1+value2*l < -0.01 ) {
     isign = -1.0;
   }
   else if ( value1+value2*l > 0.01 ) {
     isign = 1.0;
   }
   else {
   isign = 0.0;
   }

   mkid[0] = (int) upar[0];
   mkid[1] = (int) upar[1];

   sysfnc("FY",mkid,2,&force,&errflg);
   result[0] = -mu*fabs(force)*isign;

   // OMPUTE A TORQUE GENERATED BY THE FRICTION FORCE
   sysfnc("FX",mkid,2,&force,&errflg);
   result[5] = l*fabs(force);
 }