0
$\begingroup$

I created several constraints (6DoF) with the following script:

import PhysicsConstraints as constr
import GameLogic
scene = GameLogic.getCurrentScene()
objList = scene.objects

stiffness = 500
MaxAngleLimit = 0.2
MinAngleLimit = -0.2
steer = objList['FrontAxisGhost']['steer']

CarBodyID = objList["CarBody"].getPhysicsId()
CarCenterID = objList["CarCenter"].getPhysicsId()
FrontAxisID = objList["FrontAxisGhost"].getPhysicsId()
RearAxisID = objList["RearAxisGhost"].getPhysicsId()
FRAxleID = objList["AxleFR"].getPhysicsId()
FLAxleID = objList["AxleFL"].getPhysicsId()
RRAxleID = objList["AxleRR"].getPhysicsId()
RLAxleID = objList["AxleRL"].getPhysicsId()
SteerLID = objList["SteerL"].getPhysicsId()
SteerRID = objList["SteerR"].getPhysicsId()
WheelFLID = objList["WheelFL"].getPhysicsId()
WheelFRID = objList["WheelFR"].getPhysicsId()

CarBody6DoF = constr.createConstraint(CarBodyID,
CarCenterID, 12, 0, 0, 0, 0, 0, 0, 0)
CarBody6DoF.setParam(3, 0.0, 0.0)
CarBody6DoF.setParam(4, 0.0, 0.0)
CarBody6DoF.setParam(5, 0.0, 0.0)

FAxis6DoF = constr.createConstraint(FrontAxisID,
CarCenterID, 12, 0, 0, 0, 0, 0, 0, 0)
FAxis6DoF.setParam(3, 0.0, 0.0)
FAxis6DoF.setParam(4, 0.0, 0.0)
FAxis6DoF.setParam(5, 0.0, 0.0)

RAxis6DoF = constr.createConstraint(RearAxisID,
CarCenterID, 12, 0, 0, 0, 0, 0, 0, 0)
RAxis6DoF.setParam(3, 0.0, 0.0)
RAxis6DoF.setParam(4, 0.0, 0.0)
RAxis6DoF.setParam(5, 0.0, 0.0)

FR_6DoF = constr.createConstraint(FRAxleID,
FrontAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
FR_6DoF.setParam(3, 0.0, 0.0)
FR_6DoF.setParam(4, 0.0, 0.0)
FR_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
FR_6DoF.setParam(15, stiffness, 1)

FL_6DoF = constr.createConstraint(FLAxleID,
FrontAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
FL_6DoF.setParam(3, 0.0, 0.0)
FL_6DoF.setParam(4, 0.0, 0.0)
FL_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
FL_6DoF.setParam(15, stiffness, 1)

RR_6DoF = constr.createConstraint(RRAxleID,
RearAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
RR_6DoF.setParam(3, 0.0, 0.0)
RR_6DoF.setParam(4, 0.0, 0.0)
RR_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
RR_6DoF.setParam(15, stiffness, 1)

RL_6DoF = constr.createConstraint(RLAxleID,
RearAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
RL_6DoF.setParam(3, 0.0, 0.0)
RL_6DoF.setParam(4, 0.0, 0.0)
RL_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
RL_6DoF.setParam(15, stiffness, 1)

SteerFL_6DoF = constr.createConstraint(SteerLID,
FLAxleID, 12, 0, 0, 0, 0, 0, 0, 0)
SteerFL_6DoF.setParam(3, 0, 0)
SteerFL_6DoF.setParam(4, 0, 0)
SteerFL_6DoF.setParam(5, 0, 0)

SteerFR_6DoF = constr.createConstraint(SteerRID,
FLAxleID, 12, 0, 0, 0, 0, 0, 0, 0)
SteerFR_6DoF.setParam(3, 0, 0)
SteerFR_6DoF.setParam(4, 0, 0)
SteerFR_6DoF.setParam(5, 0, 0)

WheelFL_6DoF = constr.createConstraint(WheelFLID,
SteerLID, 12, 0, 0, 0, 0, 0, 0, 0)
WheelFL_6DoF.setParam(4, 0.0, 0.0)
WheelFL_6DoF.setParam(5, 0, 0)

WheelFR_6DoF = constr.createConstraint(WheelFRID,
SteerRID, 12, 0, 0, 0, 0, 0, 0, 0)
WheelFR_6DoF.setParam(4, 0, 0)
WheelFR_6DoF.setParam(5, 0, 0)

So the car body, front and rear axes are attached to the car center, front, rear, right, left axles are attached to the axes, two steering dummies are attached to the front axles and wheels themselves are attached to the steering dummies. Everything is fine and dandy so far.

However, now I want the front wheels to steer according to some action. I set up some logic bricks so that I have a property called steer that always decreases to the zero if nothing is pressed and if either A or left arrow is pressed it decreases down to some negative threshold value and if either D or right arrow is pressed it increases to the same positive threshold value.

I take that steer value from the front dummy object with steer = objList['FrontAxisGhost']['steer']. However when I change the following:

SteerL_6DoF = constr.createConstraint(SteerLID,
FLAxleID, 12, 0, 0, 0, 0, 0, 0, 0)
SteerL_6DoF.setParam(3, 0, 0)
SteerL_6DoF.setParam(4, 0, 0)
SteerL_6DoF.setParam(5, steer, steer)

SteerR_6DoF = constr.createConstraint(SteerRID,
FLAxleID, 12, 0, 0, 0, 0, 0, 0, 0)
SteerR_6DoF.setParam(3, 0, 0)
SteerR_6DoF.setParam(4, 0, 0)
SteerR_6DoF.setParam(5, steer, steer)

two things happen:

1) the steering is buggy. Although the property returns to zero after I let go off the key (I can see that in debug), the dummy continues to turn and the vehicle starts to jerk (this doesn't happen when I don't include that steer thing).

2) the whole game starts to lag until the framerate is really low.

I think that there is the same cause to the both bugs: every time the property steer changes the script is executed again. I think this means the script creates numerous constraints which cumulate up to the point the game starts to lag. Of course, it is then logical that once there is numerous constraints with various values of "steer", they would somehow collide and produce unsatisfactory results.

I have a basic idea how to relieve this: when steer property is changed, it would be better to destroy all constraints and recreate them with an updated value of steer. This could be a little jerky and wasteful (no need to destroy and recreate all the constraints).

What would be even better is to create a separate script which would only update already existing constraint (SteerL -> AxleFL and SteerR -> AxleFR) and attach this new script to the change sensor of the property steer.

My question is: how to do this? The separate script doesn't recognize SteerL_6DoF and SteerR_6DoF constraint and I don't know how to retrieve an existing constraint from an object.

$\endgroup$

1 Answer 1

1
$\begingroup$

Save the contrain in an attribute of bge.logic (blender v2.79) module makes it persistent. I change import GameLogic to from bge import logic to give it a try but get lazy when adding objects... so is untested.

import PhysicsConstraints as constr
from bge import logic
scene = logic.getCurrentScene()
objList = scene.objects

stiffness = 500
MaxAngleLimit = 0.2
MinAngleLimit = -0.2
steer = objList['FrontAxisGhost']['steer']

CarBodyID = objList["CarBody"].getPhysicsId()
CarCenterID = objList["CarCenter"].getPhysicsId()
FrontAxisID = objList["FrontAxisGhost"].getPhysicsId()
RearAxisID = objList["RearAxisGhost"].getPhysicsId()
FRAxleID = objList["AxleFR"].getPhysicsId()
FLAxleID = objList["AxleFL"].getPhysicsId()
RRAxleID = objList["AxleRR"].getPhysicsId()
RLAxleID = objList["AxleRL"].getPhysicsId()
SteerLID = objList["SteerL"].getPhysicsId()
SteerRID = objList["SteerR"].getPhysicsId()
WheelFLID = objList["WheelFL"].getPhysicsId()
WheelFRID = objList["WheelFR"].getPhysicsId()
if not hasattr(logic, 'CarBody6DoF')
    logic.CarBody6DoF = constr.createConstraint(CarBodyID,
    CarCenterID, 12, 0, 0, 0, 0, 0, 0, 0)
    logic.CarBody6DoF.setParam(3, 0.0, 0.0)
    logic.CarBody6DoF.setParam(4, 0.0, 0.0)
    logic.CarBody6DoF.setParam(5, 0.0, 0.0)

    logic.FAxis6DoF = constr.createConstraint(FrontAxisID,
    CarCenterID, 12, 0, 0, 0, 0, 0, 0, 0)
    logic.FAxis6DoF.setParam(3, 0.0, 0.0)
    logic.FAxis6DoF.setParam(4, 0.0, 0.0)
    logic.FAxis6DoF.setParam(5, 0.0, 0.0)

    logic.RAxis6DoF = constr.createConstraint(RearAxisID,
    CarCenterID, 12, 0, 0, 0, 0, 0, 0, 0)
    logic.RAxis6DoF.setParam(3, 0.0, 0.0)
    logic.RAxis6DoF.setParam(4, 0.0, 0.0)
    logic.RAxis6DoF.setParam(5, 0.0, 0.0)

    logic.FR_6DoF = constr.createConstraint(FRAxleID,
    FrontAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
    logic.FR_6DoF.setParam(3, 0.0, 0.0)
    logic.FR_6DoF.setParam(4, 0.0, 0.0)
    logic.FR_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
    logic.FR_6DoF.setParam(15, stiffness, 1)

    logic.FL_6DoF = constr.createConstraint(FLAxleID,
    FrontAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
    logic.FL_6DoF.setParam(3, 0.0, 0.0)
    logic.FL_6DoF.setParam(4, 0.0, 0.0)
    logic.FL_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
    logic.FL_6DoF.setParam(15, stiffness, 1)

    logic.RR_6DoF = constr.createConstraint(RRAxleID,
    RearAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
    logic.RR_6DoF.setParam(3, 0.0, 0.0)
    logic.RR_6DoF.setParam(4, 0.0, 0.0)
    logic.RR_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
    logic.RR_6DoF.setParam(15, stiffness, 1)

    logic.RL_6DoF = constr.createConstraint(RLAxleID,
    RearAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
    logic.RL_6DoF.setParam(3, 0.0, 0.0)
    logic.RL_6DoF.setParam(4, 0.0, 0.0)
    logic.RL_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
    logic.RL_6DoF.setParam(15, stiffness, 1)

    logic.SteerFL_6DoF = constr.createConstraint(SteerLID,
    FLAxleID, 12, 0, 0, 0, 0, 0, 0, 0)
    logic.SteerFL_6DoF.setParam(3, 0, 0)
    logic.SteerFL_6DoF.setParam(4, 0, 0)
    logic.SteerFL_6DoF.setParam(5, 0, 0)

    logic.SteerFR_6DoF = constr.createConstraint(SteerRID,
    FLAxleID, 12, 0, 0, 0, 0, 0, 0, 0)
    logic.SteerFR_6DoF.setParam(3, 0, 0)
    logic.SteerFR_6DoF.setParam(4, 0, 0)
    logic.SteerFR_6DoF.setParam(5, 0, 0)

    logic.WheelFL_6DoF = constr.createConstraint(WheelFLID,
    SteerLID, 12, 0, 0, 0, 0, 0, 0, 0)
    logic.WheelFL_6DoF.setParam(4, 0.0, 0.0)
    logic.WheelFL_6DoF.setParam(5, 0, 0)

    logic.WheelFR_6DoF = constr.createConstraint(WheelFRID,
    SteerRID, 12, 0, 0, 0, 0, 0, 0, 0)
    logic.WheelFR_6DoF.setParam(4, 0, 0)
    logic.WheelFR_6DoF.setParam(5, 0, 0)
else:
    logic.SteerL_6DoF.setParam(3, 0, 0)
    logic.SteerL_6DoF.setParam(4, 0, 0)
    logic.SteerL_6DoF.setParam(5, steer, steer)

    logic.SteerR_6DoF.setParam(3, 0, 0)
    logic.SteerR_6DoF.setParam(4, 0, 0)
    logic.SteerR_6DoF.setParam(5, steer, steer)

On the other hand, if you like, take a look at Vehicle Constraint > VehicleWrapper

Here is a portion of a script where i use vehicle contraint in a subclassed KX_GameObject

from bge import logic, types, constraints

class Vehicle(types.KX_GameObject):

    def __init__(self, old, wheels, ai):      
        self.vehicle_constraint_id = self.create_contraint()
        //more stuff
        self.init_vehicle()

    def create_contraint(self):
        physicsId = self.getPhysicsId()
        vehicle_constraint = constraints.createConstraint(physicsId, 0, 11)
        constraintId = vehicle_constraint.getConstraintId()
        return constraints.getVehicleConstraint(constraintId)

    def init_vehicle(self):
        for wheel in range(len(self.wheels)):
            self.vehicle_constraint_id.addWheel(self.wheels[wheel], self.wheel_position[wheel], self.suspension_angle[wheel], self.wheel_axis[wheel], self.suspension_height[wheel], self.wheel_radius[wheel], self.wheel_steer[wheel])
            self.vehicle_constraint_id.setSuspensionCompression(self.suspension_compression[wheel], wheel)
            self.vehicle_constraint_id.setTyreFriction(self.wheel_grip[wheel], wheel)
            self.vehicle_constraint_id.setSuspensionDamping(self.suspension_damping[wheel], wheel)
            self.vehicle_constraint_id.setSuspensionStiffness(self.suspension_stiffness[wheel], wheel)
            self.vehicle_constraint_id.setRollInfluence(self.roll_influence[wheel], wheel)
$\endgroup$
4
  • $\begingroup$ That produces the following error: if not hasattr(logic, 'CarBody6DoF') invalid syntax (the arrow points at the last apostrophe) $\endgroup$
    – user16320
    Commented Nov 18, 2017 at 10:33
  • $\begingroup$ What version of blender are you using?. Also can you post an img of your logic editor and maybe a the blend file use https://blend-exchange.giantcowfilms.com. $\endgroup$ Commented Nov 18, 2017 at 17:21
  • $\begingroup$ OH... if not hasattr(logic, 'CarBody6DoF') > invalid syntax. if not hasattr(logic, 'CarBody6DoF'): missing : at the end of if sintax. $\endgroup$ Commented Nov 18, 2017 at 18:12
  • $\begingroup$ I'm trying the same thing as you and got stuck with steering too, but your code gave me a idea, your bug is more probably to be because you are assigning "SteerL_6DoF.setParam(5, steer, steer)" what gieve you no space for the wheel swing between min-max value making it unstable, i will try your code on my car now hehe and if works i will say there! $\endgroup$
    – Maxx Nunes
    Commented May 1, 2022 at 23:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .