0. 시뮬레이션 스크립트
http://www.coppeliarobotics.com/helpFiles/en/simulationScripts.htmhttp://www.coppeliarobotics.com/helpFiles/en/mainAndChildScripts.htm
'메인 스크립트'와 '차일드 스크립트'가 있다.
시뮬레이션 스크립트에 사용한다.
'메인 스크립트' : 시뮬레이션 루프 코드
'차일드 스크립트' : 모델을 제어하는 일반적인 코드
모든 '씬(Scene)'에는 모든 기능을 제어하는 '메인 스크립트'가 있다.
'메인 스크립트'가 없다면 시뮬레이션은 실행 불가.
'메인 스크립트'에서 모든 코드를 구현할 수 있지만, 세부 기능들은 '차일드 스크립트'에서 구현하는 것이 더 바람직하다.
각 씬의 객체는 각 차일드 스크립트를 이용하여 독립 제어, 분산 제어 할 수 있다.
<메인 스크립트와 차일드 스크립트의 주요 차이점>
1. 메인 스크립트는 하나만 존재할 수 있다. 차일드 스크립트의 갯수는 무제한이다.
2. 메인 스크립트에 세부 함수나 기능을 구현하지 않는 것이 바람직하다. 각 씬의 객체는 차일드 스크립트와 연관되어 있으므로 차일드 스크립트에서 기능을 구현해야 한다.
3. 메인 스크립트는 씬 객체 복사/붙여넣기할 때 중복될 수 없다. 차일드 스크립트는 씬 객체와 함께 복제된다.
4. 메인 스크립트는 쓰레드 할 수 없다. 차일드 스크립트는 쓰레드 또는 non-쓰레드 할 수 있다.
5. 차일드 스크립트는 스페셜 타입의 시스템 콜백 함수를 사용할 수 있다.
각 스크립트에는 시뮬레이션 매개변수(Parameter) 목록이 첨부되어 있다. 매개변수를 이용하여 시뮬레이션 모델의 값을 조정할 수 있다.
Recommended topics
1. 메인 스크립트(The main script)
메인 스크립트 아이콘 :기본적인 메인 스크립트는 4가지 기능으로 분류할 수 있다.
function sysCall_init() --초기화 함수, 시작시 1번만 실행, 시뮬레이션 준비
-- Initialization part:
sim.handleSimulationStart()
sim.openModule(sim.handle_all)
sim.handleGraph(sim.handle_all_except_explicit,0)
end
function sysCall_actuation() -- 작동 기능(역기구학, 동역학 등)
-- Actuation part:
sim.resumeThreads(sim.scriptthreadresume_default) --쓰레드된 차일드 스크립트 재시작
sim.resumeThreads(sim.scriptthreadresume_actuation_first) --쓰레드된 차일드 스크립트 재시작
sim.launchThreadedChildScripts() --쓰레드된 차일드 스크립트 시작
sim.handleChildScripts(sim.syscb_actuation)
--쓰레드되지 않은 차일드 스크립트의 sysCall_acuation 함수 호출
sim.resumeThreads(sim.scriptthreadresume_actuation_last)
sim.handleCustomizationScripts(sim.syscb_actuation)
sim.handleAddOnScripts(sim.syscb_actuation)
sim.handleModule(sim.handle_all,false)
sim.resumeThreads(2)
sim.handleMechanism(sim.handle_all_except_explicit)
sim.handleIkGroup(sim.handle_all_except_explicit)
sim.handleDynamics(sim.getSimulationTimeStep())
end
function sysCall_sensing() --센싱 기능(근접센서, 충돌감지 등)
-- Sensing part:
sim.handleSensingStart()
sim.handleCollision(sim.handle_all_except_explicit)
sim.handleDistance(sim.handle_all_except_explicit)
sim.handleProximitySensor(sim.handle_all_except_explicit)
sim.handleVisionSensor(sim.handle_all_except_explicit)
sim.resumeThreads(sim.scriptthreadresume_sensing_first) --쓰레드된 차일드 스크립트 재시작
sim.handleChildScripts(sim.syscb_sensing)
--쓰레드되지 않은 차일드 스크립트의 sysCall_sensing 함수 호출
sim.resumeThreads(sim.scriptthreadresume_sensing_last)
sim.handleCustomizationScripts(sim.syscb_sensing)
sim.handleAddOnScripts(sim.syscb_sensing)
sim.handleModule(sim.handle_all,true)
sim.resumeThreads(sim.scriptthreadresume_allnotyetresumed)
sim.handleGraph(sim.handle_all_except_explicit,sim.getSimulationTime()+sim.getSimulationTimeStep())
end
function sysCall_cleanup() -- 복원 기능(시뮬레이션이 끝나기 바로 전에 1번만 실행됨)
-- Clean-up part:
sim.resetCollision(sim.handle_all_except_explicit)
sim.resetDistance(sim.handle_all_except_explicit)
sim.resetProximitySensor(sim.handle_all_except_explicit)
sim.resetVisionSensor(sim.handle_all_except_explicit)
sim.closeModule(sim.handle_all)
end
function sysCall_suspend() --일시정지
sim.handleChildScripts(sim.syscb_suspend)
sim.handleCustomizationScripts(sim.syscb_suspend)
sim.handleAddOnScripts(sim.syscb_suspend)
end
function sysCall_resume() --재시작
sim.handleChildScripts(sim.syscb_resume)
sim.handleCustomizationScripts(sim.syscb_resume)
sim.handleAddOnScripts(sim.syscb_resume)
end
메인 스크립트에서 가장 중요한 명령어는 sim.handleChildScripts 입니다. 이 스크립트는 'Actuation' 내부와 'Sensing' 내부의 두 개의 별개의 위치에서 호출됩니다. 기본 메인 스크립트를 보면 동작 기능으로 장면 컨텐츠 (예 : sim.handleIkGroup, sim.handleDynamics 등)를 조작하거나 수정할 수 있으며 감지 기능을 사용하면 장면 컨텐츠를 감지하고 프로빙 할 수 있습니다. sim.handleCollision, sim.handleDistance, sim.handleProximitySensor 등).
다음은 근접 센서가 장착 된 모바일 로봇을 시뮬레이션 할 때 기본 스크립트에서 발생하는 상황을 보여줍니다.
[Actuation] -> [Sensing] -> [Display]
또는
[Sensing] -> [Actuation] -> [Display]
2. 차일드 스크립트(Child script)
차일드 스크립트는 Lua로 작성되었으며 시뮬레이션에서 특정 기능을 수행합니다. 차일드 스크립트는 씬 객체에 첨부되며 씬 계층의 스크립트 아이콘에서 볼 수 있습니다.<차일드 스크립트의 장점>
1. 뛰어난 이식성
2. 내재적 확장성
3. 다른 모델 버전간 충돌 없음
4. 시뮬레이션 루프와의 쉬운 동기화
<차일드 스크립트의 2가지 유형>
1. 쓰레드 되지 않은(Non-Threaded) 차일드 스크립트(왼쪽 아이콘)
2. 쓰레드 된 차일드 스크립트(오른쪽 아이콘)
1) Non-threaded child scripts
쓰레드 되지 않은 차일드 스크립트는 차단 기능(Block Functions)을 포함합니다. 즉, 호출될 때마다 작업을 수행한 다음 제어를 반환해야 합니다. 제어가 반환되지 않으면 전체 시뮬레이션이 중단됩니다. 논쓰레드 차일드 스크립트는 메인 스크립트의 Actuation 및 Sensing 기능에서 시뮬레이션 단계마다 메인 스크립트에 의해 2번 호출됩니다. 시스템은 적절한 경우 차일드 스크립트 (예 : 차일드 스크립트 초기화, Clean-up 또는 콜백 기능이 실행될 때)를 호출합니다. 이 유형의 차일드 스크립트는 가능하다면 항상 스레드 된 차일드 스크립트에서 선택해야합니다.
Non-threaded 차일드 스크립트는 정확한 호출 또는 실행 순서를 따릅니다. 기본적으로 차일드 스크립트는 Leaf 객체 (또는 Childless 객체)로 시작하고 Root 객체 (또는 Parentless 객체)로 끝나는 것으로 호출됩니다(시작 : Childless 객체 → 끝 : Parentless 객체). 메인 스크립트에서 호출 된 sim.handleChildScripts 명령은 Non-threaded 차일드 스크립트의 호출을 처리합니다.
'자동문'을 나타내는 시뮬레이션 모델의 예를 생각해보십시오. 앞면과 뒷면의 근접 센서는 접근하는 사람을 감지합니다. 사람이 충분히 가까워지면 문이 자동으로 열립니다. 다음 코드는 '자동문'의 예를 보여주는 일반적인 Non-threaded 차일드 스크립트를 보여줍니다.
<'자동문' 예제>
function sysCall_init()
sensorHandleFront=sim.getObjectHandle("DoorSensorFront")
sensorHandleBack=sim.getObjectHandle("DoorSensorBack")
motorHandle=sim.getObjectHandle("DoorMotor")
end
function sysCall_actuation()
resF=sim.readProximitySensor(sensorHandleFront)
resB=sim.readProximitySensor(sensorHandleBack)
if ((resF>0)or(resB>0)) then
sim.setJointTargetVelocity(motorHandle,-0.2)
else
sim.setJointTargetVelocity(motorHandle,0.2)
end
end
function sysCall_sensing()
end
function sysCall_cleanup()
-- Put some restoration code here
end
function sysCall_dynCallback(inData)
-- See the dynamics callback function section in the user manual for details about the input argument
end
function sysCall_jointCallback(inData)
-- See the joint callback function section in the user manual for details about input/output arguments
return outData
end
function sysCall_contactCallback(inData)
-- See the contact callback function section in the user manual for details about input/output arguments
return outData
end
function sysCall_beforeCopy(inData)
for key,value in pairs(inData.objectHandles) do
print("Object with handle "..key.." will be copied")
end
end
function sysCall_afterCopy(inData)
for key,value in pairs(inData.objectHandles) do
print("Object with handle "..key.." was copied")
end
end
function sysCall_beforeDelete(inData)
for key,value in pairs(inData.objectHandles) do
print("Object with handle "..key.." will be deleted")
end
-- inData.allObjects indicates if all objects in the scene will be deleted
end
function sysCall_afterDelete(inData)
for key,value in pairs(inData.objectHandles) do
print("Object with handle "..key.." was deleted")
end
-- inData.allObjects indicates if all objects in the scene were deleted
end
<Non-threaded 차일드 스크립트의 4가지 주요 부분>
-1.초기화 함수 : sysCall_init. 이 부분은 한 번만 실행됩니다 (차일드 스크립트가 처음 호출 될 때). 시뮬레이션 시작과 동시에 시뮬레이션 중간에 있을 수 있습니다. 시뮬레이션이 실행 중일 때도 차일드 스크립트와 관련된 객체를 언제든지 씬에 복사 / 붙여 넣기 할 수 있습니다. 일반적으로 당신은 이 파트에서 검색 핸들뿐만 아니라 초기화 코드도 넣을 것이다.
• 작동 기능 : sysCall_actuation. 이 부분은 시뮬레이션 단계의 작동 단계에서 각 시뮬레이션 단계에서 실행됩니다. 작동 단계에 대한 자세한 내용은 메인 스크립트 기본 코드를 참조하십시오. 일반적으로이 부분에서 일부 작동을 수행합니다 (Sensing 기능 수행하지 않음).
• 감지 기능 : sysCall_sensing. 이 부분은 시뮬레이션 단계의 감지 단계에서 각 시뮬레이션 단계에서 실행됩니다. 감지 단계에 대한 자세한 내용은 기본 스크립트 기본 코드를 참조하십시오. 일반적으로이 부분에서는 감지 만 수행합니다 (Actuation 기능 수행하지 않음).
• 복원 기능 : sysCall_cleanup. 이 부분은 시뮬레이션이 끝나기 직전 또는 스크립트가 삭제되기 전에 한 번 실행됩니다.
2) Threaded Child Scripts
쓰레드 된 차일드 스크립트는 쓰레드에서 실행되는 스크립트입니다.
메인 스크립트의 sim.launchThreadedChildScripts 및 sim.resumeThreads 기능을 통해 처리됩니다. 쓰레드 된 차일드 스크립트의 시작/재개는 정확한 순서로 실행됩니다. 쓰레드 된 차일드 스크립트의 실행이 아직 진행중이면 두 번째 실행은 하지 않습니다. 'excute once' 항목이 선택 취소 되어 있는 경우에만 쓰레드 된 차일드 스크립트는 재실행 될 수 있습니다. 씬 계층의 쓰레드된 차일드 스크립트 아이콘은 밝은 파란색으로 표시되어 쓰레드에서 시작될 것임을 나타냅니다. 쓰레드 된 차일드 스크립트는 리소스를 많이 사용하고, 처리 시간을 낭비할 수 있으며, 시뮬레이션 중지 명령에 덜 반응할 수 있습니다. 아래는 일반적인 쓰레드 된 차일드 스크립트 입니다.
function sysCall_threadmain()
-- Put some initialization code here:
sensorHandleFront=sim.getObjectHandle("DoorSensorFront")
sensorHandleBack=sim.getObjectHandle("DoorSensorBack")
motorHandle=sim.getObjectHandle("DoorMotor")
-- Here we execute the regular thread code:
while sim.getSimulationState()~=sim.simulation_advancing_abouttostop do
resF=sim.readProximitySensor(sensorHandleFront)
resB=sim.readProximitySensor(sensorHandleBack)
if ((resF>0)or(resB>0)) then
sim.setJointTargetVelocity(motorHandle,-0.2)
else
sim.setJointTargetVelocity(motorHandle,0.2)
end
-- this loop wastes precious computation time since we should only read new
-- values when the simulation time has changed (i.e. in next simulation step).
end
end
function sysCall_cleanup()
-- Put some clean-up code here:
end
<쓰레드 된 차일드 스크립트의 2가지 부분>
-1. 주요 부분 :이 부분은 스레드가 시작될 때 스레드가 종료되기 직전까지 실행됩니다. 시뮬레이션 시작과 동시에 시뮬레이션 중간에 있을 수 있습니다. 시뮬레이션이 실행 중일 때도 차일드 스크립트와 관련된 객체를 언제든지 씬에 복사 / 붙여 넣기 할 수 있습니다. 일반적으로 루프의 코드는 시뮬레이션의 특정 부분 (예 : 자동 슬라이딩 도어 처리)을 담당합니다. 이 부분에는 기본 루프뿐만 아니라 초기화 코드도 넣습니다. 위의 특정 예에서 루프는 귀중한 계산 시간을 낭비하고 메인 시뮬레이션 루프와 비동기 적으로 실행됩니다. 더 좋은 예를 보려면 아래를 참조하십시오.
-2. 복구 부분 :이 부분은 시뮬레이션이 끝나기 직전 또는 스레드가 끝나기 전에 한 번 실행됩니다.
V-REP는 전통적인 쓰레드 방식 대신에 코루틴의 동작을 모방하여 쓰레드를 사용합니다(유연성이 높고 통제가 쉬움). 기본적으로 스레드 된 차일드 스크립트는 약 1-2 밀리 초 동안 실행되어 다른 스레드로 자동 전환됩니다. 이 기본 동작은 sim.setThreadSwitchTiming 또는 sim.setThreadAutomaticSwitch를 사용하여 변경할 수 있습니다. 현재 스레드가 전환되면 다음 시뮬레이션 Pass (즉, currentTime + simulationTimeStep 시점)에서 실행을 다시 시작합니다. 스레드 전환은 자동 (지정된 시간 이후에 발생)이지만, sim.switchThread 명령을 사용하면 필요할 때 그 시간을 단축 할 수 있습니다. 위의 세 가지 명령을 사용하여 주 시뮬레이션 루프와의 우수한 동기화를 달성 할 수 있습니다. 다음 코드 (위의 예에서 자동 슬라이딩 도어를 처리)는 주 시뮬레이션 루프와 하위 스크립트 동기화를 보여줍니다.
function sysCall_threadmain()
-- Put some initialization code here:
sim.setThreadAutomaticSwitch(false) -- disable automatic thread switches
sensorHandleFront=sim.getObjectHandle("DoorSensorFront")
sensorHandleBack=sim.getObjectHandle("DoorSensorBack")
motorHandle=sim.getObjectHandle("DoorMotor")
-- Here we execute the regular thread code:
while sim.getSimulationState()~=sim.simulation_advancing_abouttostop do
resF=sim.readProximitySensor(sensorHandleFront)
resB=sim.readProximitySensor(sensorHandleBack)
if ((resF>0)or(resB>0)) then
sim.setJointTargetVelocity(motorHandle,-0.2)
else
sim.setJointTargetVelocity(motorHandle,0.2)
end
sim.switchThread() -- Explicitely switch to another thread now!
-- from now on, above loop is executed once in each simulation step.
-- this way you do not waste precious computation time and run synchronously.
end
end
function sysCall_cleanup()
-- Put some clean-up code here
end
-- Put some initialization code here:
sim.setThreadAutomaticSwitch(false) -- disable automatic thread switches
sensorHandleFront=sim.getObjectHandle("DoorSensorFront")
sensorHandleBack=sim.getObjectHandle("DoorSensorBack")
motorHandle=sim.getObjectHandle("DoorMotor")
-- Here we execute the regular thread code:
while sim.getSimulationState()~=sim.simulation_advancing_abouttostop do
resF=sim.readProximitySensor(sensorHandleFront)
resB=sim.readProximitySensor(sensorHandleBack)
if ((resF>0)or(resB>0)) then
sim.setJointTargetVelocity(motorHandle,-0.2)
else
sim.setJointTargetVelocity(motorHandle,0.2)
end
sim.switchThread() -- Explicitely switch to another thread now!
-- from now on, above loop is executed once in each simulation step.
-- this way you do not waste precious computation time and run synchronously.
end
end
function sysCall_cleanup()
-- Put some clean-up code here
end
위의 루프는 이제 각 메인 시뮬레이션 루프에 대해 정확히 한 번 실행되며 동일한 시뮬레이션 시간 동안 센서 상태를 반복해서 읽는 데 낭비하지 않습니다. 기본적으로 스레드는 메인 스크립트가 sim.resumeThreads (sim.scriptthreadresume_default)를 호출 할 때 항상 재개됩니다. 메인 스크립트가 Sensing 단계에 있는 동안만 스레드가 실행되도록 해야하는 경우 API 함수 sim.setThreadResumeLocation을 사용하여 스레드의 재개 위치를 다시 확인할 수 있습니다.
V-REP의 스레드의 코루틴과 같은 동작은 일반 스레드와 구별 될 수 없습니다. 예외적으로 외부 명령 (예 : Lua 라이브러리에서 제공하는 소켓 통신 명령)이 차단되는 경우 V-REP도 차단으로 표시됩니다. 이 경우 다음 예와 같이 비 차단 섹션을 정의 할 수 있습니다.
V-REP의 스레드의 코루틴과 같은 동작은 일반 스레드와 구별 될 수 없습니다. 예외적으로 외부 명령 (예 : Lua 라이브러리에서 제공하는 소켓 통신 명령)이 차단되는 경우 V-REP도 차단으로 표시됩니다. 이 경우 다음 예와 같이 비 차단 섹션을 정의 할 수 있습니다.
sim.setThreadIsFree(true) -- Start of the non-blocking section
http = require("socket.http")
print(http.request("http://www.google.com")) -- this command may take several seconds to execute
sim.setThreadIsFree(false) -- End of the non-blocking section
non-blocking 섹션에서 sim 함수를 호출하지 않도록하십시오. 차단 섹션을 닫는 것을 잊지 마십시오. 그렇지 않으면 V-REP가 중단되거나 훨씬 느리게 실행될 수 있습니다. 또한 V-REP의 스레드 작동에 대한 자세한 내용은 스레드 관련 기능과 블로킹 기능을 참조하십시오.
올바르게 실행하려면 일부 작업을 중단하면 안됩니다 (루프에서 여러 객체를 움직이는 경우). 이 경우 sim.setThreadAutomaticSwitch 기능으로 일시적으로 스레드 스위치를 금지 할 수 있습니다.
올바르게 실행하려면 일부 작업을 중단하면 안됩니다 (루프에서 여러 객체를 움직이는 경우). 이 경우 sim.setThreadAutomaticSwitch 기능으로 일시적으로 스레드 스위치를 금지 할 수 있습니다.
3. 스크립트 시뮬레이션 매개변수(Parameter)
비어있는 매개변수(좌측), 비어있지 않은 매개변수(우측)
매개변수 입력창
스크립트는 sim.getScriptSimulationParameter 함수를 사용하여 매개 변수의 값을 검색하거나 sim.setScriptSimulationParameter 함수를 사용하여 매개 변수의 값을 수정할 수 있습니다. 스크립트 시뮬레이션 매개 변수는 특정 스크립트 간 메시징 목적으로 사용될 수도 있습니다.
• 매개 변수는 비공개입니다. 활성화 된 경우 선택한 매개 변수가 시뮬레이션 중에 표시되지 않습니다 (이 경우 매개 변수는 시뮬레이션 중에 수정되지 않을 가능성이 큽니다).
• 매개 변수는 영구적입니다 : 활성화 된 경우 선택한 매개 변수는 시뮬레이션 종료시 원래 값으로 복원되지 않습니다.
• 매개 변수는 영구적입니다 : 활성화 된 경우 선택한 매개 변수는 시뮬레이션 종료시 원래 값으로 복원되지 않습니다.
4. 콜백함수
콜백 함수
콜백 함수는 시뮬레이션 단계의 특정 상태에서 V-REP에 의해 선택적으로 호출되는 특수 스크립트 함수입니다.
• 다이내믹 콜백 함수는 각 다이나믹 시뮬레이션 단계 전후에 물리 엔진에 의해 호출됩니다.
• 컨택 콜백 기능은 각 컨택 쌍에 대한 물리 엔진에 의해 호출됩니다.
• 공동 콜백 함수는 사용자 지정 공동 제어를 위해 피직스 엔진에 의해 호출됩니다.
콜백 함수는 시뮬레이션 단계의 특정 상태에서 V-REP에 의해 선택적으로 호출되는 특수 스크립트 함수입니다.
• 다이내믹 콜백 함수는 각 다이나믹 시뮬레이션 단계 전후에 물리 엔진에 의해 호출됩니다.
• 컨택 콜백 기능은 각 컨택 쌍에 대한 물리 엔진에 의해 호출됩니다.
• 공동 콜백 함수는 사용자 지정 공동 제어를 위해 피직스 엔진에 의해 호출됩니다.
Recommended topics
5. 스크립트 실행 순서
스크립트가 더 중요하거나 영구적 일수록 나중에 스크립트가 호출되거나 실행된다는 것입니다. 실행 순서는 스크립트 유형을 기반으로합니다. 첫 번째 실행에서 마지막 실행까지 다음과 같은 순서가 있습니다.
1. Threaded 차일드 스크립트(순서는 sim.setThreadResumeLocation을 통해 조정할 수 있습니다)
2. Non-threaded 차일드 스크립트
3. Customization 스크립트
4. add-on 스크립트
예를 들어, 콜백 sysCall_sensing은 차일드 스크립트에서 먼저, 그리고 Customization 스크립트에서, 마지막으로 add-on 스크립트에서 다음 순서로 호출됩니다.
스크립트 유형 내에서 실행 순서는 씬 계층 구조에서 스크립트의 위치 및 다음과 같은 두 가지 스크립트 설정의 함수입니다
스크립트 유형 내에서 실행 순서는 씬 계층 구조에서 스크립트의 위치 및 다음과 같은 두 가지 스크립트 설정의 함수입니다
1) 실행 우선 순위 : 스크립트의 실행 우선 순위를 지정합니다. 실행 우선 순위는 동일한 유형의 스크립트에만 적용되며 장면 계층 구조의 형제 인 스크립트에만 적용됩니다.
[실행 우선 순위 설정에 따른 스크립트 실행 순서]
2) 트리 검색(Tree traversal) : 씬 계층에서 더 아래쪽에 부착 된 스크립트 (차일드 스크립트)와 관련하여 스크립트가 실행될 시기를 지정합니다. 'reverse'를 사용하면 차일드 스크립트가 먼저 실행되고 'forward'를 사용하면 차일드 스크립트가 마지막으로 실행됩니다. 부모와 동일하게 첫 번째 조상 스크립트와 동일한 트리 순회를 사용합니다. 트리 탐색은 동일한 유형의 스크립트에만 관련됩니다. 기본값은 'reverse' 입니다.
[트리 검색 설정에 따른 스크립트 실행 순서]
아래의 다이어그램은 구체적인 예제 씬을 보여줍니다.
Recommended topics
#V-REP 메뉴얼 번역(Main script, Child script, Parameter, Callback, Execution order)
Reviewed by kukanuc
on
3월 17, 2019
Rating:
댓글 없음: