Inline slider crank modeling

Hi, I am trying to model a simple inline slider crank mechanism using AnyScript. I am quite new at this.

According to my understanding, I need four segments (24 DOFs), three Revolute Joints and a prismatic joints.

Here is my joint mechanisms:
joint 1: A revolute joint between the origin and one end of the crank.
joint 2: A revolute joint between crank tip and connecting rod end.
joint 3: A revolute joint between connecting rod and the slider segment
joint 4: A prismatic joint between slider and the base segment.

The driver for joint 1 has a rotational velocity. Drivers for all other joints have velocity 0.

If I do this, the system does not work as intended.

If I try to fix the base by introducing another joint between the origin and the left end of the base, then the system shows over-constrained.

Please let me know where I am going wrong and the correct solution. I am attaching the bad code for convenience.


 
Main = {
  
  AnyFolder MyModel = {
    
    // Global Reference Frame
    AnyFixedRefFrame GlobalRef = {
      /*AnyRefNode leftjnt ={
        AnyDrawNode drawnode ={
          ScaleXYZ = {0.09,0.09,0.9};
          RGB = {1,0,0};
        };
      };*/ 
      /*
      AnyRefNode groundjnt ={
        sRel = {8.5,0,0};
        AnyDrawNode drawnode ={
          ScaleXYZ = {0.09,0.09,0.9};
          
          RGB = {1,0,0};
        };
      };*/ 
      
      AnyDrawRefFrame DrwGlobalRef = { 
        RGB={1,0,0}; 
        ScaleXYZ={3,0,0}; 
      };
      
      
    }; //Global Ref Frame
    
    
    //******************************//
    //--------- Segment-1 ---------//
    //****************************//
    
    AnyFolder Segment = {
      
      AnySeg Segment1 = { 
        r0 = {1.5,0,0};
        Mass = 10;
        Jii = {0.1,5,5};
        AnyRefNode Left1 = {
          sRel = {-1.5,0,0};
        };
        AnyRefNode Right1 = {
          sRel = {1.5,0,0};
        };
        AnyDrawSeg drwSegment1 = {
          Opacity = 0.4;
        };
      }; //Segment1
      
      AnySeg Segment2 ={
        Mass = 10;
        Jii = {0.1,10,10};
        r0 = {6, 0,0}; 
        AnyRefNode Right2 = {
          sRel = {2.5, 0.0, 0};
        };
        AnyRefNode Left2 = {
          sRel = {-2.5, 0.0, 0};
        };
        AnyDrawSeg Seg2 = {
          Opacity= 0.4;
        }; 
      }; // Segment2
      
      AnySeg Segment3 ={
        Mass = 10;
        Jii = {0.2,12,12};
        r0={8,0,0};
        
        AnyDrawSeg Seg3 = {
          Opacity= 0.4;
        }; 
        
      };
      
      AnySeg Segment4 ={
        Mass = 10;
        Jii = {0.1,0.1,0.1};
        r0={9,0,0};
        
        AnyDrawSeg Seg4 = {
          Opacity= 0.4;
        }; 
        
      };
      
    }; //Segment Folder
    
    
    //**************************//
    //----------Joint----------//
    //*************************//
    
    AnyFolder Joint ={
      AnyRevoluteJoint Leftjnt = {
        Axis = z;
        AnyFixedRefFrame& Ground =Main.MyModel.GlobalRef;
        AnyRefNode &LeftNode = Main.MyModel.Segment.Segment1.Left1;
        
      };
      
      AnyRevoluteJoint jnt3 = {
        Axis = z;
        AnyFixedRefFrame& Ground =Main.MyModel.GlobalRef;
        AnySeg &LeftNode = Main.MyModel.Segment.Segment3;
        
      };
      
      
      
      
      AnyRevoluteJoint Middlejnt = {
        
        Axis = x;
        //Axis2 = z;
        AnyRefNode &MiddleNode1 = Main.MyModel.Segment.Segment1.Right1;
        AnyRefNode &MiddleNode2 = Main.MyModel.Segment.Segment2.Left2;
      };
      
      AnyRevoluteJoint secondRev = {
        Axis =z;
        AnySeg &seg4=Main.MyModel.Segment.Segment4;
        AnyRefNode &node=Main.MyModel.Segment.Segment2.Right2;
      };
      
      AnyPrismaticJoint sliderjnt = {
        
        Axis = x;
        AnyRefNode &MiddleNode1 = Main.MyModel.Segment.Segment2.Right2;
        AnySeg &MiddleNode2 = Main.MyModel.Segment.Segment3;
      };
      
      
      //      
    };// Joint
    
    
    //----------Drivers----------//
    
    AnyFolder Drivers = {
      AnyKinEqSimpleDriver SimpleDriver = {
        AnyRevoluteJoint &Jnt =Main.MyModel.Joint.Leftjnt ;
        DriverPos = {30*pi/180};
        DriverVel = {360*pi/180};
        Reaction.Type = {Off};
      };
      
      AnyKinEqSimpleDriver SimpleDriver2 = {
        AnyRevoluteJoint &Jnt2 =Main.MyModel.Joint.Middlejnt ;
        DriverPos = {0}; // Because 2 degree of Freedom
        DriverVel = {0};
        
        Reaction.Type = {Off};
      };
      
      /*
      AnyKinEqSimpleDriver SimpleDriver3 = {
        AnyRevoluteJoint &Jnt =Main.MyModel.Joint.jnt3 ;
        DriverPos = {0};
        DriverVel = {0};
        Reaction.Type = {Off};        
      };*/
      
      AnyKinEqSimpleDriver SimpleDriver4 = {
        AnyRevoluteJoint &Jnt2 =Main.MyModel.Joint.secondRev ;
        DriverPos = {0}; // Because 2 degree of Freedom
        DriverVel = {0};
        
        Reaction.Type = {Off};
      };
      
      AnyKinEqSimpleDriver SimpleDriver5 = {
        AnyPrismaticJoint &Jnt2 =Main.MyModel.Joint.sliderjnt ;
        DriverPos = {0}; // Because 2 degree of Freedom
        DriverVel = {0};
        
        Reaction.Type = {Off};
      };
      
      
    }; // Drivers Folder
    
    
    //---------Kninematics---------//
    
    
    
    
  };// My Model Folder
  
  //----------ModelStudy----------//
  
  AnyBodyStudy ModelStudy = {
    AnyFolder& Model = Main.MyModel;
    Gravity = {0.0, -9.81, 0.0};
    AnyKinEqSimpleDriver& Driver = Main.MyModel.Drivers.SimpleDriver;
    AnyKinEqSimpleDriver& Driver2 = Main.MyModel.Drivers.SimpleDriver2;
    //AnyKinEqSimpleDriver& Driver3 = Main.MyModel.Drivers.SimpleDriver3;
    AnyKinEqSimpleDriver& Driver4 = Main.MyModel.Drivers.SimpleDriver4;
    AnyKinEqSimpleDriver& Driver5 = Main.MyModel.Drivers.SimpleDriver5;
    



    
    InverseDynamics.Criterion.Type = MR_MinMaxStrict;
  }; // ModelStudy
  
}; // Main

Hi Dibyayan,

Welcome to the AnyScript forum!

Technically, you need 3 segments to make the slider crank mechanism. The fourth segment, base, can simply be the Global Reference Frame, or what you call as origin.

From your explanation and code, it seems like you're running into an issue with the degree of freedom (DOF) constraints. Here's a breakdown of the problem and the solution:

The Mechanical System:

You are trying to model a slider-crank mechanism with the following joints:

  • Joint 1: Revolute joint between the base (origin) and the crank.
  • Joint 2: Revolute joint between the crank and the connecting rod.
  • Joint 3: Revolute joint between the connecting rod and the slider.
  • Joint 4: Prismatic joint between the slider and the ground (allowing motion along a line).

DOF Analysis:

  • The crank has 1 DOF (rotational).
  • The connecting rod only rotates, constrained by two revolute joints, so no additional DOF (essentially becomes a rigid link).
  • The slider is constrained to move along a line (prismatic joint), so 1 translational DOF.

For a system with 4 segments (including the base, crank, rod, and slider) and 24 DOF (6 per segment), the number of constraints must be carefully managed. The base can simply be the GlobalRef, so you don't really need another segment for the base. The system will have 3 revolute joints (each removing 5 DOFs) and 1 prismatic joint (removing 5 DOFs). This should reduce the total DOFs appropriately.

Issues in the Code:

  1. Over-Constraining: You mentioned fixing the base by introducing another joint between the origin and the left end of the base. This introduces an additional constraint, over-constraining the system. In the default setup, the base is already fixed by default via the global reference frame, so there's no need to add another joint.
  2. Incorrect Joint Drivers: You are applying drivers (velocities/positions) to all joints, but in fact, only joint 1 (crank rotation) should have a driver (with rotational velocity). The remaining joints are naturally constrained by the kinematics of the system and shouldn't be driven directly.

Correcting the Model:

  1. Fix the Base Segment: The base is already defined by AnyFixedRefFrame GlobalRef, so no additional joint between the origin and base is required.
  2. Only Apply Driver to Joint 1: The rotational velocity driver should be applied to the revolute joint between the ground and the crank.
  3. Remove Unnecessary Drivers: Remove or modify the drivers for the other joints so that they allow the system to be constrained naturally.

Here's a corrected version of your model:

Main = {
  
  AnyFolder MyModel = {
    
    // Global Reference Frame
    AnyFixedRefFrame GlobalRef = {
      AnyDrawRefFrame DrwGlobalRef = { 
        RGB={1,0,0}; 
        ScaleXYZ={3,0,0}; 
      };
    }; 
    
    //******************************//
    //--------- Segments -----------//
    //******************************//
    
    AnyFolder Segments = {
      
      AnySeg Crank = { 
        r0 = {1.5, 0, 0}; // Position of Crank
        Mass = 10;
        Jii = {0.1, 5, 5};
        AnyRefNode Left = {
          sRel = {-1.5, 0, 0}; // Position of Left node of Crank
        };
        AnyRefNode Right = {
          sRel = {1.5, 0, 0}; // Position of Right node of Crank
        };
        AnyDrawSeg drwCrank = {
          Opacity = 0.4;
        };
      };
      
      AnySeg ConnectingRod = {
        Mass = 10;
        Jii = {0.1, 10, 10};
        r0 = {6, 0, 0}; // Position of Connecting Rod
        AnyRefNode Right = {
          sRel = {2.5, 0.0, 0};
        };
        AnyRefNode Left = {
          sRel = {-2.5, 0.0, 0};
        };
        AnyDrawSeg drwRod = {
          Opacity= 0.4;
        };
      };
      
      AnySeg Slider = {
        Mass = 10;
        Jii = {0.1, 0.1, 0.1};
        r0 = {9, 0, 0}; // Position of Slider
        AnyDrawSeg drwSlider = {
          Opacity = 0.4;
        };
      };
      
    }; // Segments Folder
    
    
    //**************************//
    //---------- Joints --------//
    //**************************//
    
    AnyFolder Joints = {
      
      // Revolute joint between Ground and Crank (Joint 1)
      AnyRevoluteJoint CrankGroundJoint = {
        Axis = z;
        AnyFixedRefFrame& Ground = Main.MyModel.GlobalRef;
        AnyRefNode &CrankNode = Main.MyModel.Segments.Crank.Left;
      };
      
      // Revolute joint between Crank and Connecting Rod (Joint 2)
      AnyRevoluteJoint CrankRodJoint = {
        Axis = z;
        AnyRefNode &CrankRightNode = Main.MyModel.Segments.Crank.Right;
        AnyRefNode &RodLeftNode = Main.MyModel.Segments.ConnectingRod.Left;
      };
      
      // Revolute joint between Connecting Rod and Slider (Joint 3)
      AnyRevoluteJoint RodSliderJoint = {
        Axis = z;
        AnyRefNode &RodRightNode = Main.MyModel.Segments.ConnectingRod.Right;
        AnySeg &Slider = Main.MyModel.Segments.Slider;
      };
      
      // Prismatic joint between Slider and Ground (Joint 4)
      AnyPrismaticJoint SliderGroundJoint = {
        Axis = x;
        AnySeg &Slider = Main.MyModel.Segments.Slider;
        AnyFixedRefFrame &Ground = Main.MyModel.GlobalRef;
      };
      
    }; // Joints Folder
    
    
    //*************************//
    //-------- Drivers --------//
    //*************************//
    
    AnyFolder Drivers = {
      
      // Driver for Joint 1 (Crank Rotation)
      AnyKinEqSimpleDriver CrankRotationDriver = {
        AnyRevoluteJoint &Jnt = Main.MyModel.Joints.CrankGroundJoint;
        DriverPos = {30 * pi / 180}; // Initial position in radians
        DriverVel = {360 * pi / 180}; // Rotational velocity in radians/second
        Reaction.Type = {Off}; // No reaction force
      };
      
    }; // Drivers Folder
    
  }; // MyModel Folder
  
  
  //*************************//
  //------- Study Setup ------//
  //*************************//
  
  AnyBodyStudy ModelStudy = {
    AnyFolder& Model = Main.MyModel;
    Gravity = {0.0, -9.81, 0.0};
    
    // Only one driver is needed for the crank.
    // AnyKinEqSimpleDriver& CrankDriver = Main.MyModel.Drivers.CrankRotationDriver;
   // It is commented out as it is already included through the model folder.
    
    InverseDynamics.Criterion.Type = MR_MinMaxStrict;
  };
  
}; // Main

Key Changes:

  1. Removed Extra Joint on Base: No need for the joint between the base and the left end of the base.
  2. Drivers: Applied only to the crank (joint 1), no need to apply drivers for the other joints since their motion is constrained naturally by the system.
  3. Defined All Four Joints: Each joint is set up correctly.

Result:

This should fix your over-constrained problem and allow your model to run properly. The crank will rotate with the specified velocity, driving the rest of the mechanism through the joints.

Best regards,
Dave

1 Like

Thank you very much Divyaksh. Your solution worked like a charm.

1 Like