Migrating from EZ-Script to JavaScript

Semicolon Line Endings

When writing EZ-Script code, at the end of the line you simply press <enter> and start coding on the next line. However, in JavaScript, it is recommended to terminate the line with a semicolon ; character. With the ARC JavaScript compiler, it is not mandatory to do it, but you will find most code examples will have the semicolon at the end of the line.

Examples

EZ-Script Example

print("This is some text")
print("This is another line of text")

JavaScript Example

print("This is some text");
print("This is another line of text");

*Note: Notice the semicolon at the end of the lines in JavaScript. Again, it's not mandatory, but it is recommended for proper JavaScript compliance.

Why Semicolons?

Traditionally, a semicolon has been common across many programming languages to tell the compiler the end of the command. This is because many commands can be included on the same line with JavaScript. It is not recommended to do this because it is messy to read, but some people program this way.

Example Of Many Commands On One Line

print("Hello"); print("World");


ARC Pro

Upgrade to ARC Pro

With ARC Pro, your robot is not just a machine; it's your creative partner in the journey of technological exploration.

#1  

Wow that is totally great info to know, thanks!

#2  

Thanks for this Tutorial @DJ. It will be invaluable as I change over my many scripts from EZ Script to JavaScript! I'm excited to see how my robot's arm servo react to the new faster language. I have some pretty complex scripts (for me anyway. LOL).

PRO
Synthiam
#3  

I think you'll find that the new scripts you write will be even smaller and faster. Probably easier to read as well. I can always help you change some over if you post one. That'll give you examples of how the difference would be.

#4   — Edited

But just to be clear, the EZ scripts should still mostly work in Arc? I tried 2 that still worked no conversion. Just slower most likely.

PRO
Synthiam
#5  

Yeah, EZ-Script works in ARC. This is a tutorial to help people migrate to a faster and more feature-rich language.

#6  

Wow @DJ. That's an amazing offer. Thanks! I'll post one soon. I think I have covid now and need to get past that first. Can't quite thing straight right now. LOL.

PRO
Synthiam
#7  

Oh boy, it seems everyone is getting covid these days. I'm feeling left out. I hope you're doing well and binge-watching a lot of tv! Drink soup and dream about robots.

#8  

Thanks DJ. I'm coming to the end of it I hope. Feeling better. Don't feel left out. Only good thing about this is now I have some antibodies for a while. LOL. Stay healthy!

PRO
Synthiam
#9  

That's what super heros are made of!

#10   — Edited

Actually i was adding some script codes for my Init servos start up and other start up functions, then realized I used EZ script instead of Javascript. Since Javascript is way faster ,what is the easy way to convert the EZ script over to Javascript? right now it just wants to delete the whole EZ script when I move into Javascript window. Like if I copy and paste it in, will it convert? I guess I can just start over line by Line with the cheat helper Edit.... I think I had a similar question last week about using my old EZ scripts and did you point out some tutorial Link? I seem to have forgot where.

PRO
Synthiam
#11  

*Note: I moved your question to the appropriate thread because it was asked on a feature request for Blockly copy and paste

The windows Copy and Paste command will copy the text. There is no way to "convert code" when pasting. It will merely paste what is copied. Once you paste the EZ-Script into the JavaScript window, you can edit the code to make it JavaScript syntax.

#12  

Ahh yes That was what I was looking for thanks again, sorry for asking twice,LOL!

Kyrgyzstan
#13  

How to  include a javascript library ?

PRO
Synthiam
#14  

There used to be an option for that. Hmmm. I can't seem to find it now. I'll have to take a better look as I don't see it in the documentation on the support section.

PRO
USA
#15  

....just stumbled onto this...thank you so much.

#16   — Edited

OK, I'm having trouble wrapping my mind around converting my EZ Script to JavaScript. I do think I understand some of the basics ways to write in JS like loops, classes and variables. However I I have a very complicated but working EZ script I wrote a few years ago I'm trying to convert to JS but I don't understand some of the proper ways to write commands.

Here are a couple of the commands I'm having trouble understanding. I'll show the EZ Script command that works and try to show the way I think the JS command will work. If some one can guide me to the correct syntax I would be grateful:

In this first example I am sending a command through EZB 2, Uart 2 to a Kangaroo Motor controller. The Roo's command is inside the " ". It states which channel on the Roo to start the move on, the position to move to and at what speed. The next command in the line, 0x0d, is the ASCII value for the Return Key on a keyboard. The Roo needs this to accept the command:

uartWrite(2, 2, "2,p805 s300", 0x0d)

Below is what I think the JS Syntax should be??? Notice the  0x0d ASCII value and the uart port and EZB index numbers. Do I need those quote marks? How close am I in being correct?

UART.uartWrite(2,"2,p805 s300", 0x0d,2);

Now, My next big problem. How to split and GetCharAt with JS. When the I request a position and the Kangaroo motor controller returns this position to ARC through an EZB Uart, it comes back looking like this: Pxxx or pxxx. Their will be either a upper or lower case P followed by the position number (xxx). An upper case P means the motor is still moving and a lower case means it's stopped. I wrote an EZ script that puts this returned value into a variable, splits the P from the position number, tells me if the P is upper or lower case and what the position number is. The way I'm using this script is that I ignore the P and only need to position number. However I need to split the P from the returned value and ignore it or the script wont work:

# Get Right ARS Roo Position
uartWrite(2, 2, "1, Getp", 0x0d)

:waitFor_Rt_Data
Sleep(30)

$y = UartAvailable(2, 2)
# Sleep(30)
# print("Bytes in buffer:" + $y)
if ($y < 6)
# Go back and wait for data again because we did not receive the least number of expected bytes.
goto(waitFor_Rt_Data)
endif

$Get_Rt_Carrage_P = UARTRead(2, 2, $y)
# Sleep(30)
# print("Received:" + $Get_Rt_Carrage_P)
Sleep( 150 )

# -------------------------------
# Find out (and print if wanted) if the P is upper or lower case.
# Upper case means the motor has finished moving and stopped.
# Lower Case means that the motor is still moving.
$P_or_p = GetCharAt($Get_Rt_Carrage_P, 2) #Assign a variable to either a capital P or Lowercase p returned by Kangaroo.
# Print("P_or_p:" + $P_or_p)

# -----------------------------
# # Defeat the P_or_p because it must die!
if ($P_or_p = "p")
$Rt_Carrage_Position = Split($Get_Rt_Carrage_P, "p",1) #1,pXXXX is returned. Get everything after the Lowercase p (P is case sensitive).
ELSE ($P_or_p = "P")
$Rt_Carrage_Position = Split($Get_Rt_Carrage_P, "P",1) #1,pXXXX is returned. Get everything after the Upper case P (P is case sensitive).
endif

Then I have the EZ Script decide if the motor has fully deployed the payload and it's safe to continue or it needs to go loop back and do everything over again until the payload in in position. It then sets a global variable which tells a different script that is waiting on this that i's safe to proceed. This EZ script loops until that safe position is reached (805) and sets that variable.

if ($Rt_Carrage_Position >= 751 and $Lft_Carrage_Position >= 751)
$Both_ARS_Extended = 1 #Rt Carriage fully out. Set this variable so the waiting Automation Script knows the carriage is fully out.
ELSE ($Rt_Carrage_Position < 750 and $Lft_Carrage_Position < 750)
Goto (Wait_ARS_Loop) # Go back and do this again because the carriage is not fully out.
endif
# Arms should now be fully out and arms can safely move.

As you can see above this EZ Script is commanding two motors through one Kangaroo, I have no idea how to do the above with JS. I know I'll have to figure out a different way to do the looping as JS does not use GOTO and labels like this. If I could get some help with splitting returned characters and getting characters at a certain place this would be very helpful.

Here's the complete EZ Script for reference if it helps: Be kind. It's probably messy. LOL. Any ideas or advice are very welcomed that will improve it or help with conversion to JS. Thanks in advance!

# Move Both Carriages Out of torso
# -----------------------------------------------------------------
$Both_ARS_Extended = 0 #Sets Variable to both ARS still in torso. 0=in, 1=out
ClearVariable("$Get_Lft_Carrage_P") #Clears Variable in case it's in an Array
ClearVariable("$Get_Rt_Carrage_P") #Clears Variable in case it's in an Array

Sleep(100)

uartWrite(2, 2, "1,p805 s300", 0x0d) #Move Rt ARS Carriage full out
Sleep(50)
uartWrite(2, 2, "2,p805 s300", 0x0d) #Move Lft ARS Carriage full out

# ------------------
# Loop to Read & send Carriage position info for Waiting Automation Arm
# Script so it can safely start moving arms when Carriage is fully out.
# The following will get the position of the LFt & Rt Kangaroo positions

# --------------------

:Wait_ARS_Loop

# Get Right Carriage Roo Position
uartWrite(2, 2, "1, Getp", 0x0d)

:waitFor_Rt_Data
Sleep(30)

$y = UartAvailable(2, 2)
# Sleep(30)
# print("Bytes in buffer:" + $y)
if ($y < 6)
  # Go back and wait for data again because we did not receive the least number of expected bytes.
  goto(waitFor_Rt_Data)
endif

$Get_Rt_Carrage_P = UARTRead(2, 2, $y)
# Sleep(30)
# print("Received:" + $Get_Rt_Carrage_P)
Sleep( 150 )

# -------------------------------
# Find out (and print if wanted) if the P is upper or lower case.
# Upper case means the motor has finished moving and stopped.
# Lower Case means that the motor is still moving.
$P_or_p = GetCharAt($Get_Rt_Carrage_P, 2) #Assign a variable to either a capital P or Lowercase p returned by Kangaroo.
# Print("P_or_p:" + $P_or_p)

# -----------------------------
# # Defeat the P_or_p because it must die!

if ($P_or_p = "p")
  $Rt_Carrage_Position = Split($Get_Rt_Carrage_P, "p",1) #1,pXXXX is returned. Get everything after the Lowercase p (P is case sensitive).
ELSE ($P_or_p = "P")
  $Rt_Carrage_Position = Split($Get_Rt_Carrage_P, "P",1) #1,pXXXX is returned. Get everything after the Upper case P (P is case sensitive).
endif
Sleep(50)

# -----------------------------------------------------------
# Get Lft ARS Roo position

uartWrite(2, 2, "2, Getp", 0x0d)

:waitFor_Lft_Data
Sleep(30)

$y_lft = UartAvailable(2, 2)
# Sleep(30)
# print("Bytes in buffer:" + $y_lft)

if ($y_lft < 6)
  # Go back and wait for data again because we did not receive the least number of expected bytes.
  goto(waitFor_Lft_Data)
endif

$Get_Lft_Carrage_P = UARTRead(2, 2, $y_lft)

# Sleep(30)
# print("Received: " + $Get_Lft_Carrage_P)
Sleep( 150 )

# -------------------------------

# Find out (and print if wanted) if the P is upper or lower case.
# Uppercase means the motor has finished moving and stopped.
# Lower Case means that the motor is still moving. We need to know so we can move past this to the rest of the script.

$P_lft_or_p_lft = GetCharAt($Get_Lft_Carrage_P, 2) #Assign a variable to either a capital P or Small case p returned by Kangaroo.
# Print("P_lft_or_p_lft:" + $P_lft_or_p_lft)

# -----------------------------

# Defeat the P_lft_or_p_lft

if ($P_lft_or_p_lft = "p")
  $Lft_Carrage_Position = Split($Get_Lft_Carrage_P, "p",1) #1,pXXXX is returned. Get everything after the Lowercase p (P is case sensitive).
ELSE ($P_lft_or_p_lft = "P")
  $Lft_Carrage_Position = Split($Get_Lft_Carrage_P, "P",1) #1,pXXXX is returned. Get everything after the Upper case P (P is case sensitive).
endif

  # ------------------------------
  # The following will loop and read both of the actual ARS carriage positions
  # until both carriages are full out past 750 (830 is actually full out but
  # this starts the animation a little early to take away any delay).
  # Sleep(150)
  # Get$Rt_Carrage_Position
  # Get$Lft_Carrage_Position
  # Sleep(500)
Print($Rt_Carrage_Position)
Print($Lft_Carrage_Position)

if ($Rt_Carrage_Position >= 751 and $Lft_Carrage_Position >= 751)
  $Both_ARS_Extended = 1 #Rt Carriage fully out. Set this variable so the waiting Automation Script knows the carriage is fully out.
ELSE ($Rt_Carrage_Position < 750 and $Lft_Carrage_Position < 750)
  Goto (Wait_ARS_Loop)  # Go back and do this again because the carriage is not fully out.
endif
  # Arms should now be fully out and arms can safely move.
#17  

OK, I decided I was biting off to much at one time. I decided to just concentrate on trying one JS command at a time to see if I can get stuff working. I'm starting with the Uart command.

I'm making progress on making things work like checking if variables exist and initializing Uart ports. I'm been able to run several commands without errors so I think I'm catching on. However I've hit a wall.

After initializing the proper Uart port I decided to try to move a motor by sending a command through the port to the Kangaroo Motor controller. Like I mentioned  and showed above I've been able to do this using EZ Script. I followed @DJ's tutorial and the online JavaScript API here on this forum in the support section with no luck. The script ran and compilated with out an error but the Kangaroo didn't respond. I think the problem is how I'm sending the string to the roo. It needs a Return (enter) keyed after the position and speed command and I don't think I have that properly written in JS. Here's the EZ Script command that works makes the Kangaroo respond. Notice the 0x0d (ASCII for carrage return) :

uartWrite(2, 2, "1,p805 s300", 0x0d)

Here's the code I wrote in JS that I think is close (from what I read in the JavaScript API in the support section). The script completes and seems to send it through the UART. Again, I don't think I have the 0x0d part of string written properly. But I don't really know.

var str = "2,p805 s300 0x0d";
UART.hardwareUartWrite(2,str.length,2);
UART.hardwareUartWriteString(2,str,2);

Any help figuring this out would be welcomed.

#18  

I don't know if this is a dumb suggestion but I just noticed that Chat A.I. can write Java script code for you if you just ask what you need done. I looked at some examples that seem legit. Sorry if that is no help. Your problem stems from the Kangaroo so, Depends if A.I. can find previous solutions in other forum posters around the internet.

#19  

Thanks my friend. I've never used any chat AI programs. I wouldn't know how to start. However you gave me a good idea. I'll contact the Dimension Engineering who make the Kangaroo. Maybe they can tell me a way to send the simple serial command for speed, position and the needed "return" key using JavaScript. I had this same issue when I started commanding the Roo using EZ Script. It's that "return" (or Enter) key, 0x0d, that I cant figure how to get into the JavaScript command.

#20   — Edited

HAHA!! Got it!! Yes!!

I found the answer on the Stackoverflow forum. A guy there was working on a different problem he was having with a Python script that controls his Kangaroo. I looked through his script and saw in his Python script that he has a \r inside his double quotes and the end of his string. I inserted it and it works!!

So the proper script that works (once the UART initialized) is as follows. Note the \r at the end of line 1:

var str = "2,p805 s300\r"; UART.hardwareUartWrite(2,str.length,2); UART.hardwareUartWriteString(2,str,2);

#21  

Great news Dave, Glad you solved it and have a great Easter!

#23  

I've been making slow but sure progress with converting my EZ Script I posted above into Javascript. I'm able to do most basic things now like looping and If statements. I've also been able to send and commands to my Kangaroo using the UART. commands. I'm pretty excited at how little syntax I need and how fast it appears to be.

I do have a question about one of the UART. commands that I hope some one could help explain. When I'm asking to read bytes from the UART buffer I seem to have two commands available:

UART.hardwareUartReadString(uartIndex, bytesToRead, [ezbIndex])
UART.hardwareUartReadStringAvailable(uartIndex, [ezbIndex])

When I run these commands with different scripts I get the same returned answers: Script 1 using UART.hardwareUartReadStringAvailable


var getRightp = "1, Getp\r";
UART.hardwareUartWrite(2,getRightp.length,2);
UART.hardwareUartWriteString(2,getRightp,2);
sleep( 500 );

var UartAvailable = UART.hardwareUartAvailable(2,2);
print("UartAvailable: " + UartAvailable);

var UartReadStringAvailable = UART.hardwareUartReadStringAvailable(2,2);
print("UartReadStringAvailable: " + UartReadStringAvailable);

Script 1 Answers:

> UartAvailable: 7
> UartReadStringAvailable: 1,P20

Script 2 using UART.hardwareUartReadString

var getRightp = "1, Getp\r";
UART.hardwareUartWrite(2,getRightp.length,2);
UART.hardwareUartWriteString(2,getRightp,2);
sleep( 500 );

var Position = UART.hardwareUartReadString(2,7,2);
print("hardwareUartReadString: " + Position);

Script 2 Answers:

> UartAvailable: 7
> hardwareUartReadString: 1,P20

As I said, I get the same answers. The only differance I can see is that in UART.hardwareUartReadString I need to state how many bites I am expecting. This has proven a problem because I've notices that sometime the buffer has more then the usual 7 bytes available. Mostly after a failed read.

Can someone explain which is the best command to use and/or why I would have to state how many bytes I'm expecting if I use UART.hardwareUartReadString ?

Thanks!

#24   — Edited

Well, it's been a learning experience for me. However with the help of the tutorial at the top of this page, the Synthiam JavaScript api at the link provided in that same tutorial along with many, many tips throughout the internet to JS scripting sites I was able to convert the EZ script I posted above to JavaScript.

As I said, I'm a novice to JS and mostly understand how to write a working script in EZ Script. I'm starting to understand some of the basic nuances of JS and have made a converted working script. It looks much neater and runs much smoother and faster then my original EZ Script. At this point I'm satisfied with my result but after seeing how much I don't know about JS I'm not sure it's done as well as possible. However it works nice for my needs and I'm happy. LOL.

My intent is to move two carriages that are powered and controlled by a Sabertooth / Kangaroo motor controller. They must move out of an enclosed robot torso until they reach a save point before the arm servos can start moving around. I could just send the carriages out and hope they reach a safe point but if the arms starts moving around before they are clear they will destroy themselves. This script has a built in fail safe to keep that from happening. It monitors the progress of the carriage motor's encoders, Then when it reaches safety it sets a global variable that tells a different waiting script (it's an EZ Script at this point) that it's safe to start moving the arm servos.

Here it is for your enjoyment. LOL. :

//Extend Right Arm Carriage
var rt_carrage_PosSpeed_Roo_cmd = "1,p809 s300\r";
UART.hardwareUartWrite(2,rt_carrage_PosSpeed_Roo_cmd.length,2); //UART 2 on EZB 2
UART.hardwareUartWriteString(2,rt_carrage_PosSpeed_Roo_cmd,2); //UART 2 on EZB 2

//Extend Left Arm Carriage
var lft_carrage_PosSpeed_Roo_cmd = "2,p809 s300\r";
UART.hardwareUartWrite(2,lft_carrage_PosSpeed_Roo_cmd.length,2); //UART 2 on EZB 2
UART.hardwareUartWriteString(2,lft_carrage_PosSpeed_Roo_cmd,2); //UART 2 on EZB 2

sleep( 100 );

//Start of if Statemant
do{
///////////////
//Right ARM
//////////////

//Send Request to Kangaroo Channel 1 to Get Position of Right Carriage
var getRightp = "1, Getp\r";
UART.hardwareUartWrite(2,getRightp.length,2); //UART 2 on EZB 2
UART.hardwareUartWriteString(2,getRightp,2); //UART 2 on EZB 2

//Pause to let UART Buffer fill
sleep( 100 );

//Read Full String Actual Position of Right Carriage. Expecting 1,pxxx (Lowercase p - Still Moving)) or 1,Pxxx(Upper case P - Movment Stopped)
var UartReadStringAvailable_RT = UART.hardwareUartReadStringAvailable(2,2);
print("UartReadStringAvailable_RT: " + UartReadStringAvailable_RT);

//Get the Actual Last Numaric String of Right Carriage Posistion Without the P. Expecting 0 Thru 805
var actualPosition_RT = UartReadStringAvailable_RT.substr(3, 7);
print( "actualPosition_RT: " + actualPosition_RT );


///////////////
//Left ARM
//////////////

//Send Request to Kangaroo Channel 1 to Get Position of Right Carriage
var getLeftp = "2, Getp\r";
UART.hardwareUartWrite(2,getLeftp.length,2); //UART 2 on EZB 2
UART.hardwareUartWriteString(2,getLeftp,2); //UART 2 on EZB 2

//Pause to Let UART Buffer Fill
sleep( 100 );

//Read String in UART Buffer of position of Right Carriage from Kangaroo. Expecting 1,pxxx (Lowercase p - Still Moving)) or 1,Pxxx(Upper case P - Movment Stopped)
var UartReadStringAvail_Left = UART.hardwareUartReadStringAvailable(2,2); //UART 2 on EZB 2
print("UartReadStringAvail_Left: " + UartReadStringAvail_Left);

//Get the Actual Last Numaric String of Left carriage posistion without the P. Expecting 0 Thru 805
var actualPosition_Left = UartReadStringAvail_Left.substr(3, 7);
print( "actualPosition_Left: " + actualPosition_Left );

//End of if Statement
}  while(actualPosition_RT < 808 && actualPosition_Left < 808 );

print("Final Reading Left: " + actualPosition_Left);
print("Final Reading: " + actualPosition_RT);

//Sets the Global Variable a waiting script is waiting for before it starts moving servos. 
setVar( "$Both_ARS_Extended",1 )

Here's the console readout:


> actualPosition_Left: 405

> UartReadStringAvailable_RT: 1,p467

> actualPosition_RT: 467

> UartReadStringAvail_Left: 2,p489

> actualPosition_Left: 489

> UartReadStringAvailable_RT: 1,p551

> actualPosition_RT: 551

> UartReadStringAvail_Left: 2,p572

> actualPosition_Left: 572

> UartReadStringAvailable_RT: 1,p638

> actualPosition_RT: 638

> UartReadStringAvail_Left: 2,p656

> actualPosition_Left: 656

> UartReadStringAvailable_RT: 1,p726

> actualPosition_RT: 726

> UartReadStringAvail_Left: 2,p744

> actualPosition_Left: 744

> UartReadStringAvailable_RT: 1,p795

> actualPosition_RT: 795

> UartReadStringAvail_Left: 2,p799

> actualPosition_Left: 799

> UartReadStringAvailable_RT: 1,p808

> actualPosition_RT: 808

> UartReadStringAvail_Left: 2,p808

> actualPosition_Left: 808

> Final Reading Left: 808

> Final Reading: 808

Done (00:00:03.3421916)