Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Locomotive using joints

dave1707dave1707 Mod
edited April 1 in Code Sharing Posts: 9,106

Here’s something I was playing with the last few days. It’s a locomotive demo using Revolute, Distance and Prismatic joints. The piston uses Prismatic, the wheels use Revolute, and the joints connecting the wheels and piston uses Distance. The only piece the gets any value to move is the piston. When the piston moves, it causes wheel number 3 to start rotating by the distance joint connecting them. Wheel 3 then rotates wheel 2 and wheel 4 with their connecting joints. When 2 rotates wheel 1 with their connecting joint. By increasing the pressure slider, the piston moves faster causing wheel 3 and the other wheels to move faster. You can slide the parameter “piston joint” to break the joint between the piston and wheel 3 causing them to slow down. Parameter “Joints 1_2, 2_3, and 3_4” breaks the joints between those wheels and they will slow down. Wheels 1, 2, and 3 have angularDamping, so they will slow down faster. Wheel 4 has no damping, so it will rotate for awhile.

PS. Run in landscape orientation.

viewer.mode=STANDARD

-- locomotive

function setup()
    rectMode(CENTER)
    parameter.integer("pressure",1,100,5)
    parameter.boolean("piston joint",false)
    parameter.boolean("joint1_2",false)
    parameter.boolean("joint2_3",false)
    parameter.boolean("joint3_4",false)

    -- create wheels
    w1=wheel(200,200,200,200,200,260)
    w2=wheel(380,200,380,200,380,260)
    w3=wheel(560,200,560,200,560,260)
    w4=wheel(740,200,740,200,740,260)

    createPiston()
    createJoints()
end

function draw()
    background(142, 95, 31)
    fill(255)
    text("Angular velocity (1)   "..w1.wheel.angularVelocity//-1,WIDTH/2,HEIGHT-25)
    text("Angular velocity (2)   "..w2.wheel.angularVelocity//-1,WIDTH/2,HEIGHT-50)
    text("Angular velocity (3)   "..w3.wheel.angularVelocity//-1,WIDTH/2,HEIGHT-75)
    text("Angular velocity (4)   "..w4.wheel.angularVelocity//-1,WIDTH/2,HEIGHT-100)

    w1:draw()
    w2:draw()
    w3:draw()
    w4:draw()
    drawPiston()
    drawJoints() 

    if r1.linearVelocity.x>0 then
        r1.linearVelocity=vec2(pressure*10,0)
    else
        r1.linearVelocity=vec2(pressure*-10,0)
    end

    if piston_joint and j5~=nil then   
        j5:destroy()
        j5=nil
    end
    if joint1_2 and j61~=nil then
        j61:destroy()
        j61=nil
        w1.wheel.angularDamping=1
    end
    if joint2_3 and j62~=nil then
        j62:destroy()
        j62=nil
        w2.wheel.angularDamping=1
    end
    if joint3_4 and j63~=nil then
        j63:destroy()
        j63=nil
        w3.wheel.angularDamping=1
    end

end

function createPiston()
    p1=physics.body(CIRCLE,0)   -- anchor piston
    p1.x=100
    p1.y=350
    p1.type=STATIC

    r1=physics.body(CIRCLE,0)  -- piston rect
    r1.x=100
    r1.y=350
end

function drawPiston()
    if j5==nil then
        return
    end
    pushStyle()
    strokeWidth(8)
    fill(255)
    stroke(0)
    rect(110,350,200,50) -- piston cylinder
    fill(0)
    rect(r1.x,r1.y,20,50) -- piston
    strokeWidth(0)
    rectMode(CORNER)
    if pressure>0 then
        if r1.linearVelocity.x>0 then
            fill(255,0,0,pressure*2+55)
            rect(p1.x-84,r1.y-20,r1.x-24,40)   -- red pressure
        elseif r1.linearVelocity.x<0 then
            fill(255,0,0,pressure*2+55)
            rect(r1.x+8,r1.y-20,p1.x-r1.x+96,40)   -- red pressure
        end
    end
    popStyle()
end

function drawJoints()
    pushStyle()
    stroke(172)
    strokeWidth(4)
    if j61~=nil then
        line(j61.bodyA.x,j61.bodyA.y,j61.bodyB.x,j61.bodyB.y)
    end
    if j62~=nil then
        line(j62.bodyA.x,j62.bodyA.y,j62.bodyB.x,j62.bodyB.y)
    end
    if j63~=nil then
        line(j63.bodyA.x,j63.bodyA.y,j63.bodyB.x,j63.bodyB.y)
    end
    if j5~=nil then
        line(j5.bodyA.x,j5.bodyA.y,j5.bodyB.x,j5.bodyB.y)
    end
    popStyle()
end

function createJoints()
    j31=physics.joint(REVOLUTE,w1.anchor1,w1.wheel,vec2(w1.anchor1.x,w1.anchor1.y))
    j32=physics.joint(REVOLUTE,w2.anchor1,w2.wheel,vec2(w2.anchor1.x,w2.anchor1.y))
    j33=physics.joint(REVOLUTE,w3.anchor1,w3.wheel,vec2(w3.anchor1.x,w3.anchor1.y))
    j34=physics.joint(REVOLUTE,w4.anchor1,w4.wheel,vec2(w4.anchor1.x,w4.anchor1.y))

    j41=physics.joint(REVOLUTE,w1.wheel,w1.anchor2,vec2(w1.wheel.x,w1.wheel.y+60))
    j42=physics.joint(REVOLUTE,w2.wheel,w2.anchor2,vec2(w2.wheel.x,w2.wheel.y+60))
    j43=physics.joint(REVOLUTE,w3.wheel,w3.anchor2,vec2(w3.wheel.x,w3.wheel.y+60))
    j44=physics.joint(REVOLUTE,w4.wheel,w4.anchor2,vec2(w4.wheel.x,w4.wheel.y+60))

    j61=physics.joint(DISTANCE,w1.anchor2,w2.anchor2,
        vec2(w1.anchor2.x,w1.anchor2.y),vec2(w2.anchor2.x,w2.anchor2.y))
    j62=physics.joint(DISTANCE,w2.anchor2,w3.anchor2,
        vec2(w2.anchor2.x,w2.anchor2.y),vec2(w3.anchor2.x,w3.anchor2.y))
    j63=physics.joint(DISTANCE,w3.anchor2,w4.anchor2,
        vec2(w3.anchor2.x,w3.anchor2.y),vec2(w4.anchor2.x,w4.anchor2.y))

    j1=physics.joint(PRISMATIC,p1,r1,p1.position,vec2(1,0))
    j5=physics.joint(DISTANCE,r1,w3.anchor2,r1.position,w3.anchor2.position)
end

wheel=class()

function wheel:init(a1x,a1y,wx,wy,a2x,a2y)
    self.anchor1=physics.body(CIRCLE,0)
    self.anchor1.x=a1x
    self.anchor1.y=a1y
    self.anchor1.type=STATIC

    self.wheel=physics.body(CIRCLE,80)
    self.wheel.x=wx
    self.wheel.y=wy

    self.anchor2=physics.body(CIRCLE,0)
    self.anchor2.x=a2x
    self.anchor2.y=a2y
end

function wheel:draw()
    pushMatrix()
    pushStyle()
    stroke(255)
    strokeWidth(6)
    fill(46, 30, 29)
    translate(self.anchor1.x,self.anchor1.y)
    rotate(self.wheel.angle)
    ellipse(0,0,self.wheel.radius*2)       --large wheel
    fill(255)
    strokeWidth(3)
    stroke(103, 66, 64)
    for z=0,360,30 do
        x=math.cos(math.rad(z))*72
        y=math.sin(math.rad(z))*72
        line(0,0,x,y)
    end
    ellipse(0,0,30)                 -- center circle
    ellipse(0,60,20)                -- outer circle
    fill(0)
    ellipse(0,0,10)                -- small center circle
    popStyle()
    popMatrix()
end

Comments

  • Posts: 977

    neat. now i'll have to figure out what you did :smile:

  • dave1707dave1707 Mod
    Posts: 9,106

    @RonJeffries Thanks, if you have questions about anything, just ask. It took a lot of trial and error writing this because I wasn’t sure how the joints actually worked. I spent a lot of time on small programs playing with a single joint until I understood what was happening.

  • Posts: 977

    yes, that's what i'd do too. that's a neat example, should be added to the examples that ship with codea

Sign In or Register to comment.