Spain
Asked — Edited

Script Manager And Script Pauseon

You can pause a script and then unpause? I'm trying to run my personal radar control and I have a script that moves the servo ping sensor, but I would like to pause the movement when turning to avoid obstacle and then unpause to move forward. I have proven this if successful: CC ("Script Manager" ScriptPauseOn, "radar") Not if it is misspelled or does not exist the command "PauseOn" for Script Manager I have also proven with the command PauseMS but seems not to work. Thanks in advance for your answers:)


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.

United Kingdom
#9  

Edit: Scrap all I just said (which you can't see now as I'm editing the post:))

Why not use the Radar Scan control? It should do most, if not all of what you want.

Spain
#10  

The control "Radar Scan" is great, and corrects the direction to the opposite side of the obstacle (guess which bisects the "cone" or total angle radar scan, and take decisions based on that half of the sweep is) My idea is to divide the total sweep angle in three parts

  • left
  • center
  • right

    User-inserted image

To take advantage of the ability to decide to stand in the front, does not have to be a left or right turn or have to be equal-time spin, reverse or detected distance, can be a script that includes a complete maneuver to dodge . I also like the idea of experimenting with a single ping sensor, while I practice and learn ez-scripts:)

United Kingdom
#11  

Fair enough:)

It would probably pay to look at my IR detection script and adjust it to suit. Using GetPing rather than GetADC and adding in some servo movement parts.

IR Object Avoidance

Also, my introduction to scripting was written around an IR detection script but explained a lot better.

An Introduction To Scripting

United Kingdom
#12  

It looks like today will be a busy day so I'll break it up in to smaller chunks.

The IR Object Avoidance script converted to Ping/Echo.


# Ping Object Avoidance
# Using Ultra Sonic Ping Sensor on servo for avoidance

# Adjust values below for configuration
$pingport = D0 # Change for Ping Port
$echoport = D1 # Change for Echo Port
$maxdistance = 35 # Change for maximum distance from object before avoiding in units
$onlyforward = 0 # Only if moving forwards? 0 = no, 1 = yes
$reverseturn = 0 # Reverse before turn? 0 = no, 1 = yes
$centreturndirection = 0 # Change 0 = left or 1 = right
$turnamount = 500 # Change for how long to turn for in ms
$reverseamount = 500 # Change for how long to reverse for in ms (if applicable)
$movementspeed = 255 # Change for movement speed


# -- The Script --

# Check if only to detect when moving forwards
:detect
IF ($onlyforward = 1)
  IF ($Direction = "Forward")
    GOTO (detectstart)
  ELSE 
    GOTO (detect)
  ENDIF 
ELSE 
  :detectstart
  $currentdistance = GetPing($pingport, $echoport)
  IF ($currentdistance <= $maxdistance)
    GOTO(avoid)
  ENDIF 
  SLEEP (50)
  GOTO(detect)
ENDIF 

# The avoidance script
:avoid
IF ($reverseturn = 1)
  reverse($movementspeed,$reverseamount)
ENDIF 
IF ($centreturndirection = 0)
  LEFT($movementspeed,$turnamount)
ELSE 
  RIGHT($movementspeed,$turnamount)
ENDIF 
RETURN()

Next we need to add in the servo sweep code which shouldn't be too difficult, then have it check the servo position to determine if it's a left or a right turn that is needed, and even by how much with a bit more code too.

United Kingdom
#13  

NOTE: This has been done in bits while working on other things and is unchecked. I will check it later when I get home however until then I cannot be 100% certain it is correct (it should be).

The code for sweeping the servo to the correct location, in the right direction.


# New variables for the top of the script
$sweepmin = 25 # Change for min limit
$sweepmax = 77 # Change for max limit
$sweepcenter = 52 # Change for center position
$sweepservo = "D3" # Change for servo port
$sweepprevious = "none" # Do not change

# The sweep sub routine to be inserted at the end of the script
:sweep

# Check for previous position, if no position assume to be $sweepmax
IF($sweepprevious = "none")
  $sweepprevious = $sweepmax
ENDIF

# Get the current position
$sweepcurrent = GetServo($sweepservo)

# Move in the correct direction and store previous position
IF($sweepcurrent = $sweepmin)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepcenter)
ELSEIF($sweepcurrent = $sweepcenter and $sweepprevious = $sweepmin)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepmax)
ELSEIF($sweepcurrent = $sweepcenter and $sweepprevious = $sweepmax)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepmin)
ELSE
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepcenter)
ENDIF

# Return back to the main script
Return()

This can then be called from the main script with a Goto(sweep) command. So the code now would look like this;


# Ping Object Avoidance
# Using Ultra Sonic Ping Sensor on servo for avoidance

# Adjust values below for configuration
$pingport = D0 # Change for Ping Port
$echoport = D1 # Change for Echo Port
$maxdistance = 35 # Change for maximum distance from object before avoiding in units
$onlyforward = 0 # Only if moving forwards? 0 = no, 1 = yes
$reverseturn = 0 # Reverse before turn? 0 = no, 1 = yes
$centreturndirection = 0 # Change 0 = left or 1 = right
$turnamount = 500 # Change for how long to turn for in ms
$reverseamount = 500 # Change for how long to reverse for in ms (if applicable)
$movementspeed = 255 # Change for movement speed

# Sweep variables
$sweepmin = 25 # Change for min limit
$sweepmax = 77 # Change for max limit
$sweepcenter = 52 # Change for center position
$sweepservo = "D3" # Change for servo port
$sweepprevious = "none" # Do not change

# -- The Script --

# Check if only to detect when moving forwards
:detect
IF ($onlyforward = 1)
  IF ($Direction = "Forward")
    GOTO (detectstart)
  ELSE 
    GOTO (detect)
  ENDIF 
ELSE 
  :detectstart
  $currentdistance = GetPing($pingport, $echoport)
  IF ($currentdistance <= $maxdistance)
    GOTO(avoid)
  ENDIF 

# Sweep the servo to the next position
  GOTO(sweep)

  SLEEP (50)
  GOTO(detect)
ENDIF 

# The avoidance script
:avoid
IF ($reverseturn = 1)
  reverse($movementspeed,$reverseamount)
ENDIF 
IF ($centreturndirection = 0)
  LEFT($movementspeed,$turnamount)
ELSE 
  RIGHT($movementspeed,$turnamount)
ENDIF 
RETURN()

# The sweep script

# Check for previous position, if no position assume to be $sweepmax
IF($sweepprevious = "none")
  $sweepprevious = $sweepmax
ENDIF

# Get the current position
$sweepcurrent = GetServo($sweepservo)

# Move in the correct direction and store previous position
IF($sweepcurrent = $sweepmin)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepcenter)
ELSEIF($sweepcurrent = $sweepcenter and $sweepprevious = $sweepmin)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepmax)
ELSEIF($sweepcurrent = $sweepcenter and $sweepprevious = $sweepmax)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepmin)
ELSE
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepcenter)
ENDIF

# Return back to the main script
Return()

Next will be to determine the turn direction based on the sweep servo's location when an object is detected. Very simple to implement but I am out of time again so will cover that later.

United Kingdom
#14  

I have a few more minutes than what I thought so a few notes for myself about the next part, and the code will follow later on.

Because of how I wrote the script to start with the direction of turn is pretty easy to integrate.

It may not have made much sense until now why there was a variable for the centre turn direction, this will become apparent now. As when the sweep servo is in the centre position the turn direction could be either, depending on who writes the script. I always tend to turn left when centre as this is the direction I personally turn when I need to do a 180. However, a further idea that just popped in to my head is to check the left and right positions when a centre object is detected and use that information to determine the turn direction.

So what we need to do is figure out which area the object is in when detected.

User-inserted image

For the purposes of this script I will assume the 0 position of the servo is on the left and 100 is on the right.

So first we need to think, if an object is in the left zone the robot doesn't want to turn towards it but needs to turn away from it, so turning right. If it's in the right zone then it needs to turn left. If it's in the centre zone we need to check both the left and the right zones and turn the opposite direction to where the object is. Not forgetting to move the sweep servo back to the centre position.

It's the avoidance script which now needs to be altered to suit this.


# The avoidance script
:avoid
IF ($reverseturn = 1)
  reverse($movementspeed,$reverseamount)
ENDIF 
IF ($centreturndirection = 0)
  LEFT($movementspeed,$turnamount)
ELSE 
  RIGHT($movementspeed,$turnamount)
ENDIF 
RETURN()

We will leave the reverse before turn option available as some like it, others can do without it but it's an option that is easily turned on or off from the configuration variables at the beginning of the script.

We can do away with the $centreturndirection variable if we opt for checking left and right after a centre detection.

We also need to decide of we want the robot to just turn and continue going straight on that new path or turn, move forward slightly and turn back. So either alter the path completely or adjust the path to go around the object. This option could be added in as a configuration variable and both pieces of code written, which would allow for extra code to be written which lets the robot decide based on information it receives. But for now I will just tackle the driving around the object code.

United Kingdom
#15  

Let's make changes to the avoidance routine to suit the new brief.

We want to turn right if the object is to the left;


IF($currentposition = $sweepmin)
  RIGHT($movementspeed,$turnamount)
ENDIF

And we want to turn left if the object is to the right;


IF($currentposition = $sweepmax)
  LEFT($movementspeed,$turnamount)
ENDIF

And for the middle zone we want to check left and right, return to the middle and move in the other direction to where the object is.


IF($currentposition = $sweepcenter)
  Servo($sweepservo,$sweepmin)
  $pingmin = GetPing($pingport, $echoport)
  Servo($sweepservo,$sweepmax)
  $pingmax = GetPing($pingport, $echoport)
  Servo($sweepservo,$sweepcenter)
  IF($pingmin > $pingmax)
    Goto(moveright)
  ELSE
    Goto(moveleft)
  ENDIF
ENDIF

For simplicity I've assumed the robot will move left if the object is dead centre in front and equal distance from both left and right. This can be improved but I will cover that at a later time.

To combine them for less code


IF($currentposition = $sweepmin)
  RIGHT($movementspeed,$turnamount)
ELSEIF($currentposition = $sweepmax)
  LEFT($movementspeed,$turnamount)
ELSE
  Servo($sweepservo,$sweepmin)
  $pingmin = GetPing($pingport, $echoport)
  Servo($sweepservo,$sweepmax)
  $pingmax = GetPing($pingport, $echoport)
  Servo($sweepservo,$sweepcenter)
  IF($pingmin > $pingmax)
    RIGHT($movementspeed,$turnamount)
  ELSE
    LEFT($movementspeed,$turnamount)
  ENDIF
ENDIF

Now to put it all together one more time and the new code should look like;


# Ping Object Avoidance
# Using Ultra Sonic Ping Sensor on servo for avoidance

# Adjust values below for configuration
$pingport = D0 # Change for Ping Port
$echoport = D1 # Change for Echo Port
$maxdistance = 35 # Change for maximum distance from object before avoiding in units
$onlyforward = 0 # Only if moving forwards? 0 = no, 1 = yes
$reverseturn = 0 # Reverse before turn? 0 = no, 1 = yes
# centreturndirection removed
$turnamount = 500 # Change for how long to turn for in ms
$reverseamount = 500 # Change for how long to reverse for in ms (if applicable)
$movementspeed = 255 # Change for movement speed

# Sweep variables
$sweepmin = 25 # Change for min limit
$sweepmax = 77 # Change for max limit
$sweepcenter = 52 # Change for center position
$sweepservo = "D3" # Change for servo port
$sweepprevious = "none" # Do not change

# -- The Script --

# Check if only to detect when moving forwards
:detect
IF ($onlyforward = 1)
  IF ($Direction = "Forward")
    GOTO (detectstart)
  ELSE 
    GOTO (detect)
  ENDIF 
ELSE 
  :detectstart
  $currentdistance = GetPing($pingport, $echoport)
  IF ($currentdistance <= $maxdistance)
    GOTO(avoid)
  ENDIF 

# Sweep the servo to the next position
  GOTO(sweep)

  SLEEP (50)
  GOTO(detect)
ENDIF 

# The avoidance script
:avoid
IF ($reverseturn = 1)
  reverse($movementspeed,$reverseamount)
ENDIF 
IF($currentposition = $sweepmin)
  RIGHT($movementspeed,$turnamount)
ELSEIF($currentposition = $sweepmax)
  LEFT($movementspeed,$turnamount)
ELSE
  Servo($sweepservo,$sweepmin)
  $pingmin = GetPing($pingport, $echoport)
  Servo($sweepservo,$sweepmax)
  $pingmax = GetPing($pingport, $echoport)
  Servo($sweepservo,$sweepcenter)
  IF($pingmin > $pingmax)
    RIGHT($movementspeed,$turnamount)
  ELSE
    LEFT($movementspeed,$turnamount)
  ENDIF
ENDIF
RETURN()

# The sweep script

# Check for previous position, if no position assume to be $sweepmax
IF($sweepprevious = "none"
  $sweepprevious = $sweepmax
ENDIF

# Get the current position
$sweepcurrent = GetServo($sweepservo)

# Move in the correct direction and store previous position
IF($sweepcurrent = $sweepmin)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepcenter)
ELSEIF($sweepcurrent = $sweepcenter and $sweepprevious = $sweepmin)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepmax)
ELSEIF($sweepcurrent = $sweepcenter and $sweepprevious = $sweepmax)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepmin)
ELSE
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepcenter)
ENDIF

# Return back to the main script
Return()

As mentioned, again this us unchecked so may have some bugs and errors in it. Please feel free to check it for me, to use it, to alter it, to follow it and attempt to write it yourself. It is offered as an aid to help you learn.

I will revisit this again when I have more time to play and will test it when I have an EZB and battery which I can set up to test this.

Spain
#16  

The truth is that I'm impressed with your ability to this written code, and I like the idea of checking distances left and right when it detects an obstacle in front, I wanted to address this concept later but you've advance (things of genius). I copied and pasted your last code, and tested on ARC, the first error message told me that it was the "GOTO (sweep)", so I added "sweep" in this part assuming missing write here :

........................................................................................................

The sweep script

: sweep

Check for previous position, if position not assume to be $ sweepmax

IF ($ sweepprevious = "none") $ sweepprevious = $ sweepmax ENDIF

Get the current position

$ sweepcurrent = GetServo ($ sweepservo) ......................................................................................................... But then I have received this error when checking code in the console:

User-inserted image

This looks like a great team, you can write code and I practiced so I test.:)