3.6 BasScript 스크립트 클래스
개요
BasScript 는 C++17 에 공개된 구조화 스크립트 생성기입니다.
3.6.1 스크립트 객체 본체
cpp
BasScript()
BasScript(const std::string& scriptName)| 항목 | 설명 |
|---|---|
| 설명 | 스크립트 객체를 생성합니다. |
| 비고 | 스크립트 이름을 지정할 수도 있고 기본 생성자를 사용할 수도 있습니다. |
공개 멤버
| 멤버 | 설명 |
|---|---|
name | 스크립트 이름 |
content | 스크립트 텍스트 행 |
flagIf | IF 닫힘 카운트 |
flagSwitch | SWITCH 닫힘 카운트 |
flagWhile | WHILE 닫힘 카운트 |
indent | 현재 들여쓰기 레벨 |
기본 메서드
cpp
GetScript() -> std::string
SetParam(ParamType type, ValueType valueType, SetParamVal_t value) -> STATUS_CODE
AssignValue(AssignType param1, int32_t index, AssignParam2 param2, AssignValue_t value, int32_t optIndex = 0, int32_t optValue = 0) -> STATUS_CODE| 메서드 | 설명 | 반환 |
|---|---|---|
GetScript | 현재 생성기가 생성한 스크립트 텍스트를 출력합니다. | std::string |
SetParam | 스크립트 파라미터를 설정합니다. | STATUS_CODE |
AssignValue | 값을 대입합니다. | STATUS_CODE |
추가 설명:
BasScript(scriptName)은 다음 두 행을 미리 씁니다:scriptName및SUB main.BasScript()는 빈 스크립트 객체를 생성합니다. 스크립트 헤더가 필요하면 이름을 받는 생성자를 사용합니다.
3.6.2 BasMotion
cpp
MoveJoint(MovePoseType, int32_t, SpeedType, Float64, SmoothType, Float64 = 0.0, const ExtraParam* = nullptr)
MoveLine(MovePoseType, int32_t, SpeedType, Float64, SmoothType, Float64 = 0.0, const ExtraParam* = nullptr)
MoveCircle(MovePoseType, int32_t, MovePoseType, int32_t, SpeedType, Float64, SmoothType, Float64 = 0.0, const ExtraParam* = nullptr)
MoveJump(MovePoseType, int32_t, Float64, Float64, SpeedType, Float64, SmoothType, Float64 = 0.0, const ExtraParam* = nullptr)
MoveJump3(MovePoseType, const std::vector<int32_t>&, Float64, Float64, SmoothType, Float64 = 0.0, const ExtraParam* = nullptr)
MoveJump3cp(MovePoseType, const std::vector<int32_t>&, Float64, SmoothType, Float64 = 0.0, const ExtraParam* = nullptr)| 메서드 | 설명 | 주요 제약 |
|---|---|---|
MoveJoint | 관절 운동 문장 | VALUE 속도 범위 0~100 |
MoveLine | 직선 운동 문장 | VALUE 속도 범위 0~5000 |
MoveCircle | 원호 운동 문장 | VALUE 속도 범위 0~5000 |
MoveJump | Jump 문장 | speedRatio 범위 0~100 |
MoveJump3 | 3점 Jump 문장 | poseIndex.size() 는 반드시 3 이어야 함 |
MoveJump3cp | 3점 연속 Jump 문장 | poseIndex.size() 는 반드시 3 이어야 함 |
공통 제약:
SmoothType::SMOOTH_DISTANCE인 경우smoothDistance범위는 반드시0~1000이어야 합니다.- 유효하지 않은 설정의
ExtraParam이 전달되면 운동 메서드는INVALID_PARAMETER를 반환합니다.
3.6.3 BasLogical
cpp
LogiIf(LogiParam1, int32_t, LogiParam2, LogiValue_t, BooleanOperator = EQ)
LogiElseIf(LogiParam1, int32_t, LogiParam2, LogiValue_t, BooleanOperator = EQ)
LogiElse()
LogiEndIf()
LogiSwitch(LogiParam1, int32_t)
LogiCase(LogiParam2, LogiCaseValue_t)
LogiDefault()
LogiEndSwitch()
LogiWhile(LogiParam1, int32_t, LogiParam2, LogiValue_t, BooleanOperator = EQ)
LogiEndWhile()
LogiGoto(int32_t index)
LogiLabel(int32_t index)
LogiSkipCondition(LogiParam1, int32_t, LogiParam2, LogiValue_t, BooleanOperator = EQ)
LogiBreak()
LogiContinue()| 메서드 | 설명 | 주요 제약 |
|---|---|---|
LogiIf | IF | 레지스터, IO, 리터럴, 문자열, IO 상태 지원 |
LogiElseIf | ELSE IF | 위와 동일 |
LogiElse | ELSE | 없음 |
LogiEndIf | ENDIF | 없음 |
LogiSwitch | SWITCH | 실제 출력은 SELECT |
LogiCase | CASE | OtherType 은 VALUE / STRING 만 지원 |
LogiDefault | DEFAULT | 없음 |
LogiEndSwitch | ENDSELECT | 없음 |
LogiWhile | WHILE | 조건 기준은 LogiIf 와 동일 |
LogiEndWhile | WEND | 없음 |
LogiGoto | GOTO | 대상은 LABELn |
LogiLabel | LABEL | 실제 출력은 스크립트명::LABELn |
LogiSkipCondition | SKIP CONDITION | 좌우 양쪽 모두 MH / MI 를 허용하지 않음 |
LogiBreak | BREAK | 없음 |
LogiContinue | CONTINUE | 없음 |
3.6.4 BasStructure
cpp
Wait(LogiParam1, int32_t, WaitParam2, WaitValue_t, BooleanOperator = EQ)
WaitTime(ValueType, SetParamVal_t)
Pause()
Abort()
Call(const std::string& name)
Run(const std::string& name)
Load(LoadType param, LoadValue_t value)
Unload(LoadType param, LoadValue_t value)
Exec(LoadType param, LoadValue_t value)| 메서드 | 설명 | 주요 제약 |
|---|---|---|
Wait | 조건 대기 | 왼쪽 피연산자는 RegisterType::SR 을 지원하지 않으며, OtherType 은 IO_STATUS 만 지원 |
WaitTime | 시간 대기 | VALUE 는 리터럴을 출력하고, R 은 R[index] 를 출력 |
Pause | 일시 정지 | 없음 |
Abort | 중지 | 없음 |
Call | 스크립트 동기 호출 | 파일 헤더에 IMPORT name 을 자동 삽입 |
Run | 스크립트 비동기 실행 | 없음 |
Load | 로드 | R/SR 는 인덱스를 전달하고, STRING 은 문자열을 전달하며, VALUE 는 숫자 값을 전달 |
Unload | 언로드 | Load 와 동일 |
Exec | 실행 | Load 와 동일 |
3.6.5 BasSocket
cpp
SocketOpen(int32_t index)
SocketClose(int32_t index)
SocketConnect(int32_t index)
SocketSend(int32_t index, StrType msgType, SocketValue_t value)
SocketRecv(int32_t index, int32_t msgLength, StrType msgType, SocketValue_t value)| 메서드 | 설명 | 주요 제약 |
|---|---|---|
SocketOpen | 연결 열기 | 실제 출력은 SOCKET_OPEN SK[index] |
SocketClose | 연결 닫기 | 실제 출력은 SOCKET_CLOSE SK[index] |
SocketConnect | 연결 생성 | 실제 출력은 SOCKET_CONNECT SK[index] |
SocketSend | 전송 | SR 은 정수 인덱스만 받고, STRING 은 문자열만 받음 |
SocketRecv | 수신 | SR 은 정수 인덱스만 받고, STRING 은 문자열만 받음 |
3.6.6 BasModbus
cpp
ModbusReadMH(int32_t, int32_t, int32_t, int32_t, int32_t)
ModbusReadMI(int32_t, int32_t, int32_t, int32_t, int32_t)
ModbusWriteMH(int32_t, int32_t, int32_t, int32_t, ValueType, int32_t)| 메서드 | 설명 | 주요 제약 |
|---|---|---|
ModbusReadMH | MH 읽기 | 결과를 R[rIndex] 에 씁니다. |
ModbusReadMI | MI 읽기 | 결과를 R[rIndex] 에 씁니다. |
ModbusWriteMH | MH 쓰기 | ValueType::R 은 R[index] 를 쓰고, VALUE 는 리터럴을 씁니다. |
3.6.7 BasVision
cpp
VisionFind(const std::string& name)
VisionGetOffset(const std::string& name, int32_t index, int32_t labelIndex)
VisionGetQuantity(const std::string& name, int32_t index)| 메서드 | 설명 | 실제 출력 |
|---|---|---|
VisionFind | 찾기 | VISION_FIND "name" |
VisionGetOffset | 오프셋 | VISION_GET_OFFSET "name" VR[index] GOTO LABEL[labelIndex] |
VisionGetQuantity | 수량 | VISION_GET_QUANTITY "name" R[index] |
3.6.8 ExtraParam
cpp
Acceleration(Float64 value)
Rctp()
Offset(int32_t index)
Tb(Float64 second, const std::string& type, const std::string& name = "", int32_t index = 0, const std::string& status = "")
Skip(int32_t index)
Approach(Float64 departureDist, Float64 approachingDist)| 메서드 | 설명 | 주요 동작 |
|---|---|---|
Acceleration | 추가 가속도 | 1~120 범위를 벗어나도 오류를 내지 않고 100.0 으로 fallback |
Rctp | RTCP 파라미터 | C++ 쪽 이름은 Rctp 이고, 스크립트 출력은 RTCP |
Offset | 오프셋 파라미터 | FRAME_OFFSET PR[index] 출력 |
Tb | TB 파라미터 | " name 이 있는 RUN" 또는 " index+status 가 있는 ASSIGN" 중 하나를 만족해야 하며, 아니면 오류로 표시 |
Skip | Skip 파라미터 | SKIP GOTO LABELn 출력 |
Approach | 이탈/접근 거리 | Jump 계열 명령의 추가 파라미터로만 사용 |
3.6.9 실행 의미
| 항목 | 설명 |
|---|---|
GetScript | 현재 스크립트 텍스트를 반환 |
ExecuteBasScript | 먼저 검증한 뒤 RETURN / END 를 자동 추가 |
| 닫힘 검증 | IF / SWITCH / WHILE 는 반드시 닫혀야 함 |
Call | 스크립트 헤더에 IMPORT name 을 삽입한 뒤 CALL "name" 생성 |
최소 호출 예제
cpp
#include <iostream> // 생성된 스크립트 텍스트를 출력하기 위한 표준 출력 스트림 포함
#include "arm_api.h" // Arm 메인 진입점과 BasScript 생성기 타입 포함
#include "status_code.h" // 생성기 호출 결과를 확인하기 위한 STATUS_CODE 포함
int main() // 예제 프로그램 진입점
{ // 예제 main 함수 시작
Arm arm; // 로봇 세션 객체 생성
STATUS_CODE connectRet = arm.Connect("192.168.110.2", ""); // 컨트롤러에 연결, 티치 펜던트 주소를 비워 기본 규칙 사용
if (connectRet != STATUS_CODE::OK) { // 연결 실패 여부 확인
return 1; // 연결 실패 시 바로 종료
} // 연결 결과 판단 종료
BasScript script("demo.bas"); // 스크립트 이름이 있는 BasScript 생성기 생성
STATUS_CODE waitRet = script.structure.WaitTime( // 시간 대기 문장 하나 추가
ValueType::VALUE, // 대기 시간을 리터럴로 사용
Float64{0.1} // 대기 시간을 0.1초로 설정
); // 대기 문장 생성 호출 종료
if (waitRet != STATUS_CODE::OK) { // 대기 문장 생성 실패 여부 확인
return 1; // 생성 실패 시 오류 코드 반환
} // 대기 문장 결과 판단 종료
STATUS_CODE loadRet = script.structure.Load( // LOAD 문장 하나 추가
LoadType::STRING, // 프로그램 이름을 문자열로 직접 사용
std::string("demo_program") // 로드할 프로그램 이름 설정
); // LOAD 문장 생성 호출 종료
if (loadRet != STATUS_CODE::OK) { // LOAD 문장 생성 실패 여부 확인
return 1; // 생성 실패 시 오류 코드 반환
} // LOAD 문장 결과 판단 종료
std::cout << script.GetScript() << "\n"; // 생성기가 현재 생성한 스크립트 텍스트 출력
// STATUS_CODE execRet = arm.programManager.ExecuteBasScript(script); // 실제 실행은 컨트롤러로 전송되므로 확인 후 주석 해제
return 0; // 예제 정상 종료
} // 예제 main 함수 종료시나리오 예제
아래 여러 코드 조각은 "기본 생성기, 운동 문장, 논리 문장, 흐름 문장, Socket/Modbus/비전" 관점에서 BasScript 생성기 API 를 교차로 다룹니다. 예제는 스크립트 텍스트 생성까지만 보여 줍니다.
기본 생성기와 추가 파라미터
cpp
BasScript script("demo.bas"); // 스크립트 헤더가 있는 생성기 생성
BasScript emptyScript; // 조각만 이어 붙이는 시나리오에 적합한 빈 생성기 생성
ExtraParam extra; // 운동 추가 파라미터 객체 생성
extra.Acceleration(80.0); // 추가 가속도 설정
extra.Rctp(); // RTCP 파라미터 추가
extra.Offset(1); // FRAME_OFFSET PR[1] 추가
extra.Tb(0.1, "RUN", "helper.bas"); // TB RUN 파라미터 추가
extra.Skip(10); // SKIP GOTO LABEL10 파라미터 추가
extra.Approach(10.0, 10.0); // Jump 접근 및 이탈 거리 추가
STATUS_CODE setTfRet = script.SetParam(ParamType::TF_NO, ValueType::VALUE, int32_t{0}); // 툴 좌표계 번호 설정
STATUS_CODE assignRet = script.AssignValue(AssignType::R, 1, OtherType::VALUE, Float64{3.14}); // R[1] 에 리터럴 대입
std::cout << script.GetScript() << "\n"; // 현재 생성기가 생성한 스크립트 텍스트 출력운동 문장 생성
cpp
BasScript script("motion.bas"); // 운동 스크립트 생성을 위한 생성기 생성
ExtraParam extra; // 운동 추가 파라미터 객체 생성
extra.Acceleration(80.0); // 운동 추가 가속도 설정
STATUS_CODE moveJointRet = script.motion.MoveJoint(MovePoseType::PR, 1, SpeedType::VALUE, 20.0, SmoothType::FINE, 0.0, &extra); // 관절 운동 문장 생성
STATUS_CODE moveLineRet = script.motion.MoveLine(MovePoseType::PR, 2, SpeedType::VALUE, 100.0, SmoothType::SMOOTH_DISTANCE, 5.0, &extra); // 직선 운동 문장 생성
STATUS_CODE moveCircleRet = script.motion.MoveCircle(MovePoseType::PR, 2, MovePoseType::PR, 3, SpeedType::VALUE, 100.0, SmoothType::FINE, 0.0, &extra); // 원호 운동 문장 생성
STATUS_CODE moveJumpRet = script.motion.MoveJump(MovePoseType::PR, 4, 100.0, 50.0, SpeedType::VALUE, 20.0, SmoothType::FINE, 0.0, &extra); // Jump 운동 문장 생성
STATUS_CODE moveJump3Ret = script.motion.MoveJump3(MovePoseType::PR, std::vector<int32_t>{1, 2, 3}, 100.0, 50.0, SmoothType::FINE, 0.0, &extra); // 3점 Jump 문장 생성
STATUS_CODE moveJump3cpRet = script.motion.MoveJump3cp(MovePoseType::PR, std::vector<int32_t>{1, 2, 3}, 100.0, SmoothType::FINE, 0.0, &extra); // 3점 연속 Jump 문장 생성조건 및 반복 문장 생성
cpp
BasScript script("logical.bas"); // 논리 스크립트 생성을 위한 생성기 생성
STATUS_CODE ifRet = script.logical.LogiIf(RegisterType::R, 1, OtherType::VALUE, Float64{1.0}, BooleanOperator::EQ); // IF 조건 생성
STATUS_CODE elseIfRet = script.logical.LogiElseIf(RegisterType::R, 1, OtherType::VALUE, Float64{2.0}, BooleanOperator::EQ); // ELSEIF 조건 생성
STATUS_CODE elseRet = script.logical.LogiElse(); // ELSE 생성
STATUS_CODE endIfRet = script.logical.LogiEndIf(); // ENDIF 생성
STATUS_CODE switchRet = script.logical.LogiSwitch(RegisterType::R, 1); // SELECT 생성
STATUS_CODE caseRet = script.logical.LogiCase(OtherType::VALUE, int32_t{1}); // CASE 생성
STATUS_CODE defaultRet = script.logical.LogiDefault(); // DEFAULT 생성
STATUS_CODE endSwitchRet = script.logical.LogiEndSwitch(); // ENDSELECT 생성
STATUS_CODE whileRet = script.logical.LogiWhile(RegisterType::R, 1, OtherType::VALUE, Float64{1.0}, BooleanOperator::EQ); // WHILE 생성
STATUS_CODE continueRet = script.logical.LogiContinue(); // CONTINUE 생성
STATUS_CODE breakRet = script.logical.LogiBreak(); // BREAK 생성
STATUS_CODE endWhileRet = script.logical.LogiEndWhile(); // WEND 생성
STATUS_CODE labelRet = script.logical.LogiLabel(10); // LABEL10 생성
STATUS_CODE gotoRet = script.logical.LogiGoto(10); // GOTO LABEL10 생성
STATUS_CODE skipRet = script.logical.LogiSkipCondition(IOType::DI, 0, OtherType::IO_STATUS, IOStatus::ON, BooleanOperator::EQ); // SKIP 조건 생성흐름 제어 문장 생성
cpp
BasScript script("structure.bas"); // 흐름 스크립트 생성을 위한 생성기 생성
STATUS_CODE waitRet = script.structure.Wait(IOType::DI, 0, OtherType::IO_STATUS, IOStatus::ON, BooleanOperator::EQ); // 조건 대기 생성
STATUS_CODE waitTimeRet = script.structure.WaitTime(ValueType::VALUE, Float64{0.1}); // 시간 대기 생성
STATUS_CODE pauseRet = script.structure.Pause(); // 일시 정지 문장 생성
STATUS_CODE abortRet = script.structure.Abort(); // 중지 문장 생성
STATUS_CODE callRet = script.structure.Call("helper.bas"); // 스크립트 동기 호출 문장 생성
STATUS_CODE runRet = script.structure.Run("helper.bas"); // 스크립트 비동기 실행 문장 생성
STATUS_CODE loadRet = script.structure.Load(LoadType::STRING, std::string("demo_program")); // LOAD 문장 생성
STATUS_CODE unloadRet = script.structure.Unload(LoadType::STRING, std::string("demo_program")); // UNLOAD 문장 생성
STATUS_CODE execRet = script.structure.Exec(LoadType::STRING, std::string("demo_program")); // EXEC 문장 생성Socket, Modbus 및 비전 문장 생성
cpp
BasScript script("io.bas"); // 외부 장치 스크립트 생성을 위한 생성기 생성
STATUS_CODE socketOpenRet = script.socket.SocketOpen(1); // SOCKET_OPEN 생성
STATUS_CODE socketConnectRet = script.socket.SocketConnect(1); // SOCKET_CONNECT 생성
STATUS_CODE socketSendRet = script.socket.SocketSend(1, StrType::STRING, std::string("hello")); // SOCKET_SEND 생성
STATUS_CODE socketRecvRet = script.socket.SocketRecv(1, 32, StrType::SR, int32_t{1}); // SOCKET_RECV 생성
STATUS_CODE socketCloseRet = script.socket.SocketClose(1); // SOCKET_CLOSE 생성
STATUS_CODE readMhRet = script.modbus.ModbusReadMH(0, 1, 0, 2, 1); // MH 읽기 문장 생성
STATUS_CODE readMiRet = script.modbus.ModbusReadMI(0, 1, 0, 2, 2); // MI 읽기 문장 생성
STATUS_CODE writeMhRet = script.modbus.ModbusWriteMH(0, 1, 0, 1, ValueType::VALUE, 10); // MH 쓰기 문장 생성
STATUS_CODE visionFindRet = script.vision.VisionFind("camera"); // 비전 찾기 문장 생성
STATUS_CODE visionOffsetRet = script.vision.VisionGetOffset("camera", 1, 10); // 비전 오프셋 문장 생성
STATUS_CODE visionQuantityRet = script.vision.VisionGetQuantity("camera", 2); // 비전 수량 문장 생성예제 코드
cpp
#include "build_bas_script/run.h"
#include "execute_bas_script/run.h"
int main(void)
{
// [ZH] 默认只调用一个门面方法;如需体验其他接口,请把下一行替换成下面任意一行。
// [EN] The main function calls only one facade by default. Replace the next line with any line below to try other APIs.
return RunBasScriptExecutionBuildBasScript();
// return RunBasScriptExecutionExecuteBasScript();
}