loading

CScript (picoc)

Please be sure to read the Plugins page to get a general sense of if the CScript module is a good fit for your project.

The CScript module provides a way to create custom C scripts that can be used to process image statistics and map then toward servo/motor values. This module is intended to be used as a way to quickly perform custom operations without needing to implement a Plugin or use the API which typically require external tools.

The interface allows two methods for specifying your code. One technique requires that you specify a text file as the source of the program. You can use your favorite text editor to edit/create this file. The file should be a regular text .c file containing CScript commands/functions/operators. The program interface displays the current file being used, available system or user variables (and their values) and any messages the program produces.

The alternate way is to include the CScript text within the provided text box (see below). Using this technique allows you to include the CScript code within the .robo program and not require another user to save the code and reference a text file as needed by the above file based technique. Using the text box provides a quick way to enter in text but is NOT meant as a replacement for a full featured text editor as its editing features are very basic.

The CScript module interprets C code using the PicoC - A very small C interpreter project and thus will not have the full Windows API available to use. If you need additional capabilities have a look at the Plugin or API architecture where you can use the full Visual Studio tools and still communicate with RoboRealm.

As PicoC is interpreted it will run slower than regular C. This will be fine for most applications but if you chose to do image processing directly in this module (similar to the SwapColor example below) the FPS (frames per second) will decrease dramatically as a result.

Interface

RoboRealm Specific Functions

  • int variableExists(char *variable_name); - returns true (1) or false (0) depending on if the specified variable exists in RoboRealm. Several of the variable return functions below will return a valid value regardless of if the variable exists or not. You can use this function to determine if the value returned from one of these functions is a valid value.

  • int getVariable(char *var); - returns an integer value of the specified variable

  • float getFloatVariable(char *var); - returns the float value of the specified variable

  • char *getStrVariable(char *var); - returns the string value of the specified variable

  • int getArrayVariable(char *var, int *arr, int max); - returns the int array associated with the specified variable in the array "arr" for max entries. The number of items stored in the provided array is returned. Note that the array NEEDS to already be allocated or statically declared (int arr[64]).

  • int getFloatArrayVariable(char *var, float *arr, int max); - returns the float array associated with the specified variable in the array "arr" for max entries. The number of items stored in the provided arr is returned by the function.

  • int getStrArrayVariable(char *var, char *arr, int max); - returns the string array associated with the specified variable in the char buffer "arr" up to max size. Each entry is spaced within 64 characters of arr such that &arr[0] is record 1, &arr[64] is record 2, etc. Note that max is the total maximum number of characters to be used including any padding below 64.
    int arr[64];
    
    int num = getArrayVariable("BLOBS", arr, 64);
    
    printf("%d %d", num, arr[0]);
    
    arr[0]=33;
    
    setArrayVariable("BLOBS", arr, num);
    

  • void setVariable(char *var, int value); - sets the integer variable value to the specified variable

  • void setFloatVariable(char *var, float value); - sets the float variable value to the specified variable

  • void setStrVariable(char *var, char *value); - sets the string variable value to the specified variable

  • void setTimedVariable(char *key, int value, int timeout); - - sets the variable value to the specified variable after the timeout (milliseconds) has passed. This allows you to specify when in time a variable's value should be changed. Note that each call to SetTimedVarible will reset the timer so be sure to only call it once to allow the time to lapse and set the specified value. This function is useful when you need an alternative to the Sleep function. By setting a variable to a value in the future you can emulate a Sleep function by allowing something to happen for a period of time, but then switching it off after the time has lapsed. So instead of using
    setVariable("motor", 100);
    sleep(1000);
    setVariable("motor", 0);
    
    you could use
    setVariable("motor", 100);
    setTimedVariable("motor", 0, 1000);
    

  • void setFloatTimedVariable(char *key, float value, int timeout); - sets the float variable value to the specified variable after the timeout (milliseconds) has passed

  • void setStrTimedVariable(char *key, char *value, int timeout); - sets the string variable value to the specified variable after the timeout (milliseconds) has passed

  • void addTimedVariable("variable_name", variable_value, timeout); - similar to SetTimedVariable, this function will instead add the timing parameter to a queue instead of overwriting the timing information. For example:
    setTimedVariable("motor", 100, 1000);
    setTimedVariable("motor", 200, 1500);
    setTimedVariable("motor", 300, 2000);
    
    will result in the motor variable being set to 300 in 2 seconds (2000 ms). What happens is that the first two calls to setTimedVariable are OVERWRITTEN by the third. Instead, if you use
    addTimedVariable("motor", 100, 1000);
    addTimedVariable("motor", 200, 1500);
    addTimedVariable("motor", 300, 2000);
    
    the motor variable will be set to 100 in 1 second, 200 in 1.5 seconds and finally 300 in 2 seconds. The addTimedVariable will add each call into a list that is executed in sequence based on the specified time.

  • void addFloatTimedVariable("variable_name", variable_value, timeout); - float version of addTimedVariable

  • void addStrTimedVariable("variable_name", variable_value, timeout); - string version of addTimedVariable

  • void sleep(X); - suspends processing for X number of milliseconds and returns control to the pipeline to acquire additional images and send values to external devices.

  • void waitVariable("variable_name", variable_value); - suspends VBScript processing until the specified variable equals the specified value. This function returns control to the pipeline to acquire additional images and send values to external devices while it waits for the variable value.

  • void waitVariableChange("variable_name"); - suspends VBScript processing until the specified variable changes its value. This function returns control to the pipeline to acquire additional images and send values to external devices while it waits for the value to change.

  • void waitImage() - suspends VBScript processing and returns control to the pipeline for one pipeline iteration. This allows for the acquisition of additional images and to send values to external devices.

  • unsigned char *getPixels(int *width, int *height); - returns an array of BGR values of the current image and sets width and height of the image. Note that the returned array is an unsigned char with Blue first.

  • void setPixels(unsigned char *, int , int); - sets the current image to the specified pixel BGR data

  • void setParameter(char *module, int count, char *parameter_name, int paramter_value); - changes the specified parameter in the specified module to the specified value. This is useful when a GUI dialog does not have a variable selection as part of the dropdown. Avoid using this function unless necessary as it is slow to update the GUI. Count is used to distinquish between multiple uses of the same module (i.e. module_name would be the same for either module).

  • void setFloatParameter(char *module, int count, char *parameter_name, float paramter_value); - float value of above routine.

  • void setStrParameter(char *module, int count, char *parameter_name, char *paramter_value); - char value of above routine.

  • int getParameter(char *module, int count, char *parameter_name); - returns the specified parameter in the specified module. This is useful when a GUI dialog does not expose a value within a variable. Count is used to distinquish between multiple uses of the same module (i.e. module_name would be the same for either module).

  • float getFloatParameter(char *module, int count, char *parameter_name); - the float version of the above routine.

  • char *getStrParameter(char *module, int count, char *parameter_name); - the string version of the above routine.

  • void stopProcessing(); - stops RoboRealm from continuing to process the images with the remaining modules

  • void cameraOff(); - switches off the image capturing from the current camera

  • void cameraOn(); - switches on the image capturing using the current camera

  • void pushButton(char *module, int count, char *key); - automates pushing a button in one of the RoboRealm GUI windows. For example:
    if (strcmp(getStrVariable("test"), "pushed")!=0)
    {
      setStrVariable("test", "pushed");
      pushButton("Read_AVI", 0, "Start");
    }
    
    will cause the Read_AVI module (assuming one exists in the pipeline) to start playback.
    pushButton("RoboRealm", 0, "Snap");
    
    will cause RoboRealm to create a snapshot of the current image.

  • float atan2(x,y); - arc tangent function not present in picoC but useful for trigonometric calculations

Examples

To access variables from your CScript file/script use the following commands:

int value = getVariable("variable_name")

Or to create a new variable use

setVariable("variable_name", variable_value);

Once a new variable is created this variable becomes available to control functions (such as in the SSC module) that can be used to automatically control a servo/motor.

You can also get variable arrays using

int list[256]; int num = GetArrayVariable("variable_array_name", list, 256);

or get individual entries in an array using

int val = getVariable("variable_array_name:2");

which would return the second entry in an array.

To change a variable's value in X milliseconds you can use

setTimedVariable("variable_name", variable_value, timeout_in_milliseconds);

which is very useful for resetting motor values after a period of time.

For example the following program (assuming you have added the Center Of Gravity module) will map COG to servo motors:

int cogx getVariable("cog_x");
int 
cogy getVariable("cog_y");
int 
left_motor;
int 
right_motor;

if 
(cogx < 140)
{
 left_motor 
60;
 
right_motor 128;
}
else
{
  
if (cogx > 180)
  {
    left_motor 
128;
    
right_motor 60;
  
}
  
else
  
{
    left_motor 
128;
    
right_motor 128;
  
}
}

setVariable(
"left_motor", left_motor);
setVariable("right_motor", right_motor);

Note that the COGX values range from 0 to 320. COGY ranges from 0 to 160. These values are bounded by the current image size. These values may change if you crop, shrink, etc. the image dimensions.

You could then use a module like the SSC module to map the "left_motor" and "right_motor" variables to actual servos.

You can also process the image pixels directly using CScript. This is useful for prototyping but not recommended due to performance reasons for actual usage. The CScript module supports two routines to get and set the image pixels. Following is the example SwapColor module but in CScript.


int width, height;
int 
i;
unsigned char 
c;
unsigned char 
*pixels getPixels(&width, &height);

for 
(i=0;i<(width*height*3);i+=3)
{
  c 
pixels[i];
  
pixels[i]=pixels[i+2];
  
pixels[i+2]=c;
}

setPixels(pixels, width, height)
;

If you need to wait for a specific condition in a loop you will have to setup a trigger variable. You can't really sleep, wait or loop in the CScript module as that would stop all image processing while it is waiting for the loop or sleep to finish. As the pipeline is essentially an infinite loop (i.e. grab an image, process it, then grab another, etc) adding a sleep would cease all execution which is usually not desired. If you prevent the ending of the loop by putting a while loop in the code it will not allow the system to capture new images and continue processing. So instead you can use the SetTimedVariable to cause the variable to change value after X number of milliseconds. Your script would look something like

int period 2000;
int 
step getVariable("step");
if 
(step == 0)
{
  setVariable(
"data"2);
  
setVariable("step"1);
  
setTimedVariable("step"2, period);
}
else
{
  
if (step == 2)
  {
     setVariable(
"data"4);
     
setVariable("step"3);
     
setTimedVariable("step"0, period);
  
}
}
which would cause the variable data to oscillate between 2 and 4 with a period of 2000 seconds. Note that usage of step and setting it to 1 and 3 which are dummy steps where nothing is done.

The list of supported intrinsic C functions are:

void printf(char *, ...);
char *sprintf(char *, char *, ...);
void exit();
float atan2(float, float);
float sin(float);
float cos(float);
float tan(float);
float asin(float);
float acos(float);
float atan(float);
float sinh(float);
float cosh(float);
float tanh(float);
float exp(float);
float fabs(float);
float log(float);
float log10(float);
float pow(float,float);
float sqrt(float);
float round(float);
float ceil(float);
float floor(float);
void *malloc(int);
void *calloc(int,int);
void *realloc(void *,int);
void free(void *);
void strcpy(char *,char *);
void strncpy(char *,char *,int);
int strcmp(char *,char *);
int strncmp(char *,char *,int);
void strcat(char *,char *);
char *index(char *,int);
char *rindex(char *,int);
int strlen(char *);
void memset(void *,int,int);
void memcpy(void *,void *,int);
int memcmp(void *,void *,int);

The module has a built in timeout mechanism to avoid infinite loops from hanging the application. This timeout is set in Options Button-> Other Tab-> Timeouts Pipeline should you need to increase the default 10 seconds.

Variables

On each successful run of the script the SCRIPT_COUNT variable is incremented. Thus you can use this variable to indicate a first run state where variables can be initialized to default values. Note that the Reload and Run button will reset this count to 0. You can also use the IMAGE_COUNT variable to determine first run when the Run button in the main GUI is toggled. The SCRIPT_COUNT is NOT changed when the main GUI Run button is toggled.

See Also


VBScript Program
JScript Program
Python Program

For more information


picoc - Project Hosting on Google Code

 New Post 

CScript_Program Related Forum PostsLast postPostsViews
CScript incomplete
hello, I have a problem, I open a roboream program i made before, but the Cscript_Program is incomp...
7 year 2 2010
line
hi. I`m new to roborealm. I want to draw a offset line to probed lines count variable (a line drawn to probed lines count variab...
8 year 4 2271
cScript
I want to create a new variable making mathematical manipulation to probed lines count variable. please kindly linform me. ...
8 year 2 2209
Truncating or rounding displayed variables
Hi , I am measuring small objects under a microscope with RR, and displaying the results with wither the 'display...
10 year 4 2760
Strange Behavior of power operator (^) in Cscript
Hi again! I've noticed strange behavior with the power operator "^". From my intuition:
11 year 4 3032
Roborealm CScript variableExists function problem
Hi, I am currently facing a problem with the CScript function variableExists. In the documentation...
12 year 2 3211
image segmentation
Hi!   I need a C# coding for automatic segmentation using bayesian network algorithm. Plz help me if any...
12 year 1 3182
Problem with variables from CScript
I'm having problems with CScript variables. I'm just playing around at the moment, but I've just written up a script to find...
13 year 3 4042
Crazy Question
Thanks Guys for fixing me up. My question is: if you use the Vbasic script, the C script, the pytho...
13 year 3 3402
Trouble updating LASER_POINTS position
The goal of this code is to get the coordinates represented by COG_X and COG_Y which represent a moving person and get the coord...
13 year 3 3948