3. R3

3.1. Overview

R3 is similar to IEC 61131-3 ST language (Strucuted Text). It is used by Robox controllers. The syntax is simlar to C, Pascal and basic languages.

Note

R3 language is NOT case sensitive.

3.2. Program structure

An R3 program can be a task or a rule file. The code of a program can be written in one file or divided in several files that can be included in R3 program using the keyword $include followed by the file name. Usually the file to be included have .i3 extension.

The rule case is a little bit different, and will discussed later. A task is like a C prrogram, is executed from the begining until the end. If no infinite loop is used, once the task reach the end, its execution is terminated. Usually a task have to be executed cyclically, for this reason after the initialisation, the code is written inside an infinite loop i.e. `` while(1) { code }``. R3 provide __MAIN_LOOP__ block that is equivalent to the infinite loop.

$include filetobeincluded.i3

; variable declaration

; initialization

__MAIN_LOOP__
  ; this is an infinite loop
  ; write your code here

END_MAIN_LOOP

3.3. Basic syntax

3.3.1. Variables and types

Fundamental types :

bool

I8
I16
I32
INT

U8
U16
U32

float
real

char
string

Some strucutre or complex types:

STRUCT
STRUCTP
TIMER
COUNTER

Some example of motion related types

STRU_MVTO
STRU_CAM

Here some example on how to use. The syntax id the same for all types type varname.

INT intVar
REAL position

INT vv[10]
REAL vr [5][2]

STRING description
STIRNG desc[5]

intVar = 10
position = 20.0

We can access the single be of a varible by using the dot operator, e.g. we want to access bit 5 of the varible pippo:

int pippo = 0x20
pippo.5 = 1 ; assign value 1 to bit 5 of the varible pippo

3.3.2. Constants

Usually we create constants, to avoid to use numbers, to make our program more readable. Constants are created suing the keyword LIT, e.g. LIT MONDAY 1, LIT TUESDAY 2. As a convention constants are written in capital letters.

R3 doesn’t have the enumeration type, pay attention when constructing enumeration with constants to keep different numerical values to different costants of the same category, e.g. MONDAY and SUNDAY should have different numerical values, they can’t have both of them the value 1. If they have the same value, this will be a programming error, not a syntax error.

3.3.3. Operators

; assignment
=

;
+ - * /

;
AND OR NOT XOR

;
> < =
<> >= <=

; bitwise
R_AND R_NOT R_OR R_XOR

; string concatanation
#

3.3.4. Control flow

As any programming language, usual control flow statements are :

if (contition)
  ;
elseif (condition)
  ;
else
  ;
end_if

_if (condition)
  ; one statement
_else
  ; one statement
for(initialisation, conidtion , update)
  ;
end_for

for( i=0, i < 10, i=i+1)
  ; code
end_for

for(,1,)
  ; infinite loop
end_for
select (var)
  case 1
    ; code
    break

  case 2
    ; code
    break

  default
    ; code

end_select
while(condition)
  ;
end_while

while (i < 10)
  i=i+1
end_while

while (1)
  ; inifite loop
end_while
do
  ;
end_do_while(condition)
__main_loop__
  ; infinite loop

end_main_loop
I32 cond_val (condition, I32 val_if_true, I32 val_if_false)

i = cond_val (b=2, 10, 20)

; this equivalent to
if (b=2)
 i = 10
else
 i = 20
end_if

In the documention and in the example shown before can be found their syntax.

3.3.5. ALIAS

An alias is a more undertandable or more clear alternative to a varible or to a function. In R3 can be used to give a name to a register or to an input or a memory. The keyword LIT is used, like for constants. For example in an R3 we can write r(3) = 100, it is correct be the meaning of r(3) is not clear.

If we writte:

LTI Position r(3)
position = 100

it will be clear that the varible we are dealing with, is a position. We can give different alias to the same register.

Let’s suppose that r(10) is a mask where every bit represent something. We can use the dot operator to access the singular bits. e.g. r(10).4. Of course it will more clear if we give a name to number 4.

LIT DriveStatusWord r(10)
LIT DRIVE_READY 0
LIT DRIVE_RUN   1
LIT DRIVE_ALARM 4

if  ( DriveStatusWord.DRIVE_ALARM )
  ; do something
end_if

3.3.6. Data structure

Data strucutres could be Arrays, Sruct and OBs. In R3 documentation we can find predefined structures and OB that main are related to motion control.

We can also define our own structures and OBs.

3.3.7. Modular programming

Tasks, functions and Object blocks can be used to make the program modular and esay to debug.

RDE allow us to create maximum 9 R3 programs (files) divided in one Rule program (one file) and eight taks (8 files). It allow also to create other files that can be included in tasks and rule files. We can write our functions, variable delcation, IO mapping, registers aliases (using LIT) in different files, usually with extension .i3 and include them in the disered task using the keyword $include filename.i3

3.3.8. Scope rules

As any programming language variables have a scope. They could be local or global variables. Registers, IOs and predefined variables are global, and they can be written and read from any task. Also variables that are aliases to registers and IO are global.

Variables could be local to a function or local to a task.

$task 1

int b  ; local to this task, it can't be seen by other tasks
int c  ; local to this task
int i ; local to task

__MAIN_LOOP__

 ; code

 val =2  ; it will give compilation error. this is not delcared in the task

END_MAIN_LOOP

function

 int val ; local to funtion
 int i ; local to funtion, it is not the same as the one delcared in the TASK

 b = 2 ; this is delcared in the task, it can be used also in the funtion.

 ; code
end_fun

Variables could be also public and can be shared between tasks. If a variable is delared as public in task 1, and extern in task 2, it can be written and read in task 1, and only read in task 2.

 $task 1
  public int val  ; public variable. can be read an written by this task. I can be only read in other tasks where the keyword extern is used.

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 $task 2
  extern int val  ; external variable can only be read

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

$task 3
  int val ; this is local to task 3

I you want to read and write a variable delcared as extern, the keyword $WRITE_ON_EXTERN should be add to the task where the variable is delared as extern

$task 1
 public int val  ; public variable. can be read an written by this task. I can be only read in other tasks where the keyword extern is used.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

$task 2

 $WRITE_ON_EXTERN  ; if this keyword is present all varibles delared as extern become also writable by this task
 extern int val    ; external variable can only be read

3.3.9. Example

The purpose of the following code is to illustrate the syntax of R3. The whole code have no meaning by itself.

$TASK 2

$include incfile.i3

; this is a comment

; STRUCT definition
STRUCT stPoint 
    REAL x 
    REAL y
	REAL z
	INT n
END_STRUCT

; variable of type stPoint
stPoint myPoint1
stPoint myPoint2

int a	; 32 bit signed variable
a=2		; variable initilization

int n

real time	; 8 bytes floating point

real tim

bool c		; bool variable

; LIT keyword used as alias to registers, inputs and outputs
LIT sinf rr(1)
LIT inpValve	inp_w(200)

; LIT can be used also to define constants
lit THIS_IS_CONSTANT	2

time = tfb
tim =tfb

LIT operation r(10)
operation = 0

; array of 5 int
int arrBuffer[5]


; infinite loop
__MAIN_LOOP__

	if (tfb > time +1)
		_if ( r(2).0 )
			r(1) = r(1) + 1
		time = tfb
	end_if
	
	if (tfb > tim +0.005)
		sinf = sin(2*3.14/2 * tim)
		tim = tfb
	end_if
	
	; Object block use
	obdemoist.b =true
	c= obdemoist.readonlyvar
	
	; call a function
	call thisIsFunction()
	
	if ( a > 10 )
		n = 100
	elseif ( a < 5 AND a > 0)
		n = 10
	else
		n = -1
	end_if
	
	int i
	for (i = 0, i < 22, i=i+2)
		n = n + i
		if (n > 10)
			continue
		elseif ( n= 100)
			break
		end_if
	end_for
	
	i =0
	while (i < 10)
		i=i+1
		n= i +2
		_if (n = 10) ; this _if have only one instruction that belong to it
			break
	end_while
	
	real distance
	distance = getDistance(myPoint1, myPoint2)
	
	
END_MAIN_LOOP

function thisIsFunction()
	; string concatenation
	sr(1) = "it's" # " eight"
end_fun

; funtion
function testFunc()

	select (operation)
		case 0
			; do something
			break

		case 1
			; do somethingelse
			break
		default
			; do somethingelseelse
			operation = 0
	endselect
	
end_fun

; this function return a real value
function real getDistance(stPoint p1, stPoint p2)
	; euclidean distance	
	return sqrt( pow((p2.x -p1.x),2) +  pow((p2.y -p1.y),2) + pow((p2.z -p1.z),2) )
end_fun

Basic syntax of R3 language

3.4. Predefined variables

A full list of the predefined variables can be found in Documentaion –> Programming languages –> R3 language –> Predefined variables

3.4.1. Input-Output

../../_images/io.png

IO predefined variables

3.4.2. Registers

Regisers are arrays of prealloced memories. The dimension can be defined by the user, Register dimension.

../../_images/globalregisters.png

Registers predefined variables

Register dimension show different types of registers and their allocation in memory.

../../_images/general-storage.png

Register dimension

3.4.3. Axis parameters

The following variables are arrays of 32 elements. The array index correspond to the axis index. For example cp(2) is the current position of Axis number 2.

  • kbit2unit Bit-unit conversion factor.
  • cp Axis current position [unit]
  • cv Axis current velocity [unit/s]
  • ca Axis current acceleration [unit/s^2]
  • ip Axis ideal position [unit]
  • iv Axis ideal velocity [unit/s]
  • ia Axis ideal acceleration [unit/s^2]
  • sref speed reference.
  • pro_gai position loop proportional gain
  • kff feed forward factor
  • epos position error when the position loops are closed with a predefined formula
  • fr feed rate. This variable contains a factor ranges from 0 to 1. If a min value of 0 is programmed, the variable fr will be set = 0. If a value >1 is programmed, the variable fr will be set = 1.