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

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

#25  

@DJ, thanks for the hand.

Well, i have a robot arm that is controlled by a Kangaroo/Sabertooth. I want to write a Javascript that will send a "get Position" request to the roo and be able to read it's response.I already have done that and can see in the ARC script console the value. Like mentioned above, that will looks something like this: 1,P1234

I want to parse out the P because depending on if it's returned as upper or lower case, this info will tell me if the move is still in process. Once the move is done and the motor is idle and I check that the arm is centered by checking a different sensor. I can then retract the arm into the robot's body. I want to hold the script in place until it can confirm that the motor is stopped then have it move on to check that sensor to make the arm is centered. I need to know if the P is upper or lower case.

PRO
Synthiam
#26  

Here i had to clean a few things up...

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

// Initialize UART port (if not already initialized)
// UART 0 
// baud rate of 9600
// EZB Index #2
UART.initHardwareUart(0, 9600, 2); 

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

// loop forever because 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();
  }
  
  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 bytes avaiable on UART #0, EZB #2
  var avail = UART.hardwareUartAvailable(0, 2);

  // If we don't have enough characters, return -1
  if (avail < 7)
    return -1;

  // read 7 bytes from UART #0 on EZB #2
  var resp = UART.hardwareUartReadString(0, 7, 2);
 
  // Some verification that this is a valid packet
  if (resp[0] != '1')
    throw new Error("First character should be a 1");

  // 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 last 4 characters of the string
     var tmpPart = resp.slice(-4);
   
     // convert the string to an int
     var tmpInt = parseInt(tmpPart);
     
     // return the position
     return tmpInt;
  }

  // still moving 
  return -1;
}
PRO
Canada
#27  

It looks like DJ Sures provided a comprehensive solution for your scenario. The script he provided is designed to continuously check the UART port for a response from the Kangaroo controller. It specifically looks for a response that indicates whether the motor movement has completed, based on the case of the letter 'P' in the response.

To address your question about parsing the 'P' and why you're getting NaN when trying to parse using .substr(2,4), it's important to understand how string parsing and conversion to numbers work in JavaScript.

The NaN result occurs when parseInt() is called on a string that doesn't start with digits. In your case, when you try to parse 'P' or any non-numeric part of the string, parseInt() cannot convert it to a number, hence it returns NaN.

If your goal is to check whether the 'P' is uppercase or lowercase, you don't need to convert it to a number. Instead, you can directly compare the character. Here's a simplified example based on DJ Sures' approach:

function getMovementValue(){
    var avail = UART.hardwareUartAvailable(0,2);
    if(avail < 7) return -1;

    var resp = UART.hardwareUartReadString(0,7,2);
    if(resp[0] != '1') throw new Error("First character should be a 1");
    if(resp[1] != ',') throw new Error("Second character should be a ,");

    var movementStatus = resp[2]; // This is your 'P' character
    var positionPart = resp.slice(-4);
    var positionValue = parseInt(positionPart);

    if(movementStatus === 'P'){
        // Movement completed, uppercase P
        return positionValue;
    } else if(movementStatus === 'p'){
        // Movement still in progress, lowercase p
        return -1; // Or any indicator you prefer for movement in progress
    } else {
        // Unexpected character, handle accordingly
        return -1;
    }
}

This function checks the case of 'P' to determine the movement status and parses the position part of the response to get the numeric value. It returns the position value if the movement has completed (uppercase 'P') or -1 (or any other indicator you prefer) if the movement is still in progress (lowercase 'p').

Remember, the key here is to directly work with the character for case comparison and only parse the numeric part of the string to get the position value.


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.
#28  

I'll need to look closer and test more. I'm running out of time this evening. However I tried it and after one error and a change it ran. I think it's working.  The error I got was:

Execution Error Line 50 Col 4 - First character should be a 1 Done (00:00:00.0978231)

Here is that line:  // Some verification that this is a valid packet if (resp[0] != '1') throw new Error("First character should be a 1");

The change I made was this change: if (resp[3] != '2') throw new Error("First character should be a 2");

By changing the position and the number to expect it ran just fine. It looks like it doesn't see the first character which is the 1 (the number 1 kangaroo channel). I tried placing a sleep before this command thinking the kangaroo needed a little time to respond but it didn't help.

I think we're close to what I need. I'll have to spend a little more time tomorrow on this. Thanks for the help and direction!

#29  

@DJ, I've spent most of the day looking, testing and running these scripts two script you and @Athena so kindly wrote up for me. I got yours to run with a minor adjusting to match up with my system. Even with a lot of fiddling around I couldn't figure out how to get Athena's script to run. It just seems to loop forever. It just be my lack of skills.

Once I settled on adjusting and using your script I ran into a coupe more problems. I think it's got to do with the Kangaroo it's self and not the script. I can only properly run your script once. The second time I run it, it throws an error (as it should I'm guessing) because it cant verify a packet returned by the Kangaroo when it gets to these two lines:

//Some verification that this is a valid packet
  if (resp[0] != '2')
    throw new Error("First character should be a 2");

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

Now, If I run a different and separate script in ARC asking the Kangaroo for position, that script will return a NAN once and the second time I run it, it will give me the position. Then I'll go back to your script and it will then run without throwing the error and stopping. Again, this seems like something to do with the Kangaroo. It's like it's stuck until it get a couple of different commands.

The other issue is that when the script does run sometimes it gets stuck in a loop and wont break out. Again, probably because the roo isn't or cant send the requested packets fast enough. ??? Still another issue is that the script will stop and report the movement is stopped while in fact the motor is still moving.

I want to again thank you for your reaching out to help me on this. I do not expect you to solve this issue for me as, like I said, after testing this for many hours I've come to believe that this behavior is because of limitations of the Kangaroo. I'm just going to have to figure out another way to check if the arm has stopped moving to the position commanded.

PRO
Canada
#30  

It sounds like you've made significant progress with the script and troubleshooting, but you're encountering some challenges that seem to be related to the Kangaroo controller's behavior. Let's address the issues you've mentioned and explore potential solutions or workarounds:

  1. Script Running Once Successfully, Then Failing:

    • The issue with the script running successfully once and then failing on subsequent runs might be related to how the Kangaroo controller handles serial communication and its internal state. It's possible that the Kangaroo requires a specific sequence of commands or a reset command to properly prepare it for the next set of instructions.
  2. Script Looping Indefinitely:

    • If the script gets stuck in a loop, it might be due to not receiving the expected response from the Kangaroo. This could be caused by timing issues, where the Kangaroo hasn't yet updated its status by the time the script checks for it. Introducing a delay or a timeout mechanism in the loop could help manage timing issues.
  3. Motor Still Moving Despite Script Reporting Stop:

    • This issue could be related to how the movement completion is detected. If the script checks for a specific character ('P' in your case) to determine movement completion, ensure that the Kangaroo consistently sends this character only when the movement has indeed stopped. It might be helpful to log or print out the responses from the Kangaroo to verify the consistency of the data being sent.

Given these challenges, here are a few suggestions to further troubleshoot and potentially resolve the issues:

  • Reset Command: Investigate if the Kangaroo supports a command to reset its state or clear its buffer. Sending such a command before requesting the position might help ensure consistent behavior.

  • Command Sequence: Review the Kangaroo documentation to verify if there's a recommended sequence of commands for querying the position and detecting movement completion. It's possible that an additional command or step is needed to prepare the Kangaroo for subsequent queries.

  • Delay and Timeout: Introduce a delay before querying the Kangaroo for its position to give it enough time to process the previous command and update its status. Additionally, implementing a timeout mechanism in the loop can prevent the script from getting stuck indefinitely.

  • Response Logging: Log or print out all responses from the Kangaroo, not just the parsed position or status. This can help identify any inconsistencies or unexpected behavior in the data being sent by the Kangaroo.

  • Kangaroo Support: If the issues persist and seem to be related to the Kangaroo's behavior, consider reaching out to the manufacturer's support for insights or recommendations specific to the Kangaroo controller.

Remember, troubleshooting complex interactions between custom scripts and hardware controllers can be challenging, but systematic testing and validation of each step can help isolate and resolve the issues.


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.
#31  

@Athena , thanks for all those suggestions. Actually while I was testing these scripts and experiencing these problems, I did try most of them. To expand;

*Their are no reset commands I know of that I can find for the Kangaroo except a "Powerdown" and "Start" command. That would probably do the trick, however in a fast running loop I dont think that's practical. I did try to slow down the loop but it didn't help.

*I tried to insert many sleep() commands in the places that I thought would benefit from a pause to let the hardware process. However, no results.

*I used the print() command by storing returned data in a variable and was able to view the capital "P" so I know at least that it's visible and there (when the Kangaroo is able to return it's status). I tried to view the lowercase "p" while the movement was underway but that's when the loop wouldn't stop. Probably something I screwed up while making changes in the Javascript.

*I'm confident I'm sending the proper commands to the Kangaroo as they have worked for me in other Javascript and EZ Scripts.

In the end I think it may come down to timing of the script and/or the ability of the Kangaroo and/or the Uart port to pass the requested data. The most troubling issue is the fact that the Kangaroo (or Uart port) seems to stop responding to the same command after running the script more then once to request the data . As mentioned above, the script of @DJ I used checks the packet for the expected data and works the first time it runs but stops the second time I run it with the error message that it was expecting a "1" and a ",". I guess what it was expecting was not there. It takes a different command from a different script to get a response. Even that second script takes two tries to not get a NAN response.

Odd thing is that if I just start using the EZ Scripts I wrote years ago to send a command to the Kangaroo to return a position (before trying to use a  Javascript written script) I can get a position reading returned every time, all day long. However I've never tried to get the actual status of the "P" returned from the roo. I've always relied on just the position and not checking if the movement is underway or has ended. Like mention above a capital P means the movement has stopped and a lower case p means it still under way.

Final thoughts: I'm trying to see when the motor movement has stopped and reached it's commanded position in JavaScript. Reading the status of the "P" in the returned data (example: 1,p3214) shows that. Maybe I simply need to start the movement, use a sleep() command to wait, then confirm the movement is stopped by getting the P only once instead of looping the script and bombarding the Kangaroo with read requests. I don't know, I gotta think about this more.

Again, thanks for all the help and letting me talk this out.

PRO
Canada
#32  

It sounds like you've been thorough in your troubleshooting and experimentation with the Kangaroo controller and the scripts. Your observations and the challenges you've encountered highlight the complexities of real-time communication and status monitoring with hardware devices. Given the insights you've shared, let's consider a few additional thoughts and potential strategies moving forward:

  1. Single Query Post-Movement: As you mentioned, instead of continuously looping and querying the Kangaroo for its status, you might try a different approach where you:

    • Start the movement.
    • Use a sleep() command with an estimated duration that you expect the movement to take. This duration could be slightly less than the actual expected time to complete the movement.
    • After the sleep(), query the Kangaroo for its status (the P value) only once to check if the movement has stopped. This reduces the number of queries and might help avoid overwhelming the Kangaroo or the UART buffer.
  2. Adjusting Expectations and Error Handling: Given that the Kangaroo sometimes does not respond as expected on subsequent queries, you might want to implement more flexible error handling in your script. For example, if a query does not return the expected packet format, you could:

    • Retry the query a limited number of times before throwing an error.
    • Log unexpected responses for further analysis to understand if there's a pattern or specific conditions under which these occur.
  3. Exploring Alternative Feedback Mechanisms: If the Kangaroo's response regarding movement status (P value) proves to be unreliable or difficult to use as a sole indicator, consider if there are alternative ways to determine that the movement has completed. For example:

    • If the motor movement results in a physical change that can be detected by another sensor (e.g., a limit switch, optical sensor, or even a camera), you might use that as a secondary confirmation of movement completion.
    • If the Kangaroo controller supports other forms of feedback or status indicators that are more reliable or easier to parse, those might be worth exploring.
  4. Consulting with the Manufacturer: If you haven't already, reaching out to the manufacturer or the community around the Kangaroo controller might provide additional insights or undocumented features that could help. Sometimes, there are firmware updates, best practices, or workarounds that other users or the developers can share.

Your approach of "talking this out" and methodically working through the problem is commendable. Complex hardware-software interactions often require iterative testing and creative problem-solving. Your willingness to explore different strategies and adapt your approach based on the behavior you observe is key to finding a solution that works for your specific application.


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.