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

ARC Pro is your passport to a world of endless possibilities in robot programming, waiting for you to explore.

Spain
#25  

I've inserted the 250-ms sleeps under each line and it worked fine, now the servo moves sweep across his rrecorrido and does it well. The trouble is that when it detects a ojeto turns and stops, and only corrected to the left, then sweep the servo stops moving, and forward and goto function from an external script (which we discussed earlier) enters a loop and voids the rest of your code. The good thing is that every time we are closer, sure with the ez-b in their hands will see everything more clearly, seeing what he did without being able to experience it physically:)

Spain
#26  

Incidentally this is your code with my servo ports assigned and added the "sleep (250)":RADAR.EZB

United Kingdom
#27  

I will put together a test rig and check it out. I may even add the ping sensor and servo to my hearoid (since I need to anyway) if I get time tonight. If not I'll work on it over the weekend with a test rig.

United Kingdom
#28  

Right, just having a good ol' look at this now for the next 20 minutes or so (10 now). I've set it up with the floor map so I can see a virtual robot moving. I've slightly edited the code so the ping is a random number to save me needing to connect an EZB up.

It works fine, and then it stops. Currently I have only a rough idea of where it goes wrong but why it goes wrong I need to find. Basically you'll probably find that it moves around OK and then it will suddenly stop sweeping the servo.

So that's where I'm going to start looking.

Also, the updated code with the sleep fixed (it was in there but only 50ms so hardly counted) and forward commands added in. More of a roaming script than a detection script now:)

And I found the problem is in the code for detection direct ahead, it throws off the sweep code. I'll delve in to that better later on but have to be out in 10 minutes so it'll wait.

Here is the code all changed, it has some extra "testing" variables and options in it, I'll leave them there so you can see how I went about finding the problem. I'll explain it all later when I have time.


# 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 = 75 # Change for maximum distance from object before avoiding in units
$onlyforward = 1 # Only if moving forwards? 0 = no, 1 = yes
$reverseturn = 0 # Reverse before turn? 0 = no, 1 = yes
$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 = $sweepmax # Do not change
$sweepcurrent = $sweepcenter # Do not change

# Testing Options
$testmode = 1 # Change to 1 if testing without PING sensor
$SweepErrorFlag = 0 # Do not change

# -- The Script --
Servo($sweepservo, $sweepcenter)
FORWARD()
GOTO(sweep)

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

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

  SLEEP (750)
  GOTO(detect)
ENDIF 

# The avoidance script
:avoid
IF ($reverseturn = 1)
  Reverse($movementspeed,$reverseamount)
ENDIF 
IF($sweepcurrent = $sweepmin)
  RIGHT($movementspeed,$turnamount)
  FORWARD()
ELSE
  LEFT($movementspeed,$turnamount)
  FORWARD()
ENDIF
RETURN()

# The sweep script
:sweep
# 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)
ELSEIF($sweepcurrent = $sweepmax)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepcenter)
ELSE
  $SweepErrorFlag = 1
SLEEP(10000)
ENDIF

# Return back to the main script
Return()

Also, see the attached ezb file (merge it to import the script in to your current project)pingroam.EZB

NOTE: Testing mode is set to on. Change the variable at the start for testing to 0 if you want to test with an actual PING sensor

United Kingdom
#29  

A quick video of it working away...

It doesn't check left and right after detection in the centre position yet as I think that's where another bug lies and I want to sort that part with an actual sensor fitted to a moving robot. My new EZB should be turning up tomorrow (should have been today, why was I out?!) so I can do that tomorrow evening:)

Although feel free to attempt it yourself, hopefully you are gaining some knowledge in scripting through this topic.

Spain
#30  

The truth is that I'm learning about scripts with this topic, I realize that the best way is to type it and practice. Also I have also learned a lot by practicing on the mobile platform in a practical, write and test. I have seen reactions "ghostly" so to speak, of the robot reactions that had nothing to do with the program, and course corrections when the sensor did not detect anything, and stuff. And as changing a parameter, others are modified unintentionally is something mysterious, but certainly has a logic I do not understand yet. By the way, do not understand how you run the program without ultrasonic sensor readings. Include random numbers to simulate sensor readings?

United Kingdom
#31  

Yes, random numbers, so the actual floor map is a bit unrealistic but it runs though and tests the if statements, sometimes meeting the requirements to run the commands other times it doesn't.

Anyway, I got impatient...


# 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 = 75 # Change for maximum distance from object before avoiding in units
$onlyforward = 1 # Only if moving forwards? 0 = no, 1 = yes
$reverseturn = 0 # Reverse before turn? 0 = no, 1 = yes
$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 = $sweepmax # Do not change
$sweepcurrent = $sweepcenter # Do not change

# Testing Options
$testmode = 0 # Change to 1 if testing without PING sensor
$SweepErrorFlag = 0 # Do not change

# -- The Script --
Servo($sweepservo, $sweepcenter)
FORWARD()
GOTO(sweep)

# Check if only to detect when moving forwards
:detect
IF ($onlyforward = 1)
  IF ($Direction = "Forward")
    GOTO (detectstart)
  ELSE 
    GOTO (detect)
  ENDIF 
ELSE 
  :detectstart
  IF ($testmode=0)
    $currentdistance = GetPing($pingport, $echoport)
  ELSE 
    $currentdistance = GetRandom(0,255)
  ENDIF 
  IF ($currentdistance <= $maxdistance)
    GOTO(avoid)
  ENDIF 
    
    # Sweep the servo to the next position
  GOTO(sweep)
  
  SLEEP (750)
  GOTO(detect)
ENDIF 
  
  # The avoidance script
:avoid
IF ($reverseturn = 1)
  Reverse($movementspeed,$reverseamount)
ENDIF 
IF ($sweepcurrent = $sweepmin)
  RIGHT($movementspeed,$turnamount)
  FORWARD()
ELSEIF ($sweepcurrent = $sweepmax)
  LEFT($movementspeed,$turnamount)
  FORWARD()
ELSE 
  Goto(sweepcenter)
ENDIF 
RETURN()

# The sweep script
:sweep
# Move in the correct direction and store previous position
IF ($sweepcurrent = $sweepmin)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepcenter)
  $sweepcurrent = GetServo($sweepservo)
ELSEIF ($sweepcurrent = $sweepcenter and $sweepprevious = $sweepmin)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepmax)
  $sweepcurrent = GetServo($sweepservo)
ELSEIF ($sweepcurrent = $sweepcenter and $sweepprevious = $sweepmax)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepmin)
  $sweepcurrent = GetServo($sweepservo)
ELSEIF ($sweepcurrent = $sweepmax)
  $sweepprevious = $sweepcurrent
  Servo($sweepservo, $sweepcenter)
  $sweepcurrent = GetServo($sweepservo)
ELSE 
  $SweepErrorFlag = 1
  SLEEP(10000)
ENDIF 
  # Return back to the main script
Return()

:sweepcenter
$SweepCenterFlag = 1
Servo($sweepservo,$sweepmin)
IF ($testmode=0)
  $pingmin = GetPing($pingport, $echoport)
ELSE 
  $pingmin = GetRandom(0,255)
ENDIF 
Sleep(400)
Servo($sweepservo,$sweepmax)
IF ($testmode=0)
  $pingmax = GetPing($pingport, $echoport)
ELSE 
  $pingmax = GetRandom(0,255)
ENDIF 
Sleep(400)
Servo($sweepservo,$sweepcenter)
IF ($pingmin > $pingmax)
  RIGHT($movementspeed,$turnamount)
  FORWARD()
ELSE 
  LEFT($movementspeed,$turnamount)
  FORWARD()
ENDIF 
Return()

I had to move a few things around, mainly concerning the previous and current position variables. The way I had them didn't work correctly (although I haven't figured out why, as far as I can see they should have but I am probably missing something obvious). Then I needed to add in the forward commands missed out of the sweepcenter sub routine and also add in the testing code for using a random number rather than the GetPing in the sweepcenter sub routine.

But it all seems to be working well now... I left it running the test while I went for a shower and it was still working when I got out:)

pingroam.EZB

Some of the code could be tidied up a little and the sweepcenter routine could be moved in to the IF statement rather than using a goto since it is the only place it's called from.

We got there in the end though. Although totally untested with a ping sensor so the direction may be backwards or it may trigger when far away from an object rather than close to one - I'm unsure which way around the ping sensor reports the value. Easy fix if it is wrong though, it's just a case of changing a couple of ifs.

I have a video of it running too but the screen recorder decided it doesn't like encoding or compressing so it is 9.3Gb for only a few minutes... So I wont be posting that tonight (although it is uploading to youtube as I type this so maybe I will).

Edit: Video

United Kingdom
#32  

Since I have a few minutes to spare at the moment some quick notes on how I went about testing the script without connecting to an EZB or any sensors.

To emulate the sweep servo was pretty simple. Adding a control for a horizontal servo and setting it to the sweep servo port number will visually display the servo position within the control. This allowed me to be able to see that it was sweeping correctly.

Adding a movement control panel allowed visual indication of the direction in which the robot was moving.

Adding the floor map was just another indication of the robot moving however it was not required.

Replacing the GetPing for GetRandom supplied random numbers for the sensor data allowing random checking of the conditions in the IF statements.

The Variable Watcher control is also a very important tool. It allows to keep an eye on the variables so I could see what was changing. Also with the error flag variables it would indicate when the script had failed to perform the if conditions correctly. Adding a long sleep command after the flag change also helped indicate when the problem occurred.

And finally, in the script dialogue pressing the run button will show the debug information to the right which can be read through to check it is functioning correctly, where it runs astray or where there are problems.

However, that said, nothing beats checking scripts on an EZB with an actual robot.

To fix the script from the initial buggy code was a case of breaking it down section by section and finding where the script was going wrong, checking the code and adjusting it to suit.

As this shows I am still learning and often have bugs in code. Don't be disheartened if you have buggy code to begin with, we all do:) Trial and error will prevail.