40823220 cd2021

  • Home
    • Site Map
    • reveal
    • blog
  • About
  • WORKS
    • stage1
      • 1
      • 2~3
      • 4
      • 5
    • stage2
      • 6~7
      • 8
      • 9
    • stage3
      • 10
      • 10-task1
      • 10~11 task2
      • 12
      • 13
      • 14~15 機械手臂控制
      • 16
  • 筆記
    • SSH
    • 協同push遇到的問題
    • 推送內容給小組的步驟
    • task1亂數分組 操作步驟
    • GOGS倉儲clone及推送方式
  • 每週影片區
    • w1
    • w2~w3
    • w4
    • w6~w7
    • w8
    • w9
    • w10
    • w11
    • w12~w13
    • w13
    • w14
    • w15~w16
  • w5
  • W15
  • W16
  • W18
W15 << Previous Next >> W18

W16

項目1.在Onshape軟體上繪製機械手臂:

我教大家如何使用Onshape這套繪圖軟體,並順便演示我畫的機械手臂

圖檔網址

這是我的零組件下載點(40823220繪製)

W16零件STL檔(想要STL檔點這裡)

項目2.建立 CoppeliaSim 4.1.0 MTB robot 場景

影片:

Google Drive:所有項目的檔案

外面放的是我軟體的模擬檔案

要程式的話點選這個資料夾(我的程式都在這裡)

Leo檔:可用鍵盤控制程式

可用鍵盤控制的程式說明:

方向鍵左:軸1左轉、方向鍵右:軸1右轉

方向鍵上:軸2左轉、方向鍵下:軸2右轉

S:吸盤向下、W:吸盤向上並吸取、空白鍵:放下

function sysCall_init()
    joint1=sim.getObjectHandle('joint1')
    joint2=sim.getObjectHandle('joint2')
    jointz=sim.getObjectHandle('jointz')
    joint3=sim.getObjectHandle('joint3')
    sim.setJointTargetPosition(joint1,0)
    sim.setJointTargetPosition(joint2,0)
    sim.setJointTargetPosition(joint3,0)
    sim.setJointTargetPosition(jointz,0)
    deg1=0
    deg2=0
    deg3=0
end

function sysCall_actuation()
    message,auxiliaryData=sim.getSimulatorMessage()
    while message~=-1 do
        if (message==sim.message_keypress) then
            if (auxiliaryData[1]==2009) then
            deg1=deg1+1
            deg3=deg2-deg1
            sim.setJointTargetPosition(joint1,deg1*math.pi/180)
            end
            if (auxiliaryData[1]==2010) then
            deg1=deg1-1
            deg3=deg2-deg1
            sim.setJointTargetPosition(joint1,deg1*math.pi/180)
            end
            if (auxiliaryData[1]==2007) then
            deg2=deg2+1
            deg3=deg1-deg2
            sim.setJointTargetPosition(joint2,deg2*math.pi/180)
            end
            if (auxiliaryData[1]==2008) then
            deg2=deg2-1
            deg3=deg1-deg2
            sim.setJointTargetPosition(joint2,deg2*math.pi/180)
            end
            if (auxiliaryData[1]==115) then
                sim.setJointTargetPosition(jointz,-0.085)
                sim.setIntegerSignal("pad_switch",1)
            end
            if (auxiliaryData[1]==119) then
                sim.setJointTargetPosition(jointz,0)
            end
            if (auxiliaryData[1]==32) then
                sim.setIntegerSignal("pad_switch",0)
            end
            sim.setJointTargetPosition(joint3,deg3*math.pi/180)
        end
    message,auxiliaryData=sim.getSimulatorMessage()
    end
end

(參考老師提供的程式)藉由鍵盤按鍵來控制Robot角度

if (auxiliaryData[1]==114) then --r right turn in degree
                    -- if key r pressed axis1 angle adds 5 degrees
                     rotation1 = rotation1 + 5*deg
                     sim.setJointPosition(axis1, rotation1)
                end -- if r
                if (auxiliaryData[1]==108) then --l left turn in degree
                    -- if key l pressed axis1 angle substract 5 degrees
                     rotation1 = rotation1 - 5*deg
                     sim.setJointPosition(axis1, rotation1)
                end -- if l
                if (auxiliaryData[1]==100) then --d suction pad down
                    -- if key d pressed axis3 will down 0.01 m plus calibration
                     distance3 = distance3 + 0.01 + calibration
                     sim.setJointPosition(axis3, distance3)
                end -- if d
                if (auxiliaryData[1]==117) then --u suction pad up
                    -- if key u pressed axis3 will up 0.01 m minus calibration
                    -- 吸盤往下升 1 公分加上校正值
                     distance3 = distance3 - 0.01 - calibration
                     sim.setJointPosition(axis3, distance3)
                end -- if u

項目3.手臂末端加入 components-gripper-suction pad 吸盤

裡面的驅動程式:

1.因為我的機子比較大所以我的吸盤軸下降高度,我改為-0.085m

2.為了讓他跑迴圈我在中間加了while sim......

3.其他說明,我附在程式裡

function moving(x,y)
    a=0.4 我的第一個手臂-A距離長
    b=0.4 我的第二個手臂-B距離長
    c=math.pow((math.pow(x,2)+math.pow(y,2)),0.5) 算面積
    s=(a+b+c)/2 用海龍公式求解
    area=math.pow((s*(s-a)*(s-b)*(s-c)),0.5)
    h=area/(2*c)
    deg1_base=math.atan(x/y)
    if x<0 and y<0 then
        deg1_base=deg1_base+math.pi 算出來的角度會等於自身角度家徑度
    end
    deg1_tri=math.asin(h/a) 
    deg1=deg1_base+deg1_tri
    deg2=math.pi-(0.5*math.pi-deg1_tri)-math.acos(h/b)
    deg3=deg2-deg1
    print(deg1)
    sim.setJointTargetPosition(joint01,deg1)
    sim.setJointTargetPosition(joint02,-deg2)
    sim.setJointTargetPosition(joint03,deg3)
end

function sysCall_threadmain()
    joint01=sim.getObjectHandle('joint1')
    joint02=sim.getObjectHandle('joint2')
    joint03=sim.getObjectHandle('joint3')
    jointz=sim.getObjectHandle('jointz')
    sim.setJointTargetPosition(joint01,0)
    sim.setJointTargetPosition(joint02,0)
    sim.setJointTargetPosition(joint03,0)
    sim.setJointTargetPosition(jointz,0)
    sim.setIntegerSignal("pad_switch",1)
    sim.setJointTargetPosition(jointz,-0.085) 這裡是吸取東西的指令開始點
    sim.wait(2) 等兩秒
    sim.setJointTargetPosition(jointz,0) 吸取東西的指令終止點
    while sim.getSimulationState()~=sim.simulation_advancing_abouttostopre do
    moving(0.2,0.7) 到這個指定的座標
    sim.wait(2) 
    sim.setIntegerSignal("pad_switch",0)吸盤關掉 (把方塊往下丟)
    sim.wait(2)
    sim.setIntegerSignal("pad_switch",1) 吸盤打開
    sim.setJointTargetPosition(jointz,-0.085) 再一次向下-0.085吸取東西
    sim.wait(2)
    sim.setJointTargetPosition(jointz,0)
    sim.wait(2)
    moving(-0.3,-0.55)
    sim.wait(2)
    sim.setIntegerSignal("pad_switch",0)
    sim.wait(2)
    sim.setIntegerSignal("pad_switch",1)
    sim.setJointTargetPosition(jointz,-0.085)
    sim.wait(2)
    sim.setJointTargetPosition(jointz,0)
    sim.wait(2)
    end
end

這是吸盤的程式,感謝40823214熱心的指導,讓我能理解並使用他

    maxPullForce=sim.getScriptSimulationParameter(sim.handle_self,'maxPullForce')
    maxShearForce=sim.getScriptSimulationParameter(sim.handle_self,'maxShearForce')
    maxPeelTorque=sim.getScriptSimulationParameter(sim.handle_self,'maxPeelTorque')

    sim.setLinkDummy(l,-1)
    sim.setObjectParent(l,b,true)
    m=sim.getObjectMatrix(l2,-1)
    sim.setObjectMatrix(l,-1,m)
end

function sysCall_cleanup() 
    --this is teach by 40823214
    sim.setLinkDummy(l,-1)
    sim.setObjectParent(l,b,true)
    m=sim.getObjectMatrix(l2,-1)
    sim.setObjectMatrix(l,-1,m)
end 

function sysCall_sensing() 
    parent=sim.getObjectParent(l)
    --this is teach by 40823214
    local sig=sim.getIntegerSignal("pad_switch")
    if (not sig) or (sig==0) then
        if (parent~=b) then
            sim.setLinkDummy(l,-1)
            sim.setObjectParent(l,b,true)
            m=sim.getObjectMatrix(l2,-1)
            sim.setObjectMatrix(l,-1,m)
        end
    else
        if (parent==b) then
            index=0
            while true do
                shape=sim.getObjects(index,sim.object_shape_type)
                if (shape==-1) then
                    break
                end
                local res,val=sim.getObjectInt32Parameter(shape,sim.shapeintparam_respondable)
                if (shape~=b) and (val~=0) and (sim.checkProximitySensor(s,shape)==1) then
                    -- Ok, we found a respondable shape that was detected
                    -- We connect to that shape:
                    -- Make sure the two dummies are initially coincident:
                    sim.setObjectParent(l,b,true)
                    m=sim.getObjectMatrix(l2,-1)
                    sim.setObjectMatrix(l,-1,m)
                    -- Do the connection:
                    sim.setObjectParent(l,shape,true)
                    sim.setLinkDummy(l,l2)
                    break
                end
                index=index+1
            end
        else
            -- Here we have an object attached
            if (infiniteStrength==false) then
                -- We might have to conditionally beak it apart!
                result,force,torque=sim.readForceSensor(suctionPadLink) -- Here we read the median value out of 5 values (check the force sensor prop. dialog)
                if (result>0) then
                    breakIt=false
                    if (force[3]>maxPullForce) then breakIt=true end
                    sf=math.sqrt(force[1]*force[1]+force[2]*force[2])
                    if (sf>maxShearForce) then breakIt=true end
                    if (torque[1]>maxPeelTorque) then breakIt=true end
                    if (torque[2]>maxPeelTorque) then breakIt=true end
                    if (breakIt) then
                        -- We break the link:
                        sim.setLinkDummy(l,-1)
                        sim.setObjectParent(l,b,true)
                        m=sim.getObjectMatrix(l2,-1)
                        sim.setObjectMatrix(l,-1,m)
                    end
                end
            end
        end
    end
end 

項目4.逆向運算學函式

主要程式說明:

joint01=sim.getObjectHandle('joint1')設定軸1
    joint02=sim.getObjectHandle('joint2')設定軸2
    joint03=sim.getObjectHandle('joint3')設定軸3
    jointz=sim.getObjectHandle('jointz')設定方軸
    sim.setJointTargetPosition(joint01,0)定位軸1
    sim.setJointTargetPosition(joint02,0)定位軸2
    sim.setJointTargetPosition(joint03,0)定位軸3
    sim.setJointTargetPosition(jointz,0)定位方軸
    sim.setIntegerSignal("pad_switch",1)
    sim.setJointTargetPosition(jointz,-0.085)    吸盤下降0.085
    sim.wait(2)停頓2秒
    sim.setJointTargetPosition(jointz,0)
    sim.wait(2)
    moving(0.2,0.7)以下都是各點要求       
    sim.wait(2)
    sim.setIntegerSignal("pad_switch",0)
    sim.wait(2)
    sim.setIntegerSignal("pad_switch",1)
    sim.wait(2)
    sim.setJointTargetPosition(jointz,-0.06)
    sim.wait(2)
    sim.setJointTargetPosition(jointz,0)
    sim.wait(2)
    moving(-0.3,-0.55)                                       
    sim.wait(5)
    sim.setIntegerSignal("pad_switch",0)
    sim.wait(2)
    sim.setIntegerSignal("pad_switch",1)
    sim.wait(2)
    sim.setJointTargetPosition(jointz,-0.06)
    sim.wait(2)
    sim.setJointTargetPosition(jointz,0)
    sim.wait(2)

上面有提到過的程式我再補充說明:(試算角度)

a=0.4 調整a.距離為0.4
b=0.4 調整b.距離為0.4
c=math.pow((math.pow(x,2)+math.pow(y,2)),0.5) 角度計算
s=(a+b+c)/2
area=math.pow((s*(s-a)*(s-b)*(s-c)),0.5)
h=area/(2*c)
deg1_base=math.atan(x/y)
if x<0 and y<0 then
    deg1_base=deg1_base+math.pi
end
deg1_tri=math.asin(h/a)
deg1=deg1_base+deg1_tri
deg2=math.pi-(0.5*math.pi-deg1_tri)-math.acos(h/b)
deg3=deg2-deg1
sim.setJointTargetPosition(joint01,deg1)
sim.setJointTargetPosition(joint02,-deg2)
sim.setJointTargetPosition(joint03,deg3)

項目5.Python remote API 逆向運動學函式

Python程式說明:

(跟前面的差不多意思,有些地方要改,例如:有些end要記得拿掉、下降高度也要記得改)

import sim as vrep
import math
import random
import time
import math

def moving(x,y):
    a=0.4
    b=0.4
    c=math.pow((math.pow(x,2)+math.pow(y,2)),0.5)
    s=(a+b+c)/2
    area=math.pow((s*(s-a)*(s-b)*(s-c)),0.5)
    h=area/(2*c)
    deg1_base=math.atan(x/y)
    if x<0 and y<0 :
        deg_base1=deg1_base+math.pi
    
    deg1_tri=math.asin(h/a)
    deg1=deg1_base+deg1_tri
    deg2=math.pi-(0.5*math.pi-deg1_tri)-math.acos(h/b)
    deg3=deg2-deg1
    vrep.simxSetJointTargetPosition(clientID,joint01,deg1,opmode)
    vrep.simxSetJointTargetPosition(clientID,joint02,-deg2,opmode)
    vrep.simxSetJointTargetPosition(clientID,joint03,deg3,opmode)

print ('Start')
 
vrep.simxFinish(-1)
 
clientID = vrep.simxStart('127.0.0.1', 19997, True, True, 5000, 5)

if clientID != -1:
    print ('Connected to remote API server')

    res = vrep.simxAddStatusbarMessage(
        clientID, "This is teach by 40823214 ",
        vrep.simx_opmode_oneshot)
    if res not in (vrep.simx_return_ok, vrep.simx_return_novalue_flag):
        print("Could not add a message to the status bar.")


    opmode = vrep.simx_opmode_oneshot_wait
    STREAMING = vrep.simx_opmode_streaming


    vrep.simxStartSimulation(clientID, opmode)
    ret,joint01=vrep.simxGetObjectHandle(clientID,"joint1",opmode)
    ret,joint02=vrep.simxGetObjectHandle(clientID,"joint2",opmode)
    ret,joint03=vrep.simxGetObjectHandle(clientID,"joint3",opmode)
    ret,jointz=vrep.simxGetObjectHandle(clientID,"jointz",opmode)
    
    vrep.simxSetJointTargetPosition(clientID,joint01,0,opmode)
    vrep.simxSetJointTargetPosition(clientID,joint02,0,opmode)
    vrep.simxSetJointTargetPosition(clientID,joint03,0,opmode)
    vrep.simxSetIntegerSignal(clientID,"pad_switch",1,opmode)
    vrep.simxSetJointTargetPosition(clientID,jointz,-0.085,opmode)
    time.sleep(1)
    vrep.simxSetJointTargetPosition(clientID,jointz,0,opmode)
    
    while True:
        moving(0.2,0.7)
        time.sleep(1)
        vrep.simxSetIntegerSignal(clientID,"pad_switch",0,opmode)
        time.sleep(1)
        vrep.simxSetIntegerSignal(clientID,"pad_switch",1,opmode)
        vrep.simxSetJointTargetPosition(clientID,jointz,-0.085,opmode)吸起來
        time.sleep(1)
        vrep.simxSetJointTargetPosition(clientID,jointz,0,opmode)放下
        moving(-0.3,-0.55)
        time.sleep(1)
        vrep.simxSetIntegerSignal(clientID,"pad_switch",0,opmode)
        time.sleep(1)
        vrep.simxSetIntegerSignal(clientID,"pad_switch",1,opmode)
        vrep.simxSetJointTargetPosition(clientID,jointz,-0.085,opmode)吸起來
        time.sleep(1)
        vrep.simxSetJointTargetPosition(clientID,jointz,0,opmode)

放下

心得:

我只想說對於我這個初學者而言,要在短時間內,弄熟Onshape、Coppeliasim這兩套軟體,難度有點高,重點是還要搭配程式,這真的是個艱難的挑戰,雖然我沒有做得很完整,但至少有個樣子了,我能做到這樣,最大功臣是40823214同學的協助,我一直問,他就一直教,真的很棒。總之,期末這項作業,我學到了很多,我也真的是盡力了。

參與40823214的30人協同的教學影片:

以下是我所有的檔案在這邊也可下載:

項目2-lua程式可用鍵盤控制

項目4-lua程式在軟體內運作

項目5-用Python remote API 驅動 、 搭配的PY程式


W15 << Previous Next >> W18

Copyright © All rights reserved | This template is made with by Colorlib