Asked — Edited
Resolved Resolved by DJ Sures!

Javascript Question - Var Or Setvar?

@Athena  When I write a script using Javascript and I want to set a variable what command should I use. I've used both setVar and simply just Var. Both have worked for me.

For example I have this in my INT Script that runs when my project starts:

setVar( "$adcSoilSpecified", 200 );

And I have this in a stand alone script that operates a motor and watches an encoder:

var Get_Lft_Elbow_P = "2, Getp\r";
UART.hardwareUartWrite(0,Get_Lft_Elbow_P.length,2); //UART 0 on EZB 2

Which is the correct one to use and what is the difference between the two?


Related Hardware EZ-B v4

ARC Pro

Upgrade to ARC Pro

Don't limit your robot's potential – subscribe to ARC Pro and transform it into a dynamic, intelligent machine.

PRO
Canada
#57  

Implementing a counter in your loop to prevent infinite looping and ensure the script stops after a certain number of iterations is a straightforward task. Based on your description, you want the script to attempt re-centering the arm, and if it doesn't hit the opto switch within 25 to 35 loops, the script should stop to prevent reaching the end limit.

Here's how you can modify your loop to include a counter and a maximum number of attempts. This example assumes you have a function or condition to check if the opto switch is triggered (optoSwitchIsTriggered() as a placeholder) and a way to move the arm in small increments (moveArmIncrement() as a placeholder):

var maxAttempts = 30; // Maximum number of attempts to re-center the arm
var attempts = 0; // Counter for the number of re-centering attempts

// Loop until the opto switch is triggered or the maximum number of attempts is reached
while (!optoSwitchIsTriggered() && attempts < maxAttempts) {
    moveArmIncrement(); // Move the arm in small increments towards the center
    attempts++; // Increment the attempts counter

    // Optional: Add a delay between attempts if needed
    sleep(250); // Adjust the delay as necessary
}

// Check if the loop exited because the maximum number of attempts was reached
if (attempts >= maxAttempts) {
    // Handle the situation where the arm did not re-center within the maximum attempts
    console.log("Failed to re-center the arm within the maximum number of attempts.");
    // Add any additional error handling or recovery actions here
}

In this example, the loop will continue to attempt re-centering the arm by calling moveArmIncrement() until either the opto switch is triggered (indicating successful re-centering) or the maximum number of attempts (maxAttempts) is reached. If the maximum number of attempts is reached without triggering the opto switch, the script logs a message, and you can add any additional error handling or recovery actions in that section.

Remember to replace optoSwitchIsTriggered() and moveArmIncrement() with your actual implementation for checking the opto switch status and moving the arm. The sleep(250) function is used to add a delay between attempts, which you can adjust or remove based on your needs.

This approach ensures that the script will not loop indefinitely and provides a mechanism to handle situations where the arm cannot be re-centered as expected.


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
#58   — Edited

I do believe I have this script working now with all the guidance from @DJ and @Athena. Thanks once more. Between your help and the studying I'm doing in the internet in places like W3 Schools I'm learning a lot. I'm even starting to be able to write the Jacascript in proper styles. Spaces, indents and Semicolons aren't such a mystery anymore. Of course I still have lots to learn but it's coming.

So here's the completed and working block of code I (we) wrote.  I'm using a Do/While loop as is seems easier for me to see what's going on and seems more logical to me to use here. So, once the arm move is complete to the center of it's ARC it will check the opto switch closed through the ADC reading. It will also keep a count of the loops it takes to move the motor to the Opto. I know it's about 20 or so loops using the speed and sleep setting I've written in. If it counts more then 25 loops the whole script will stop. That will bring the whole robot to a stop and at this time that's OK. I do not want the arm trying retract into the robot or the robot to move around with the arm sticking out. Until i come up with a safe reset retinue this will be great.

I'm just attaching the working block of this script that will center and check the left arm. if it's not centered on the first move then it will move it a little ways away and slowly retry. Thanks for looking and all the help. I'm always open to listen to suggestions or constructive criticism.


**********************
Check Left Elbow Opto Switch closed and AutoCenter if needed
If closed we know the arm is centered and in position.
**********************
This Var Sets the startingl position away from center to start countdown back to center*/
var lft_elbow_AutoCenterStart = 2700;

sleep(100);

/*Looks at target ADC reading of Opto Switch for Elbow center. 
Above 185 to 255 is considdered center. If not embow will try to auto center*/
if (ADC.get(1, 2) < 185) { //Start Auto Center if ADC is below 185. Not centered.
  sleep(100);
  print("Left Arm Not Centered! Try to calibrate.");
  ControlCommand("Soundboard 2", "Track_20"); //Say "Please Stand By"

sleep(2500);

 /*Command moves the elbow to different start position away from center to start 
 countdown back to center*/ 
UART.hardwareUartWriteString(0,"2,P" + (lft_elbow_AutoCenterStart) + "s1600\r" ,2);

sleep( 1000 );

var attempts = 0; // Counter for the number of re-centering attempts
do{
  var Left_Elbow_ADC = ADC.get(1, 2); //Start Auto Center if ADC is below 185
  UART.hardwareUartWriteString(0,"2,P" + (lft_elbow_AutoCenterStart-=10) + "s1000\r" ,2); //Connected to UART 0 on EZB 2
  sleep(1000);
  print("ADC Read: " + Left_Elbow_ADC);
  sleep(100);
  attempts ++;// Increment the attempts counter
  print("Loops: " + attempts); //Shows how many loops have been proformed
  if (attempts >= 25) {
    ControlCommand("Soundboard v4", "Track_44"); //Say "Halt"
    print("Arm could not find center switch");
    halt();
  }
sleep(100);  
}
while(Left_Elbow_ADC < 185); //Once ADC gets above 185, script will continue
  sleep(100);
  print("ADC Final Read: " + Left_Elbow_ADC); //Get ADC Value on ADC Port 1 from EZB 2 and Print
//ControlCommand("Soundboard v4", "Track_86"); //Say "conclusion"
  sleep(500);
  var lft_elbow_position = get_lft_elbow_MovementValue();
  print("Left Arm Centered! Safe to Retract!"); //Left Arm Centered! Safe to Retract. Fully cnetered should read about 255
  print("Left Arm ADC Reading: " + Left_Elbow_ADC)
  print("Left Elbow Final Position: " + lft_elbow_position);
}
PRO
Canada
#59  

It's fantastic to hear that you've made significant progress with your script and are gaining confidence in writing JavaScript! Your willingness to learn and apply new concepts is commendable. The approach you've taken with the do/while loop and incorporating a counter for loop iterations is a solid strategy for ensuring your robot's arm movements are precise and safe.

Here's a general review and suggestion for your described approach:

  1. Do/While Loop: Using a do/while loop is indeed a good choice when you want the loop to execute at least once before checking the condition. This fits well with your scenario where you want to attempt to center the arm and then check if the operation was successful.

  2. Loop Counter: Implementing a loop counter to prevent infinite looping is a best practice, especially in robotics where physical movements are involved. Setting a reasonable threshold for the number of attempts helps ensure safety and prevents potential damage.

  3. Opto Switch Check: Using an opto switch as a feedback mechanism for arm positioning is a smart way to achieve precise control. It's great that you're checking the opto switch status to confirm the arm's position.

  4. Error Handling: Having a plan for what to do if the arm doesn't center correctly is important. Stopping the robot and preventing further movements until the issue is resolved is a safe approach. In the future, you might consider adding more sophisticated error recovery routines, such as attempting to re-center the arm a certain number of times before giving up.

  5. Code Readability: It's great to hear that you're focusing on writing clean and readable code. Proper formatting, such as consistent indentation, spacing, and the use of semicolons, makes your code easier to understand and maintain.

Without seeing the specific code block, these are general observations and suggestions based on your description. If you have any specific questions or need further assistance with your script, feel free to share more details or ask for help.

Keep up the great work, and remember that learning to program effectively is a journey filled with continuous improvement. Your dedication to learning and applying best practices will undoubtedly lead to success in your robotics projects.


I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.
#60  

@Athena, Is there a way to clear or delete a global variable that is set into my ARC project using Javascritp? EZ Script had a way to clear a variable but I can't see one for Javascript that seems right.

I have a global variable called $RtArmRailPosition and it's value is 800. I don't think it matters but this value was created and placed into a Javascript VAR variable from a reading of a motor encoder.  I used the following javascript command to then set the Javascript VAR variable into my ARC project as a Global $ variable:

setVar( "$RtArmRailPosition", RtArmRailPosition);

This global variable may interfear with other scripts that will run and I want to delete, reset or clear it. Any suggestions?

#61   — Edited

Edit to my last post: I may not need to clear the variable I was talking about above. I hope I fixed a script that was causing this issue and the variable will update it's value instead. It's a learning process. LOL. Still I'm interested in finding out the answer to my question above.;)

PRO
Synthiam
#62  

Remember that a global variable allows access between scripts. If you're not using the value of that variable in other scripts, don't make a it global.

  1. Also, use a different variable name if you don't want them to interfere. Because "clearing it" just means setting it to a different incorrect value that the other script would use.

  2. Lastly, using the same global variable across scripts that share it is a bad idea because they can run at the same time.

You didn't say why it was global, but if it doesn't need to be, don't make it global. Don't use setVar() or getVar() on it.

#64  

@Athena ,

I've repurposed the script below for use watching a different motor controlled by a Kangaroo motor controller and a Sabertooth. I've made the correct changes to reflect the new ports and EZB numbers and simple serial commands being sent to the Kangaroo through an EZB Uart port. Everything works as expected. Except......

On the new motor setup the motor reading being retrieved from the Kangaroo goes below zero to -20. So the position numbers for the range of motion are between -20 and 800. The script runs correctly and returns the expected motor position as long as the returned value stays above zero. Once the returned value drops into the negative numbers I get back incorrect position values. Also the bytes being read in the Uart have changed from 9 to 8 but I think I've got that fixed by changing that value to 8  in these lines. I think:

// get bytes available on UART #0, EZB #2
var avail = UART.hardwareUartAvailable(0, 2);

// If we don't have at least 9 characters, return -1
if (avail < 9)
return -1;

// read 9 bytes from UART #0 on EZB #2
var resp = UART.hardwareUartReadString(0, 9, 2);

I've tried many different changes to this script but can't seem to get it to work once the position value drops below zero. Can you advise on the proper changes to get it to work with negative returned numbers? Also am I correct about changing the value in the Uart read and available lines? Thanks.

//Move Right Elbow motor to Center
UART.hardwareUartWriteString(0,"1,P2470 s1600\r",2); //Connected to UART 0 on EZB 2

//Move Left Elbow motor to Center
UART.hardwareUartWriteString(0,"2,P2490 s1600\r",2); //Connected to UART 0 on EZB 2

// loops until a capital P is returned on UART #0 of EZB #2
// returns the position when P is returned
// --------------------------------

// loop and we BREAK out of this loop when P is
// capital
while (true) {
   
  var position = getMovementValue();
  
  // If the position is zero or greater, we know there's a position
  // returned
  if (position > 0) {
      print("We stopped moving and the position is: " + position);
    //halt();
    break;
  }
    //sleep(50);
    
 }

// This function will return the value of the position if
// moving has completed.
// OR it will return -1 if the moving is still happening

function getMovementValue() {

// Get Right Channel ARS Kangaroo position
UART.hardwareUartWriteString(0, "2, Getp\r", 2);

sleep(100)

  // get bytes available on UART #0, EZB #2
  var avail = UART.hardwareUartAvailable(0, 2);

  // If we don't have at least 9 characters, return -1
  if (avail < 9)
    return -1;

  // read 9 bytes from UART #0 on EZB #2
  var resp = UART.hardwareUartReadString(0, 9, 2);

  // More verification this is a valid packet
  if (resp[1] != ',')
    throw new Error("Second character should be a ,");

  // Check if we have a capital P, if so, extract
  // the position and return the new value
  if (resp[2] == 'P') {
   
     // get the characters between positions 3 & 7 of the string
     var tmpPart = resp.substring(3, 7);
   
     // convert the string to an int
     var tmpInt = parseInt(tmpPart);
     
     // return the position
     return tmpInt;
  }

  // still moving 
  return -1;
}