MoonWalker Series Motor Controllers User’s Manual 14. Mini-C 스크립트 언어
MoonWalker Series
Motor Controllers
User’s Manual
MW-MDC24D100S / MW-MDC24D100D
MW-MDC24D200S / MW-MDC24D200D
MW-MDC24D500S / MW-MDC24D500D
※ 사용자 매뉴얼에 포함된 정보는 정확하고 신뢰성이 있는 내용입니다. 그러나 출판 당시 발견되지 않은 오류가 있을 수 있으니 사용자는 자신의 제품 검증을 수행하시기 바라며, 전적으로 사용자 매뉴얼에 포함된 정보에 의존하지 마시기 바랍니다.
14. Mini-C 스크립트 언어
Mini-C 스크립트 언어는 C언어에서와 유사하게 제어기의 프로그래밍을 하도록 하기 위한 C언어의 서브셋으로 설계된 언어입니다. C언어의 제어문과 수식 연산구조를 일부 따오면서 배열이나 함수포인트 등 복잡한 부분을 제거하여 스크립트 언어를 처음 접하는 사용자가 쉽게 배우고 사용할 수 있습니다. 만일 C언어를 알고 있는 사용자라면 “14.2 C언어와의 차이”만 살펴보더라도 바로 사용 가능합니다.
이 장은 스크립트의 기본 구성과 특징에 대하여 설명하고 사용자가 직접 프로그램을 작성할 수 있도록 연산자, 제어문, 내장 함수들에 대하여 예제와 함께 설명합니다.
14.1 스크립트 관련 구성
Mini-C 스크립트 언어를 이용하여 작성한 제어기 프로그램은 Mini-C 스크립트 컴파일러를 사용하여 바이트코드로 변환 되고, 이 바이트코드는 제어기로 다운로드 되어 가상머신에 의해 해석되어 실행됩니다.
Mini-C 스크립트 언어:
Mini-C 스크립트 언어는 C언어의 서브셋으로 제어기의 프로그래밍에 사용되는 언어입니다.
Mini-C 스크립트 컴파일러:
Mini-C 스크립트 언어로 작성된 프로그램을 제어기의 가상머신에서 수행 가능한 바이트코드로 컴파일 합니다. 컴파일러는 Motor Control UI 유틸리티에 내장되어 있습니다.
바이트코드(Bytecode):
바이트코드는 제어기의 가상머신에서 실행될 수 있도록 정의된 중간코드입니다. 스크립트 언어로 작성된 프로그램은 바이트코드로 해석된 다음 제어기에 다운로드 되고 실행됩니다. 이러한 두 단계 구조는 바이트코드에 실행 시 필요한 정보만 담게 되어 스크립트 코드를 직접적으로 인터프리팅 하는 시스템에 비해 수행 성능을 높일 수 있습니다.
가상머신(Virtual Machine):
가상머신은 모터제어기의 마이크로컨트롤러에 포팅되어 있습니다. 가상머신은 바이트코드로 컴파일 된 프로그램을 해석하여 실행합니다.
14.2 C언어와의 차이
Mini-C 스크립트 언어는 C언어의 문법을 참조하여 설계되었습니다. 스크립트 언어는 C언어에서 다음과 같은 것들을 제공하지 않는 서브셋 언어 입니다:
· #define, #ifdef, #if 등의 전처리 문
· 함수의 정의와 선언 (main 함수 포함)
· return 키워드
· int, float, long 등 자료형 키워드
· 문자열 상수 (Ex: “abc”, “ABC”)와 문자 상수 (Ex: ‘a’, ‘A’)
· 배열 연산자([]), 포인터 연산자(*), 주소 참조 연산자(&), 멤버 연산자(., ->)
· sizeof 연산자
· ? : 연산자
· 캐스트 연산자 (Ex: (int), (float) )
· typedef, struct, union, enum 등 자료구조 관련 키워드
· switch, case 분기문 키워드
변수의 선언에 자료형은 사용되지 않으며, 변수는 정수형이나 실수형으로 초기화 하면서 선언됩니다. 다음 변수 선언 예를 참조하기 바랍니다:
· a=123 – 정수형 변수 a를 선언하면서 값 할당
· b=4.567 – 실수형 변수 b를 선언하면서 값 할당
C언어에서 사용되는 다음 분기문과 반복문을 사용 가능합니다:
· if, else – 조건에 따라 정해진 영역의 프로그램을 실행
· goto, label – 특정 프로그램 코드 위치로 무조건 점프
· for – 특정 조건이 완료 될 때까지 특정 영역을 반복 실행
· while – 특정 조건이 만족할 동안 특정 영역을 반복 실행
· do, while – 먼저 특정 영역을 실행하고 조건이 맞으면 이를 반복
· break – 현재 실행하고 있는 반복문 블록을 빠져 나옴
· continue – 현재 실행하고 있는 반복문 블록의 초기로 이동
C언어에서 사용되는 다음 수학 연산자는 사용 가능합니다:
· 산술 연산자: +, -, *, /, %, ++, –
· 관계 연산자: ==, !=, >, <, >=, <=
· 논리 연산자: !, &&, ||
· 비트 연산자: ~, &, |, ^, <<, >>
· 대입 연산자: =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
Mini-C 스크립트 언어에서 사용하는 키워드는 다음과 같습니다:
· if, else, do, for, while, goto, break, continue
Mini-C 스크립트 언어에서는 다음 상수
가 정의되어 있습니다:
· _E, _PI, _EULER, _status, _s, _fault, _f
14.3 문장
스크립트로 작성된 프로그램은 문장(Statement)들로 구성됩니다. 문장은 프로그램을 실행하기 위한 기본적인 실행 단위라고 볼 수 있습니다. 다음 그림 14‑1은 스크립트 프로그램의 구조를 보여주고 있습니다.
그림 14‑1 스크립트 프로그램의 구조 |
14.3.1 수식과 문장
프로그램을 이루는 가장 기본적인 것은 수식입니다. 연산자는 “a = 10″, “a < b”, “a + b”, “a << 4″ 등과 같이 하나의 연산을 행하는 가장 단순한 것입니다. 그리고 단순한 수식이 여러 개가 모여 “a+b*10″, “(a>b) && (b>c)” 등과 같이 복잡한 수식을 이루게 됩니다. 이러한 수식은 하나 또는 그 이상이 모여 하나의 문장을 구성합니다.
스크립트 언어에서는 ‘;’로 문장을 구분합니다. 이렇게 ‘;’로 구분된 각각의 문장을 단일문이라고 합니다. 다음 예제를 참고하십시오.
a = 5; 10*a + 3;
14.3.2 복합문
여러 개의 문장들을 ‘{‘와 ‘}’를 이용하여 하나의 실행단위로 묶어 줄 수 있는데, 이를 블록 또는 복합문(Compound Statement)이라 하고 이 복합문을 하나의 문장으로 다시 고려할 수 있습니다. 다음과 같이 사용하면 복합문이 됩니다.
{
a = 5;
b = 10*a + 3;
}
14.3.3 제어문
스크립트 언어에서는 일정한 형식을 가지고 프로그램의 흐름을 제어하는 문장들도 있습니다. 예를 들자면, 조건을 판단하여 분기하는 if-else 문장 같은 것입니다. 제어문에 대해서는 “14.8 제어문”에서 상세하게 설명합니다.
14.4 주석
스크립트 언어에서 주석문(Comment)은 ‘/*’ 와 ‘*/’사이 또는 ‘//’뒤에 기술하며, 컴파일 대상에서 제외됩니다. 주석문은 주로 프로그램의 이해를 증진시키기 위해 사용합니다. 스크립트 프로그램 내에 주석문을 나타내기 위해, C언어에서 사용하는 것과 동일한 두 가지 방법을 제공합니다.
14.4.1 블록 주석문
블록 주석은 ‘/*’과 ‘*/’로 둘러 싸인 주석문을 말합니다. 이러한 블록 주석문은 한 라인 또는 두 라인 이상을 주석으로 처리할 수 있으며 다음과 같이 사용할 수 있습니다.
/*
블록 주석 내용1
블록 주석 내용2
…
*/
14.4.2 라인 주석문
라인 주석은 ‘//’를 사용하여 나타내며, ‘//’가 한 라인의 어디에 나와도 상관없고, ‘//’이 나온 후부터 그 라인의 끝까지 주석으로 처리하게 됩니다. 라인 주석문은 다음과 같이 사용할 수 있습니다.
// 라인 주석 내용1
// 라인 주석 내용2
14.5 상수
상수는 한번 값이 결정되면 프로그램이 실행되는 동안 새로운 값으로 변경할 수 없는 정보를 말합니다. 스크립트 언어에서 사용되는 상수(리터럴 혹은 리터럴 상수)는 정수형과 실수형(부동 소수; floating point), 미리 정의된 상수로 구분됩니다.
스크립트 언어는 부울형(TRUE, FALSE)이나 문자 상수(‘A’, ‘a’), 문자열 상수(“abc”, “DEF”)를 지원하지 않습니다.
14.5.1 정수형 상수
정수형 상수는 스크립트 언어에서 사용되는 가장 기본적인 형태의 상수입니다. 메모리에 저장될 때는 32bit 크기를 가지며 범위는 -231 과 231-1 사이가 됩니다.
다음과 같이 사용되면 정수형 상수로 인식됩니다.
10, -10, 999 // 10진수로 표현된 정수형 상수
05, 011, -077 // 8진수로 표현된 정수형 상수
0×11, -0×11, 0xFF // 16진수로 표현된 정수형 상수
상기 예에서와 같이 정수형 상수는 8진수, 10진수, 그리고 16진수 등 세가지 진법으로 표현할 수 있습니다:
· 8진수 : ’0′으로 시작하는 정수형 상수, ’0′ 다음에는 ’0′에서 ’7′까지의 8진수 숫자들이 옴
· 10진수: 일반적으로 사용하는 정수형 상수, ’0′에서 ’9′까지의 10진수 숫자들로 표현
· 16진수: ’0x’ 또는 ’0X’로 시작하는 정수형 상수, ’0x’ 또는 ’0X’ 다음에는 ’0′에서 ’9′와 ‘A’ 또는 ‘a’에서 ‘F’ 또는 ‘f’ 등 16진수 숫자들이 옴
10진수는 양수, 0, 음수가 있습니다. 스크립트에서 10진수를 사용할 때 0으로 시작해서는 안됩니다. 예를 들면 01234라고 쓰면 이것은 10진수가 아닙니다. 10진수는 0을 제외한 나머지 숫자로 시작하고 그 뒤로는 0부터 9까지의 숫자가 올 수 있습니다. 0으로 시작되는 숫자는 스크립트에서는 8진수나 16진수를 의미합니다.
14.5.2 실수형 상수
실수형 상수는 부동소수 값을 표현할 수 있습니다. 메모리에 저장될 때는 IEEE 754 표준에 따라 64bit 크기를 가지며 범위는 음수일 때 -1.79769313486231E+308 과 -4.9406564584124E-308 사이고 양수일 때 4.9406564584124E-308 과 1.79769313486231E+308 사이가 됩니다.
다음과 같이 사용되면 실수형 상수가 됩니다.
1.234, -1.234, 123. // 고정 소수점으로 표기된 실수형 상수
1.234e3, 1.234e-3 // 부동 소수점으로 표기된 실수형 상수
상기 예에서와 같이 실수형 상수의 가장 간단한 표기법으로는 소수점을 기준으로 왼쪽에 정수부 오른쪽에 소수부를 적는 고정 소수점 표기법을 사용하는 것입니다. 예로 숫자 5를 쓸 때, 5라고 쓰면 정수형 상수가 됩니다. 실수형 상수임을 나타내려면 5.0이라고 쓰거나 0을 생략하고 5.라고 써야 합니다.
또 다른 표기법으로 e를 기준으로 왼쪽에 가수 오른쪽에 지수를 적는 부동 소수점 표기법이 있습니다. 숫자 중간에 나오는 e(또는 E)는 부동 소수의 지수부분을 의미합니다. 실수는 내부적으로 모두 부동 소수점 방식으로 기억되지만 상수를 표현할 때는 고정 소수점과 부동 소수점 표기법을 모두 사용할 수 있습니다.
14.5.3 미리 정의된 상수
다음은 스크립트 언어에서 미리 정의된 수학 상수입니다. 수학 상수는 프로그램이 컴파일 될 때, 실수형 상수로 바뀌게 됩니다.
표 14‑1 정의된 수학 상수
상수 | 값 | 설명 |
_E | 2.7182818284590452354 | 자연상수 |
_PI | 3.14159265358979323846 | 원주율 |
_EULER | 0.57721566490153286061 | 오일러-마스케로니 상수 |
수학 상수는 다음과 같이 사용할 수 있습니다.
a = sin(_PI/2); // a는 1을 가짐
b = cos(_PI/2); // b는 0을 가짐
또한 사용자가 제어기의 오브젝트를 참조하는 오브젝트 Index를 프로그램 작성시 쉽게 사용할 수 있도록 오브젝트 이름에 대한 상수를 정의하고 있습니다. 이 상수는 오브젝트의 Long Name과 Short Name 앞에 밑줄 문자 ‘_’를 추가하여 정의됩니다.
표 14‑2 스크립트에서 사용 가능한 상수
Long Name, Short Name |
Index |
Description |
_vendor_id, _vid |
1 |
제품 공급자 ID |
_product_id, _pid |
2 |
제품 ID |
_software_version, _swv |
3 |
제어기 펌웨어 버전 |
_hardware_version, _hwv |
4 |
제어기 하드웨어 버전 |
_system_status, _sst |
5 |
제어기의 운용 상태 |
_system_command, _sco |
7 |
제어기에 내려지는 명령 |
_battery_voltage, _bv |
8 |
전원 소스로부터 제어기에 공급되는 전압 (단위: V) |
_battery_current, _bc |
9 |
전원 소스로부터 제어기를 통해 흐르는 전류 (단위: A) |
_device_id, _id |
11 |
장치 ID |
_can_br, _cb |
12 |
CAN 통신 속도 |
_serial_bps, _sb |
13 |
USB/RS-232의 통신 속도 |
_serial_watchdog, _sw |
14 |
CAN, USB, RS-232 포트로 수신되는 명령어 패킷에 대한 와치독 타이머 타임아웃 값 (단위: ms) |
_startup_script_run, _ssr |
16 |
제어기 시작 시 스크립트의 실행 여부 |
_control_mixing, _cm |
21 |
두 모터에 내려지는 속도/전압 명령의 믹싱 모드 |
_center_safety, _cs |
22 |
모터에 내려지는 속도/전류/전압 명령의 Center Safety |
_min_max_safety, _ms |
23 |
모터에 내려지는 속도/전류/전압 명령의 MinMax Safety |
_pwm_switching, _ps |
31 |
PWM 스위칭 방법 |
_pwm_frequency, _pf |
32 |
PWM 주파수 |
_user_value, _uv |
56 |
사용자가 읽고 쓰는 변수들, 플래시 메모리에 저장됨 |
_temp_value, _tv |
57 |
사용자가 읽고 쓰는 변수들, RAM에만 저장됨 |
_num_di, _ndi |
60 |
디지털 입력 채널의 수 |
_di_enable, _die |
61 |
각 비트별 해당 디지털 입력 채널의 사용 여부 |
_di_invert, _dii |
62 |
각 비트별 해당 디지털 입력 채널의 반전 여부 |
_di_all_values, _di |
63 |
디지털 입력을 하나의 32bit 값으로 모음 |
_num_do, _ndo |
65 |
디지털 출력 채널의 수 |
_do_enable, _doe |
66 |
각 비트별 해당 디지털 출력 채널의 활성화 여부 |
_do_invert, _doi |
67 |
각 비트별 해당 디지털 출력 채널의 반전 여부 |
_do_all_values, _do |
68 |
디지털 출력을 하나의 32bit 값으로 모음 |
_num_ai, _nai |
70 |
아날로그 입력 채널의 수 |
_ai_enable, _aie |
71 |
각 비트별 해당 아날로그 입력 채널의 활성화 여부 |
_ai_invert, _aii |
72 |
각 비트별 해당 아날로그 입력 채널의 극성 반전 여부 |
_num_pi, _npi |
75 |
펄스 입력 채널의 수 |
_pi_enable, _pie |
76 |
각 비트별 해당 펄스 입력 채널의 활성화 여부 |
_pi_invert, _pii |
77 |
각 비트별 해당 펄스 입력 채널의 극성 반전 여부 |
_num_motors, _nm |
80 |
제어기에 연결 가능한 모터의 수 |
_wheel_radius, _wr |
86 |
이동로봇의 바퀴 반지름 (단위: m) |
_axle_length, _al |
87 |
이동로봇 좌우 바퀴간 거리 (단위: m) |
_gear_ratio, _gr |
88 |
모터와 바퀴간 감속비율 (모터 회전수/바퀴 회전수) |
_m_position, _mp |
91 |
모터 채널 1,2의 엔코더 값을 읽음 (단위: pulse, pulse) |
_m_position_command, _mpc |
92 |
모터 채널 1,2의 위치구동 명령을 내리고(단위: pulse, pulse) 엔코더 값을 읽음(단위: pulse, pulse) |
_m_velocity_command, _mvc |
93 |
모터 채널 1,2의 속도 구동 명령을 내리고(단위: RPM, RPM) 엔코더 값을 읽음(단위: pulse, pulse) |
_m_current_command, _mcc |
94 |
모터 채널 1,2의 전류 구동 명령을 내리고(단위: A, A) 전류 값을 읽음 (단위: A, A) |
_m_voltage_command, _mvtc |
95 |
모터 채널 1,2의 전압 구동 명령을 내리고(단위: V, V) 엔코더 값을 읽음(단위: pulse, pulse) |
_m_lav_command, _mla |
96 |
전진속도와 각속도로 이동로봇의 구동 명령을 내리고(단위: m/s, rad/s) 모터 1,2의 엔코더 값을 읽음(단위: pulse, pulse) |
_status, _s |
102 |
모터제어기의 현재 상태 |
_fault, _f |
103 |
모터제어기 및 관련 I/O에서 발생한 폴트 |
_command, _co |
101 |
모터제어기에 내려지는 명령 코드 |
_position_command, _pc |
111 |
모터의 폐루프 위치 제어 명령 (단위: pulse) |
_velocity_command, _vc |
112 |
모터의 폐루프 속도 제어 명령 (단위: RPM) |
_current_command, _cc |
113 |
모터의 폐루프 전류 제어 명령 (단위: A) |
_voltage_command, _vtc |
114 |
모터에 인가되는 전압 출력 (단위: V) |
_temperature, _tp |
121 |
FET와 방열판의 온도 (단위: °C) |
_voltage, _vt |
122 |
모터에 가해지는 전압 (단위: V) |
_current, _c |
123 |
모터에 흐르는 전류 (단위: A) |
_velocity, _v |
124 |
모터의 회전속도 (단위: RPM) |
_position, _p |
125 |
모터의 회전위치 (단위: pulse) |
_hall_count, _h |
126 |
BLDC 모터의 홀 센서 카운트 값 (단위: pulse) |
_ai_potentiometer, _pt |
131 |
아날로그 입력 포트에 매핑된 위치 센서의 피드백 값 |
_ai_tachometer, _ta |
132 |
아날로그 입력 포트에 매핑된 속도 센서의 피드백 값 |
_min_position, _np |
141 |
모터가 이동 가능한 최소 위치 (단위: pulse) |
_max_position, _xp |
142 |
모터가 이동 가능한 최대 위치 (단위: pulse) |
_home_position, _hp |
143 |
홈센서 감지 시 position에 로드 되는 위치 값 설정 (단위: pulse) |
_encoder_ppr, _ep |
144 |
모터 1회전당 엔코더 펄스 수 (단위: pulse/rev) |
_num_pole_pairs, _npp |
145 |
BLDC 모터에서 홀센서의 폴페어 수 (단위: pulse/rev) |
_use_soft_limit, _usl |
146 |
소프트 리미트 스위치 사용 여부 |
_max_current, _xc |
151 |
모터에 흐르는 최대 연속 전류 (단위: A) |
_max_voltage, _xvt |
152 |
모터에 가해지는 최대 전압 (단위: V) |
_max_velocity, _xv |
153 |
모터의 최대 회전 속도 (단위: RPM) |
_acceleration, _ac |
154 |
모터의 회전 가속도 (단위: RPM/s) |
_deceleration, _dc |
155 |
모터의 회전 감속도 (단위: RPM/s) |
_overheat_limit, _ohl |
161 |
FET와 방열판의 과열 한계 (단위: °C) |
_overcurrent_limit, _ocl |
162 |
모터의 과전류 한계 (단위: A) |
_overcurrent_delay, _ocd |
163 |
과전류 허용 지연 시간 (단위: ms) |
_peakcurrent_ratio, _pcr |
164 |
모터의 순간 피크 전류 (단위: %) |
_overvoltage_limit, _ovl |
165 |
전원단의 과전압 한계 (단위: V) |
_undervoltage_limit, _uvl |
166 |
전원단의 저전압 한계 (단위: V) |
_stall_detection, _sd |
167 |
모터의 구동 명령에 대해 움직이지 않는 상황 감지 |
_vel_error_detection, _ved |
168 |
폐루프 속도제어기에서 명령과 피드백 사이의 오차에 의한 이상 감지 |
_pos_error_detection, _ped |
169 |
폐루프 위치제어기에서 명령과 피드백 사이의 오차에 의한 이상 감지 |
_feedback_sensor, _fs |
171 |
제어기 피드벡 센서 선택 |
_profile_mode, _pm |
172 |
속도 명령에 사다리꼴 프로파일 적용여부 |
_startup_power_on, _spo |
173 |
제어기가 시작될 때 모터 Power ON/OFF 설정 |
_direction, _dir |
174 |
모터의 정방향/역방향 회전 설정 |
_brake_on_delay, _bod |
175 |
브레이크 작동 시 지연시간 설정 (단위: ms) |
_high_voltage, _hv |
176 |
제동저항(Brake Resistor)을 켜는 전압 설정 (단위: V) |
_high_temperature, _ht |
177 |
냉각 팬을 켜는 온도 설정 |
_cc_kp, _cp |
181 |
PI 전류제어기의 비례제어 이득 |
_cc_ki, _ci |
182 |
PI 전류제어기의 적분제어 이득 |
_cc_kff, _cff |
185 |
PI 전류제어기의 모터 회전속도 전향 보상 이득 |
_vc_kp, _vp |
186 |
PI 속도제어기의 비례제어 이득 |
_vc_ki, _vi |
187 |
PI 속도제어기의 적분제어 이득 |
_vc_ks, _vs |
190 |
속도 레퍼런스에 대한 스케일 펙터 |
_pc_kp, _pp |
191 |
PID 위치제어기의 비례제어 이득 |
_pc_ki, _pi |
192 |
PID 위치제어기의 적분제어 이득 |
_pc_kd, _pd |
193 |
PID 위치제어기의 미분제어 이득 |
_di_value, _div |
201 |
디지털 입력 채널의 값 |
_di_function, _dif |
202 |
디지털 입력 채널을 특정 모터의 동작으로 매핑 |
_do_value, _dov |
211 |
디지털 출력 채널의 값 (0 or 1) |
_do_function, _dof |
212 |
디지털 출력 채널을 특정 모터의 상태로 매핑 |
_ai_value, _aiv |
221 |
아날로그 입력 채널의 원시 값 |
_ai_converted_value, _aicv |
222 |
변환 과정을 거쳐 정규화된 값 |
_ai_linearity, _ail |
223 |
지수/로그 변환 형식 지정 |
_ai_function, _aif |
224 |
아날로그 입력을 특정 모터의 명령이나 피드백과 매핑 |
_ai_input_min, _ain |
225 |
캘리브레이션: 입력 최소값 |
_ai_input_center, _aic |
226 |
캘리브레이션: 입력 중앙값 |
_ai_input_max, _aix |
227 |
캘리브레이션: 입력 최대값 |
_ai_input_deadband, _aidb |
228 |
캘리브레이션: 입력의 데드밴드 값 |
_pi_value, _piv |
231 |
펄스 입력 채널의 원시 값 |
_pi_converted_value, _picv |
232 |
변환 과정을 거쳐 정규화 된 값 |
_pi_capture_type, _pit |
233 |
펄스 캡쳐의 종류 |
_pi_linearity, _pil |
234 |
지수/로그 변환 형식 지정 |
_pi_function, _pif |
235 |
펄스 입력을 특정 모터의 명령이나 피드백과 매핑 |
_pi_input_min, _pin |
236 |
캘리브레이션: 입력 최소값 |
_pi_input_center, _pic |
237 |
캘리브레이션: 입력 중앙값 |
_pi_input_max, _pix |
238 |
캘리브레이션: 입력 최대값 |
_pi_input_deadband, _pidb |
239 |
캘리브레이션: 입력의 데드밴드 값 |
_script_size, _ss |
250 |
바이트코드를 다운로드하기 전에 크기 전송 (단위: byte) |
_script_code, _sc |
251 |
바이트코드를 4-byte씩 묶어서 차례로 전송 |
_script_variable, _sv |
252 |
스크립트가 실행되는 동안 사용되는 변수 |
오브젝트이름 상수는 다음과 같이 사용할 수 있습니다.
v = getv (_temp_value, 1)/1000;
w = getv (_temp_value, 2)/1000;
setv (_velocity_command, 1, v+w);
setv (_velocity_command, 2, v-w);
14.6 변수
변수는 프로그램이 실행되는 동안 처리되는 데이터를 임시 저장하는 메모리 공간입니다. 변수는 프로그램이 시작될 때 모두 0으로 초기화 됩니다.
14.6.1 변수명
변수명을 만들 때 사용 가능한 문자는 대문자, 소문자, 숫자, 밑줄문자(‘_’)입니다. 이 중 숫자는 변수명의 처음 문자로 올 수 없습니다. 변수명은 다음과 같은 규칙에 의해 사용자가 정합니다:
· 영문자(‘a’~'z’, ‘A’~'Z’), 숫자(’0′~’9′), 밑줄문자 ‘_’로 구성되며, 첫 글자는 반드시 영문자 또는 밑줄문자 ‘_’가 되어야 함
· 대문자와 소문자는 서로 다른 문자로 인식함
· 예약어(for, while, do, …)와 미리 정의된 상수(_PI, _E, _status, _s, …)는 변수명으로 사용할 수 없음
변수 명은 다음과 다음과 같이 만들 수 있습니다.
abc, abc123, _123, ABC, ABCdef
14.6.2 변수의 선언과 초기화
변수의 선언에 자료형은 사용되지 않으며, 변수에 상수가 대입될 때와 같이 정수형이나 실수형으로 초기화 되면서 자료형이 결정됩니다. 변수는 자료형을 결정하는 내부 파라미터를 가지며, 변수의 사용처에 따라 혹은 변수에 저장되는 값의 자료형에 따라 변수의 자료형이 결정됩니다.
변수를 선언할 때 초기화 하지 않으면 컴파일러는 변수를 사용하는 것으로 인식합니다. 그래서 선언되지 않은 변수가 사용되었다는 에러를 발생합니다. 다음 예제를 참고하십시오.
a = 123; // 변수 a는 정수형 변수가 됨
b = 1.23; // 변수 b는 실수형 변수가 됨
c; // c는 에러 발생, 변수가 선언될 때는 항상 초기화 되어야 함
변수의 범위는 프로그램 전체에 연장되어있습니다. 변수는 한 번 이상 프로그램에서 선언 할 수 없습니다.
14.6.3 자료형 변환
스크립트에서 사용되는 값들에 대해 필요에 따라 서로 형변환이 가능하도록 합니다. 스크립트에서는 내부적으로 형변환은 자동으로 수행하는 묵시적 형변환(Implicit conversion)을 사용합니다.
그림 14‑2 스크립트에서의 자료 형변환 |
C언어에서는 데이터의 손실이 없이 안정적으로 형변환이 가능할 경우에만 내부적으로 자동으로 묵시적 형변환을 수행하고, 데이터의 손실을 야기하는 소지가 있는 경우에는 자동으로 형변환하는 것을 방지합니다. 하지만 스크립트에서는 언어를 간단히 하기 위해 실수형에서 정수형으로의 변환도 묵시적으로 이루어집니다. 실수형에서 정수형으로의 형변환 될 때는 실수형 숫자에 가장 가까운 정수형 숫자를 선택하여 변환 됩니다.
다음 예는 실수에서 정수로 묵시적 형변환이 발생하는 경우입니다. 나머지 연산자(%)는 피연산자로 정수형을 취하기 때문에, 수식 내의 실수형 리터럴은 정수형으로 묵시적 형변환되어 연산됩니다.
a = 10 % 3; // 결과는 1
b = 10.33 % 3; // 10%3과 동일
실수에서 정수로 명시적 형변환이 필요한 경우에는 내장함수 int()를 사용할 수 있습니다. 다음 예를 참고하십시오.
a = int(1.44); // a는 1
b = int(1.55); // b는 2
14.7 연산자
연산자는 피연산자와의 조합으로 수식을 만들어냅니다. 스크립트 언어에서는 C언어에서 지원하는 모든 수학 연산자를 사용할 수 있습니다.
14.7.1 산술, 부호 연산자
스크립트 언어에서는 산술 연산을 표현할 수 있도록 산술 연산자를 제공합니다. 더하기는 ‘+’, 빼기는 ‘-’, 곱하기는 ‘*’, 나누기는 ‘/’, 나머지 연산은 ‘%’ 기호를 사용하여 각각의 연산을 표현합니다. ‘%’ 연산자의 피연산자로 실수형을 취할 수 없는데, 이때는 실수형을 정수형으로 묵시적 형변환 한 후 연산이 수행됩니다.
수식에 대한 부호를 나타내기 위해 ‘+’ 및 ‘-’ 등과 같은 부호 연산자를 사용합니다. 부호 연산자는 피연산자를 하나만 취하는 단항 연산자이고, 산술연산자는 두 개의 피연산자를 취하는 이항 연산자입니다.
산술 연산자와 부호 연산자에 대해 정리하면, 다음과 같습니다.
분류 |
연산자 |
연산식 |
예제 |
설명 |
|
연산식 |
결과 |
||||
이항 연산자 |
+ |
a + b |
7 + 5 |
13 |
a와 b를 더하기 |
- |
a – b |
7 – 5 |
2 |
a에서 b를 빼기 |
|
* |
a * b |
7 * 5 |
35 |
a와 b를 곱하기 |
|
/ |
a / b |
7 / 5 |
1 |
a를 b로 나누기 |
|
% |
a % b |
7 % 5 |
2 |
a를 b로 나눈 나머지 |
|
단항 연산자 |
+ |
+a |
+7 |
7 |
a가 양의 수임을 나타냄 |
- |
-a |
-7 |
-7 |
a의 부호를 바꿈 |
14.7.2 증감 연산자
증감 연산자는 변수의 값을 1씩 증가 또는 감소시킨 후, 변화된 값을 다시 그 변수에 저장하는 연산자이고, 하나의 피연산자를 취하는 단항 연산자입니다. 증가 연산자는 1씩 증가시키고, 감소 연산자는 1씩 감소시킨다는 것 외에 동일합니다.
이러한 증감 연산자는 사용되는 위치에 따라 전위형과 후위형 두 가지로 나눌 수 있습니다. 전위형으로 나타내면 변수의 값에 대해 먼저 증감 연산을 수행한 후, 변화된 변수의 값을 참조하여 그 변수가 포함된 연산식에 적용됩니다. 후위형으로 나타내면 변수의 값을 참조하여 연산식에 먼저 적용을 한 후, 변수의 값에 대해 증감 연산을 수행합니다.
증감 연산자에 대해 정리하면 다음과 같습니다.
분류 |
연산자 |
연산식 |
예제 |
설명 |
단항 |
++ |
a++ |
num++ |
a값을 참조 후 1증가 |
++a |
++num |
a값을 1증가 후 참조 |
||
– |
a– |
num– |
a값을 참조 후 1감소 |
|
–a |
–num |
a값을 1감소 후 참조 |
증감 연산자의 사용시 다음 사항에 주의해야 합니다. 한 변수가 수식 내에 두 번 이상 사용될 경우 증감 연산자를 사용하지 않는 것이 바람직합니다. 물론, 값의 변화를 모두 정확히 추정하여 미리 계산하고 나서 사용한다면 상관 없겠지만, 그렇지 않은 경우에는 사용자의 의도와는 다른 결과를 야기할 수 있으므로 조심해야 합니다.
14.7.3 관계 연산자
관계 연산자는 관계를 따져보기 위한 연산자입니다. 이러한 관계 연산자는 두 개의 피연산자를 필요로 합니다. 두 개의 피연산자에 대해 관계 연산자가 의미하는 관계를 따져보고, 그 결과는 0 또는 1 값을 가집니다. 따라서 이러한 관계 연산자로 표현된 조건식을 ‘boolean-식’이라 할 수 있습니다.
스크립트 언어에서 다음과 같은 관계 연산자들을 제공합니다.
연산자 |
연산식 |
예제 |
설명 |
|
연산식 |
결과 |
|||
> |
a > b |
3 > 7 |
0 |
a가 b보다 크면 참 |
>= |
a >= b |
3 >= 7 |
0 |
a가 b보다 크거나 같으면 참 |
< |
a < b |
3 < 7 |
1 |
a가 b보다 작으면 참 |
<= |
a <= b |
3 <= 7 |
1 |
a가 b보다 작거나 같으면 참 |
== |
a == b |
3 == 7 |
0 |
a와 b가 같으면 참 |
!= |
a != b |
3 != 7 |
1 |
a와 b가 다르면 참 |
14.7.4 논리 연산자
논리 연산자는 논리값에 대한 논리적인 연산을 수행하도록 해 주는 연산자를 말하고, 이러한 논리 연산자를 사용하는 식을 논리식이라 합니다. 논리 연산자는 TRUE(1) 또는 FALSE(0)와 같은 논리값을 사용하여 논리 연산을 수행하고, 그 결과 역시 마찬가지로 TRUE 또는 FALSE의 논리값이 됩니다. 이러한 논리식 역시 조건식과 마찬가지로 boolean-식이라 할 수 있습니다.
스크립트 언어에서 사용 가능한 논리 연산들은 다음과 같습니다.
연산자 |
연산식 |
예제 |
설명 |
|
연산식 |
결과 |
|||
! |
!a |
!1 |
0 |
a가 거짓(false; 0)이면 참(true; 1) |
&& |
a && b |
0&&1 |
0 |
a와 b가 모두 참이면 참 |
|| |
a || b |
1||0 |
1 |
a가나 b 둘 중 하나라도 참이면 참 |
논리합 연산자(‘&&’)에서 a가거짓이면 b를 평가하지 않습니다. 그리고 논리곱 연산자(‘||’)에서 a가 참이면 b를 평가하지 않습니다.
14.7.5 비트 연산자
비트 연산자는 비트 단위의 연산을 수행합니다. 피연산자로 실수형을 제외한 정수형 데이터를 취합니다. 이러한 비트 연산자에는 1의 보수 연산, AND, OR, XOR 등과 같은 비트 연산과 왼쪽/오른쪽 비트 이동을 위한 연산자가 있습니다:
· 1의 보수 연산자(‘~’)는 각 비트에 대해 0은 1로 1은 0으로 바꿈
· AND 연산자(‘&’)는 주로 데이터의 특정 비트를 0으로 만들기(mask off) 위해 사용되고, 두 개의 피연산자에 대해 대응하는 두 비트 중 하나라도 0이면 결과도 0이 됨
· OR 연산자(‘|’)는 주로 어떤 데이터의 특정 비트를 1로 만들기(mask on) 위해서 사용하며, 이때 두 개의 피연산자에 대해 대응하는 두 비트 중 어느 하나라도 1이면 결과 비트는 1이 됨
· XOR 연산자(‘^’)는 두 개의 피연산자에 대해 대응하는 두 비트가 서로 다르면 결과 비트가 1이 됨
· 쉬프트 연산자(‘<<’, ‘>>’)는 주어진 자릿수 만큼 왼쪽 또는 오른쪽으로 비트열을 쉬프트 함
이러한 비트 연산자를 정리하면 다음과 같습니다.
연산자 |
연산식 |
예제 |
설명 |
|
연산식 |
결과 |
|||
>> |
a>>b |
10001100 >> 1 |
11000110 |
a를 b만큼우측으로 비트 이동 |
<< |
a<<b |
10110000 << 1 |
01100000 |
a를 b만큼좌측으로 비트 이동 |
& |
a&b |
11000110 & 00001111 |
00000110 |
a와 b의 비트 단위의 논리곱 |
| |
a|b |
11000110 | 00001111 |
11001111 |
a와 b의 비트 단위의 논리합 |
^ |
a^b |
10111011 ^ 10101000 |
00010011 |
a와 b의 비트단위의 XOR |
~ |
~a |
~10110110 |
01001001 |
a에 대하여 비트 단위의 보수 |
‘<<’ 연산자를 쓸 경우 쉬프트 연산의 결과로 오른쪽에 생긴 빈자리 부분은 0으로 채웁니다.
‘>>’ 연산자를 사용하여 쉬프트 연산을 수행한 후 왼쪽에 생긴 빈자리에는 MSB 즉, 최상위 비트인 부호비트가 복사됩니다.
14.7.6 대입 연산자
대입연산자는 우변에 있는 수식의 값을 좌변이 가리키고 있는 메모리의 위치에 저장(대입)하기 위해 사용하는 연산자입니다. 이때, 좌변에 오는 것을 좌변값(l-value)이라고 하는데, 좌변값에 올 수 있는 것으로는 변수와 같이 메모리에 저장 공간을 가지는 것들만 가능합니다. 스크립트 언어에서의 ‘=’은 수학에서의 “같음”의 의미가 아닌 “대입“의 의미를 가집니다.
대입을 허용하는 경우와 그렇지 않은 경우에 대해 다음 예제를 참고하시기 바랍니다.
· a + 1 = b; // 허용하지 않음, 컴파일시 에러 발생
· 2 = b; // 허용하지 않음, 컴파일시 에러 발생
· a = 100; // 100을 변수 a에 대입
· b = a + 20; // 변수 a에 20을 더하여 변수 b에 대입
· a = b = c = 100; // 100을 a, b, c에 대입
스크립트 언어에서 사용 가능한 대입식과 단축 대입식은 다음과 같습니다.
연산자 |
연산식 |
예제 |
설명 |
= |
a = b |
n = 1; |
일반 대입식 |
+= |
a += b |
n = n + 1; à n += 1; |
a = a + b |
-= |
a -= b |
n = n – 1; à n -= 1; |
a = a – b |
*= |
a *= b |
n = n * 1; à n *= 1; |
a = a * b |
/= |
a /= b |
n = n / 1; à n /= 1; |
a = a / b |
%= |
a %= b |
n = n % 1; à n %= 1; |
a = a % b |
&= |
a &= b |
n = n & 1; à n &= 1; |
a = a & b |
|= |
a |= b |
n = n | 1; à n |= 1; |
a = a | b |
^= |
a ^= b |
n = n ^ 1; à n ^= 1; |
a = a ^ b |
<<= |
a <<= b |
n = n << 1; à n <<= 1; |
a = a << b |
>>= |
a >>= b |
n = n >> 1; à n >>= 1; |
a = a >> b |
14.7.7 연산자 우선순위
연산자 우선순위는 서로 다른 연산자들 사이의 수행 순서를 결정합니다. 예를 들자면, “a+b*c”와 같은 수식에서 ‘*’ 연산을 ‘+’ 연산보다 먼저 수행하는 것입니다.
연산자 결합성은 같은 우선 순위의 연산자가 두 개 이상 연속적으로 나올 경우, 이들 간의 우선 순위를 결정합니다.
예를 들자면, “a+b+c”와 같이 ‘+’ 연산자와 ‘+’ 연산자가 순서대로 두 개 이상 나올 경우 왼쪽에 있는 “a+b” 연산을 “b+c” 연산보다 먼저 수행합니다.
다음 표는 스크립트 언어에서 사용하는 연산자들에 대해 연산자 우선순위와 연산자 결합성을 보여주고 있습니다.
우선순위 |
연산자 |
결합법칙 |
기본연산자 |
[ ] . ( ) ++ — |
ß |
전치 |
+ – ++ — ~ ! |
à |
승제 |
* / % |
à |
가감 |
+ – |
à |
비트 이동 |
<< >> |
à |
관계 |
< <= > >= |
à |
등식 |
== != |
à |
비트 AND |
& |
à |
비트 XOR |
^ |
à |
비트 OR |
| |
à |
논리곱 |
&& |
à |
논리합 |
|| |
à |
대입 |
= *= /= %= += -= <<= >>= >>>= &= ^= |= |
ß |
스크립트에서 정의하고 있는 연산자 우선순위와 연산자 결합성은 C언어에서 정의하고 있는 것과 동일하며, 스크립트에서는 포인터를 사용하지 않으므로 C언어에서 포인터 연산을 위해 사용하는 구조체 포인터의 항목 참조 연산자(->), 주소 연산자(&), 간접연산자(*) 등은 제공되지 않습니다.
14.8 제어문
스크립트 프로그램은 나열된 문장을 순차적으로 실행합니다. 이렇게 순차적으로만 수행하는 것은 작업이 매우 단순할 때지만, 특정 작업을 반복적으로 수행해야 할 경우에는 매우 비효율적인 프로그래밍이 됩니다. 그래서 좀더 효과적인 문장 표현을 위해 다음과 같이 세 가지 형태의 제어문을 제공합니다.
첫 번째, 조건문은 특정 조건에 대해 그 조건이 만족하면 해당 문장 또는 블록을 실행합니다. 스크립트 언어에서는 조건문으로 if문, if-else문을 제공합니다.
두 번째, 반복문은 어떤 문장 또는 블록을 반복 실행할 수 있도록 합니다. 스크립트 언어에서 사용 가능한 반복문은 while문, for문, do-while문 세 가지입니다.
세 번째, 분기문은 문장을 순서대로 실행해 나가다가 프로그램의 실행흐름을 특정 위치로 옮기고자 할 때 사용합니다. 이를 위해 스크립트에서는 break 문, continue 문, goto 문을 제공합니다.
14.8.1 if 문
if문은 가장 간단한 형태의 조건문으로 조건식이 만족할 경우에만 다음 문장을 실행하고자 할 때 사용합니다. 조건식이 참이면 if문 다음의 문장을 실행하고, 거짓이면 if문 다음의 문장을 실행하지 않고 지나갑니다.
If 문 |
if (조건식) 문장 또는 블록 |
다음은 입력이 90 이상일 때 해당 문장이 실행되도록 하는 예입니다.
if (input >= 90) {
…
}
14.8.2 if-else 문
if-else 문은 조건식이 참 혹은 거짓에 따라 문장을 양자택일할 경우 사용합니다. 조건식이 참이면 if문 다음의 문장만을 실행하고, 거짓이면 else문 다음의 문장만을 실행합니다. 여기서 else 문은 if문에 종속적입니다. if문 없이 else 만 독립적으로 사용될 수는 없습니다.
If-else 문 |
if (조건식) 문장 또는 블록 else 문장 또는 블록 |
다음은 홀수와 짝수를 구분하여 동작을 결정하는 예입니다.
if ((n % 2) == 0) {
…
} else {
…
}
스크립트 언어에서는 if 문과 else 문을 짝짓기 위한 규칙이 있습니다. 가장 가까운 if와 else를 순서대로 짝지어 주는 것입니다. 이러한 혼동을 피하기 위하여 ‘{‘와 ‘}’를 이용하여 if-else 문을 올바르게 묶어 주어야 합니다.
If-else 문 |
if (조건식) { if (조건식) 문장 또는 블록 else 문장 또는 블록 } |
14.8.3 if-else-if-else 문
다중택일을 위해서 if-else 문을 연결하여 if-else-if-else 과 같이 사용합니다.
If-else-if-else 문 |
if (조건식) 문장 또는 블록 |
다음은 입력이 90 이상이면 A기능 실행, 80에서 89 사이이면 B기능 실행, 70에서 79 사이이면 C기능 실행, 60에서 69 사이이면 D기능 실행, 나머지는 E기능 실행하는 예입니다.
if(input >= 90) {
// A statement
} else if((input >= 80)&&(input < 90)) {
// B statement
} else if((input >= 70)&&(input < 80)) {
// C statement
} else if((input >= 60)&&(input < 70)) {
// D statement
} else {
// E statement
}
14.8.4 while 문
while 문은 조건식이 참일 동안 문장 또는 블록을 반복적으로 실행하게 되고, 반복 실행 중에 조건식이 거짓으로 바뀌게 되면 반복 실행을 중단합니다.
while 문 |
while (조건식) 문장 또는 블록 |
다음은 1에서 100까지 더하는 연산을 while문으로 작성한 예입니다.
i = 1;
sum = 0;
while (i <= 100) {
sum += i;
i++;
}
14.8.5 for 문
반복문을 실행할 때, 다음과 같이 세 단계로 나누어 실행을 해야 할 경우에는 for 문을 사용하는 것이 유리합니다: 1)처음 시작할 때 하는 초기화 과정, 2)반복 여부를 검사하기 위한 조건식 검사, 3)반복할 때마다 실행할 문장 또는 블록.
for 문은 위에 나타난 세 가지 과정을 하나의 문장으로 표현 가능하도록 함으로, 반복 실행을 위한 문장을 작성하는데 드는 노력을 줄여줍니다.
for 문 |
for (초기화수식; 조건식; 증감수식) 문장 또는 블록 |
for 문의 초기화 수식에는 반복 실행을 하는데 필요한 초기화 문장들을 나열합니다. 이때 각 문장들은 ‘,’로 구분합니다. 이 초기화수식은 필요에 따라 생략 가능합니다.
조건식은 문장 또는 블록의 반복 여부를 판단합니다. 이 조건식이 만족할 동안 문장 또는 블록이 반복 실행됩니다. 조건식은 생략될 수 없습니다.
증감 수식에는 주로 증감 연산식이 사용됩니다.
다음은 1에서 100까지 더하는 연산을 for문으로 작성한 예입니다.
sum = 0;
for (i=1; i <= 100; i++) {
sum += i;
}
14.8.6 do-while 문
do-while 문은 조건식이 참일 동안 문장 또는 블록을 실행합니다. while 문에서는 반복 실행의 앞부분에서 조건식을 검사했지만, do-while 문에서는 문장 또는 블록을 실행한 후 조건식을 검사합니다. 그래서 조건식이 처음부터 거짓일 경우 연결된 문장 또는 블록을 아예 실행하지 않게 됩니다. 그러나 do-while 문은 문장 또는 블록을 먼저 실행 한 후 조건식을 검사하기 때문에 적어도 한번은 do-while 문에 연결된 문장 또는 블록을 실행을 하게 됩니다.
do-while 문 |
do { |
다음은 1에서 100까지 더하는 연산을 do-while문으로 작성한 예입니다.
i = 1;
sum = 0;
do {
sum += i;
i++;
} while (i <= 100);
14.8.7 break 문
break 문은 항상 for, while, do-while 문과 같이 쓰이며, 현재 실행중인 위치에서 break 문을 만나게 되면 프로그램의 실행이 반복문의 밖으로 빠져나가게 됩니다. break문을 for, while, do-while 문과 상관 없이 사용하면 에러가 발생합니다.
break 문 |
while (i<10) { |
다음은 1에서 100까지 더하는 연산을 while문과 break문으로 작성한 예입니다.
i = 1;
sum = 0;
while (1) {
if (i <= 100) sum += i;
else break;
i++;
}
14.8.8 continue 문
continue 문도 break 문처럼 항상 for, while, do-while 문과 같이 쓰이며, 현재 실행중인 위치에서 continue 문을 만나게 되면 프로그램의 실행이 반복문의 다음 시작 위치로 이동하게 됩니다. continue 문이 break 문과 다른 점은 제어흐름이 반복문의 밖으로 이동하는 것이 아니라 반복문의 시작 위치로 이동하는 것입니다.
continue 문 |
while (i<10) { … } |
다음은 1에서 100까지 더하는 연산을 do-while문과 continue문으로 작성한 예입니다.
i = 1;
sum = 0;
do {
sum += i;
i++;
if (i <= 100) continue;
} while (0);
14.8.9 goto 문
현재 실행중인 위치에서 특정 위치로 이동하기 위하여 goto 문을 사용합니다. 스크립트에서 레이블을 지정하는 방법은 “레이블이름:”과 같이 합니다. 그리고 하나의 프로그램 내에서 사용된 레이블은 각각 구분 가능해야 합니다.
goto 문 |
레이블:
… goto 레이블; |
다음은 1에서 100까지 더하는 연산을 goto문으로 작성한 예입니다.
i = 1;
sum = 0;
loop:
sum += i;
i++;
if (i <= 100) goto loop;
14.9 내장 함수
내장 함수는 스크립트 언어로 프로그램을 작성할 때 호출 가능한 미리 정의된 함수들입니다.
스크립트 언어에서는 다음과 같은 내장 함수들을 제공합니다:
· clock() – 현재 시간을 밀리초 단위로 반환
· rand() – 0과 32767 사이의 의사-난수를 반환
· sleep(x) – x 밀리초 동안 스크립트의 실행을 대기
· getv(index,sub_index) – index와 sub_index로 지정된 오브젝트의 값을 읽어옴
· setv(index,sub_index,x) – index와 sub_index로 지정된 오브젝트에 값을 기록함
· getrv(device_id, index,sub_index) – device_id로 지정된 제어기에서 index와 sub_index로 지정된 오브젝트의 값을 읽어옴
· setrv(device_id, index,sub_index,x) – device_id로 지정된 제어기에서 index와 sub_index로 지정된 오브젝트의 값을 기록함
· int(x) – x를 소숫점 첫째 자리에서 반올림하여 정수를 반환
· sin(x) – 라디안으로 주어진 x의 sine 값을 반환
· cos(x) – 라디안으로 주어진 x의 cosine 값을 반환
· tan(x) – 라디안으로 주어진 x의 tangent 값을 반환
· asin(x) – x(sine x의 결과 값)의 arc sine의 값을 반환
· acos(x) – x(cosine x의 결과 값)의 arc cosine의 값을 반환
· atan(x) – x(tangent x 의 결과 값)의 arc tangent의 값을 반환
· sinh(x) – 수학적으로 exp(x) – exp(-x)/2 로 정의된, x의 쌍곡선 sine을 반환
· cosh(x) – 수학적으로 exp(x)-exp(-x)/2 로 정의된, x의 쌍곡선 cosine을 반환
· tanh(x) – sinh(x)/cosh(x)이라는 수학적 정의를 가진, x 의 쌍곡선 tangent x를 반환
· fabs(x) – x의 절대값을 반환
· floor(x) – x보다 작거나 같은 정수 중에서 최대 값을 반환
· ceil(x) – x보다 크거나 같은 정수 중에서 최소 값을 반환
· sqrt(x) – x의 음이 아닌 루트 값을 반환
· exp(x) – 자연대수 e의 x 승 값을 반환
· log(x) – x의 자연로그를 반환
· log10(x) – 10을 밑으로 하는 x의 로그 값을 반환
· atan2(x,y) – 두 개의 인수를 가진 arc tangent 함수
· pow(x,y) – x의 y승을 반환하는 일반적 지수 함수
· min(x,y) – 주어진 두 인자의 최소값을 반환
· max(x,y) – 주어진 두 인자의 최대값을 반환
14.9.1 clock
Declaration: clock()
제어기의 현재 시각을 밀리초 단위로 읽어 옵니다. 시각은 제어기가 시작된 후 밀리초 단위로 카운트 되는 시각입니다.
Examples:
// 코드 블록의 실행시간 측정
t1 = clock ();
{ … }
t2 = clock ();
dt = t2 – t1;
14.9.2 rand
Declaration: rand()
0과 32767 사이의 의사-난수를 반환합니다.
Remarks: 제어기가 시작된 후 매번 난수를 다르게 발생시키기 위하여 시드(seed) 값을 설정합니다. 시드 값은 제어기의 특정 아날로그 입력 포트의 값을 읽어 지정하게 됩니다.
Examples:
// 0에서 99 사이의 난수 발생
a = rand()%100;
14.9.3 sleep
Declaration: sleep(x)
스크립트 프로그램의 실행을 x 밀리초 동안 대기합니다.
Remarks: 스크립트 프로그램의 실행이 sleep() 함수에 의해 중단된 상황에서도 제어기의 다른 모든 기능은 정상적으로 수행됩니다.
Examples:
// 채널 1번 모터에 1초 마다 전압 +5V와 -5V을 교대로 가합니다.
while (1) {
setv (_voltage_command, 1, 5);
sleep (1000);
setv (_voltage_command, 1, -5);
sleep (1000);
}
14.9.4 getv
Declaration: getv (index, sub_index)
인수 index와 sub_index로 지정된 제어기의 오브젝트 값을 읽어옵니다. getv() 함수로 제어기의 모든 오브젝트 값을 읽을 수 있습니다.
index는 제어기 오브젝트명의 참조 값이고 sub_index는 I/O나 모터의 채널 번호입니다. index는 USB/RS-232 통신에서 사용하는 Short Name과 Long Name으로 대체할 수 있으며, 스크립트에서 사용하기 위해서는 Short Name과 Long Name 앞에 언더스코어 문자(‘_’)를 붙여야 합니다.
Remarks: 유효하지 않은 index와 sub_index에 대해 읽기를 시도하는 경우, getv() 함수는 아무런 경고 없이 0을 돌려줍니다. 읽은 값이 0일 때, 실제 오브젝트의 값이 0인지 혹은 유효하지 않은 오브젝트를 엑세스 하였는지 알 수 없기 때문에 사용자는 getv() 함수로 넘기는 index와 sub_index가 유효한지 미리 판단하여야 합니다.
사용 가능한 index와 Short Name, Long Name에 대해서는 “14.5.3 미리 정의된 상수”를 참조하기 바랍니다.
Examples:
// 모터 채널 1의 전압 명령 값을 읽어옴, 다음 3개의 함수는 동일한 기능을 수행함
a = getv (114, 1);
b = getv (_vtc, 1);
c = getv (_voltage_command, 1);
14.9.5 setv
Declaration: setv (index, sub_index, x)
인수 index와 sub_index로 지정된 제어기의 오브젝트에 x를 씁니다. setv() 함수로 제어기의 모든 오브젝트에 값을 변경할 수 있습니다. 변경된 값은 제어기에 즉시 적용됩니다. 하지만 변경된 값이 제어기의 플래시 메모리에 저장되지는 않습니다.
index와 sub_index에 대한 설명은 getv() 함수의 설명을 참조하십시오.
Remarks: setv() 함수는 오브젝트에 쓰는 값 x가 유효한지 검사하지 않습니다. 사용자는 오브젝트의 값을 변경할 때 주의하여야 합니다.
Examples:
// 모터 채널 1에 전압 명령 5를 내림, 다음 3개의 함수는 동일한 기능을 수행함
setv (114, 1, 5);
setv (_vtc, 1, 5);
setv (_voltage_command, 1, 5);
14.9.6 getrv
Declaration: getrv (device_id, index, sub_index)
인수 device_id로 지정된 원격 제어기에서 index와 sub_index로 지정된 오브젝트 값을 읽어옵니다. getrv() 함수로 원격 제어기의 모든 오브젝트 값을 읽어올 수 있습니다.
device_id는 엑세스 하고자 하는 원격 제어기의 장치 ID 입니다.
index와 sub_index에 대한 설명은 getv() 함수의 설명을 참조하십시오.
Remarks: 그림 14‑3의 스크립트에서 사용된 getrv()와 setrv() 함수는 원격 제어기의 오브젝트를 엑세스 하는데 사용됩니다.
그림 14‑3 스크립트에서 원격 제어기의 오브젝트 엑세스 |
스크립트를 실행하는 제어기는 마스터(상기 그림에서 Device ID: 1)가 되고 오브젝트의 값을 제공하는 제어기는 슬레이브(상기 그림에서 Device ID: 2)가 됩니다. 마스터와 슬레이브 제어기는 동일한 CAN bus에 연결되어 있어야 하며, 동일한 CAN 통신 속도를 사용하지만 장치 ID는 서로 달라야 합니다. 마스터와 슬레이브 제어기를 USB나 RS-232로 연결하였을 경우, getrv()/setrv() 함수는 제대로 동작하지 않습니다.
Examples:
// 장치ID 2번 제어기의 모터 채널 1의 전압 명령 값을 읽어옴
a = getrv (2, 114, 1);
b = getrv (2, _vtc, 1);
c = getrv (2, _voltage_command, 1);
14.9.7 setrv
Declaration: setrv (device_id, index, sub_index, x)
인수 device_id로 지정된 원격 제어기에서 index와 sub_index로 지정된 오브젝트에 x를 변경합니다. setrv() 함수로 원격 제어기의 모든 오브젝트에 값을 변경할 수 있습니다. 변경된 값은 원격 제어기에 즉시 적용됩니다. 하지만 변경된 값이 원격 제어기의 Flash Memory에 저장되지는 않습니다.
device_id에 대한 설명은 getrv() 함수의 설명을 참조하십시오.
index와 sub_index에 대한 설명은 getv() 함수의 설명을 참조하십시오.
Remarks: setrv() 함수는 원격 제어기의 오브젝트에 기록되는 값 x가 유효한지 검사하지 않습니다. 사용자는 오브젝트의 값을 변경할 때 주의하여야 합니다.
Examples:
// 장치ID 2번 제어기의 모터 채널 1에 전압 명령 5를 내림
setrv (2, 114, 1, 5);
setrv (2, _vtc, 1, 5);
setrv (2, _voltage_command, 1, 5);
14.9.8 int
Declaration: int(x)
주어진 실수에서 가장 가까운 정수를 반환합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 정수입니다.
Examples:
a = int(1.4); // a는 1
b = int(1.6); // b는 2
14.9.9 sin
Declaration: sin(x)
라디안 각 x의 sine 값을 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 -1과 1 사이의 값입니다.
Examples:
// 정현파 전압을 가해 모터를 구동
for (i=0; i<100000000; i++) {
v = 5*sin(i*0.01);
setv (_voltage_command, 1, v);
sleep (10);
}
14.9.10 cos
Declaration: cos(x)
라디안 각 x의 cosine 값을 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 -1과 1 사이의 값입니다.
14.9.11 tan
Declaration: tan(x)
라디안 각 x 의 tangent 값을 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 모든 값이 될 수 있습니다.
14.9.12 asin
Declaration: asin(x)
x의 arc sine 값을 계산합니다. sin() 함수의 역함수입니다.
인수 x의 값은 -1과 1 사이의 값입니다.
반환 값은 -π/2와 π/2사이의 라디안 각입니다.
14.9.13 acos
Declaration: acos(x)
x의 arc cosine 값을 계산합니다. 이 함수는 cos() 함수의 역함수입니다.
인수 x의 값은 -1과 1 사이의 값입니다.
반환 값은 0과 π사이의 라디안 각입니다.
14.9.14 atan
Declaration: atan(x)
x의 arc tangent 값을 계산합니다. 이 함수는 tan() 함수의 역함수입니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 -π/2와 π/2사이의 라디안 각입니다.
14.9.15 sinh
Declaration: sinh(x)
x의 쌍곡선 sine을 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 모든 값이 될 수 있습니다.
14.9.16 cosh
Declaration: cosh(x)
x의 쌍곡선 cosine을 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 모든 값이 될 수 있습니다.
14.9.17 tanh
Declaration: tanh(x)
x 의 쌍곡선 tangent를 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 모든 값이 될 수 있습니다.
14.9.18 fabs
Declaration: fabs(x)
x의 절대값을 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 항상 양수입니다.
Examples:
a = fabs(5.5); // a는 5.5
b = fabs(-5.5); // b는 5.5
14.9.19 floor
Declaration: floor(x)
x보다 작거나 같은 정수 중에서 최대 값을 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 정수입니다.
Examples:
a = floor(5.5); // a는 5
b = floor(-5.5); // b는 -6
14.9.20 ceil
Declaration: ceil(x)
x보다 크거나 같은 정수 중에서 최소 값을 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 정수입니다.
Examples:
a = ceil(5.5); // a는 6
b = ceil(-5.5); // b는 -5
14.9.21 sqrt
Declaration: sqrt(x)
x의 음이 아닌 루트의 값을 계산합니다.
인수 x의 값은 음수가 될 수 없습니다.
반환 값은 항상 양수입니다.
Examples:
a = sqrt(4); // a는 2
14.9.22 exp
Declaration:exp(x)
자연상수 e의 x 승 값을 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 모든 값이 될 수 있습니다.
Examples:
a = exp(2); // a는 7.389…
b = pow(_E, 2); // b는 7.389…
14.9.23 log
Declaration: log(x)
x 의 자연로그를 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 모든 값이 될 수 있습니다.
Examples:
a = log(_E); // a는 1
b = log(_E*_E); // b는 2
14.9.24 log10
Declaration: log10(x)
10을 밑으로 하는 x의 로그를 계산합니다.
인수 x에는 모든 값을 사용할 수 있습니다.
반환 값은 모든 값이 될 수 있습니다.
Examples:
a = log10(10); // a는 1
b = log10(1000); // b는 3
14.9.25 atan2
Declaration: atan2 (y, x)
두 개의 인수 y, x로 arc tangent를 계산합니다. y/x에 대한 arc tangent 연산을 수행하고, y와 x의 부호로 4분원(quadrant)을 결정합니다.
인수 y, x는 0이 될 수 없습니다.
반환 값은 -π와 π사이의 라디안 각입니다.
Examples:
a = atan ( 1/ 1); // 1/4*PI
b = atan (-1/ 1); // -1/4*PI
c = atan ( 1/ -1); // -1/4*PI
d = atan (-1/ -1); // 1/4*PI
e = atan2( 1, 1); // 1/4*PI
f = atan2(-1, 1); // -1/4*PI
g = atan2( 1, -1); // 3/4*PI
h = atan2(-1, -1); // -3/4*PI
14.9.26 pow
Declaration: pow (x, y)
x의 y승을 계산합니다.
만일 인수 y가 분수 값이면 인수 x는 음수가 될 수 없습니다. 그리고 y가 0보다 작거나 같으면 x는 0이 될 수 없습니다.
Examples:
a = pow( 2, 1.5); // 2.828…
b = pow(-2, 1.5); // 계산 불가
c = pow(1.5, 2); // 2.25
d = pow(1.5, -2); // 0.444…
14.9.27 min
Declaration: min (x, y)
주어진 두 인수 x, y의 최소값을 선택합니다.
인수 x, y에는 모든 값을 사용할 수 있습니다.
14.9.28 max
Declaration: max (x, y)
주어진 두 인수 x, y의 최대값을 선택합니다.
인수 x, y에는 모든 값을 사용할 수 있습니다.