Speed Ramping

Rich

United Kingdom

Speed ramping is something that comes up often and while it's not (yet) a built in function in ARC's movement panels it's not too difficult to achieve.

Before anything you will need an init script to set the variables so as not to cause errors in the ramping script. These can't be set in the ramping script as it would stop it working correctly.

Two variables need defining, $motor1speed and $motor2speed.


# Define variables
$motor1speed = 1
$motor2speed = 1

These can be set to anything as other scripts will change them before ramping begins.

Then you need the ramping script which will gradually increase the speed of the motors, uncomment the required control method where indicated within the script. H-Bridges work a little differently and therefore another script will be posted to cover the H-Bridge version.

The ramping script would be as follows, I have commented it to explain each part where necessary.


# Script commands for gradual ramping to desired speeds.

# Author: Rich
# Version: 2015.01.08.00

# Desired speeds set elsewhere. This script is called with ControlCommands.
# Note: An init script must have previously run to set the variables.

$rampdelay = 50 # Adjust to suit speed increase

# Do not modify beyond this point unless you know what you are doing
# Any changes may cause the script to run incorrectly.

# Check the direction of ramping up or down and set the steps to suit
IF ($motor1speed > $motor1speed_end)
  # If true motor speed needs to increase therefore +1
  $motor1steps = 1
ELSE 
  # Otherwise it needs to decrease therefore -1
  $motor1steps = -1
ENDIF 
  
IF ($motor2speed > $motor2speed_end)
  # If true motor speed needs to increase therefore +1
  $motor2steps = 1
ELSE 
  # Otherwise it needs to decrease therefore -1
  $motor2steps = -1
ENDIF 
  
REPEATUNTIL($motor1speed = $motor1speed_end AND $motor2speed = $motor2speed_end)
# This section will now loop from the above REPEATUNTL down to ENDREPEATUNTIL until the above statement is true (until motor speeds match those required).

# Movement commands - uncomment required control method.

  # Serial Control Method (Sabertooth etc)
  # SendSerial(D7,38400,$motor1speed)
  # SendSerial(D7,38400,$motor2speed)

  # Modified servo Method
  # Servo(D7, $motor1speed)
  # Servo(D8, $motor2speed)

  IF ($motor1speed = $motor1speed_end)
    # Avoid increasing speed when not needed - in the case of uneven steps between motors. Also state motor up to speed for info.
    Print("Motor1 Up To Speed")
  ELSE 
    # Otherwise increase or decrease the motor speed
    $motor1speed = $motor1speed + $motor1steps
  ENDIF 
    # Increase motor 2's speed if required
  IF ($motor2speed = $motor2speed_end)
    # Avoid increasing speed when not needed - in the case of uneven steps between motors. Also state motor up to speed for info.
    Print("Motor2 Up To Speed")
  ELSE 
    # Otherwise increase or decrease the motor speed
    $motor2speed = $motor2speed + $motor2steps
  ENDIF 
    
  # Add a slight delay as required (increase/decrease the delay in the variable at the top of the script)
  SLEEP($rampdelay)
ENDREPEATUNTIL

Now we are in business to start ramping...

You need the Custom Movement Panel for this and each direction requires a very similar script.

For forward movement the script needs to be something like this (again commented for guidance);


# Set the required end speed for motor 1
$motor1speed_end = 1

# Set the required end speed for motor 2
$motor2speed_end = 180

# Start the ramping script going
ControlCommand("Movement Controls", ScriptStart, "Ramp Speed")

For reverse


# Set the required end speed for motor 1
$motor1speed_end = 180

# Set the required end speed for motor 2
$motor2speed_end = 1

# Start the ramping script going
ControlCommand("Movement Controls", ScriptStart, "Ramp Speed")

Turn Right


# Set the required end speed for motor 1
$motor1speed_end = 180

# Set the required end speed for motor 2
$motor2speed_end = 180

# Start the ramping script going
ControlCommand("Movement Controls", ScriptStart, "Ramp Speed")

Turn Left


# Set the required end speed for motor 1
$motor1speed_end = 1

# Set the required end speed for motor 2
$motor2speed_end = 1

# Start the ramping script going
ControlCommand("Movement Controls", ScriptStart, "Ramp Speed")

Stop


# Set the required end speed for motor 1
$motor1speed_end = 90

# Set the required end speed for motor 2
$motor2speed_end = 90

# Start the ramping script going
ControlCommand("Movement Controls", ScriptStart, "Ramp Speed")

Note: You will more than likely need to change the values in the above depending on your servos or serial device.

And that's pretty much it for Modified Servos or Serial. PWM/H-Bridge is different and that will be in post 2 when I get the chance.

I will update as and when time permits and also post an Example Project when I get chance to make it. Enjoy:)

By — Last update
Jump to end

ARC Pro

Upgrade to ARC Pro

Become a Synthiam ARC Pro subscriber to unleash the power of easy and powerful robot programming

United Kingdom
#1  

NOTE: H-BRIDGE/PWM METHOD STILL UNDER DEVELOPMENT

If using a H-Bridge the method will need to be somewhat different as the PWM is simply 0% to 100% as opposed to the above method where lower numbers reverse the direction.

Note: There may be a better method than this and if I think of it I will update

We still need the same init script to set the variables.


# Define variables
$motor1speed = 1
$motor2speed = 1

We also need a very similar ramping script to the above to but with a slight change;


# Script commands for gradual ramping to desired speeds.

# Author: Rich
# Version: 2015.01.08.00

# Desired speeds set elsewhere. This script is called with ControlCommands.
# Note: An init script must have previously run to set the variables.

$rampdelay = 50 # Adjust to suit speed increase

# Do not modify beyond this point unless you know what you are doing
# Any changes may cause the script to run incorrectly.

# Check the direction of ramping up or down and set the steps to suit
IF ($motor1speed > $motor1speed_end)
  # If true motor speed needs to increase therefore +1
  $motor1steps = 1
ELSE 
  # Otherwise it needs to decrease therefore -1
  $motor1steps = -1
ENDIF 
  
IF ($motor2speed > $motor2speed_end)
  # If true motor speed needs to increase therefore +1
  $motor2steps = 1
ELSE 
  # Otherwise it needs to decrease therefore -1
  $motor2steps = -1
ENDIF 
  
REPEATUNTIL($motor1speed = $motor1speed_end AND $motor2speed = $motor2speed_end)
# This section will now loop from the above REPEATUNTL down to ENDREPEATUNTIL until the above statement is true (until motor speeds match those required).

# Movement commands
  PWM(D7, $motor1speed)
  PWM(D8, $motor2speed)

  IF ($motor1speed = $motor1speed_end)
    # Avoid increasing speed when not needed - in the case of uneven steps between motors. Also state motor up to speed for info.
    Print("Motor1 Up To Speed")
  ELSE 
    # Otherwise increase or decrease the motor speed
    $motor1speed = $motor1speed + $motor1steps
  ENDIF 
    # Increase motor 2's speed if required
  IF ($motor2speed = $motor2speed_end)
    # Avoid increasing speed when not needed - in the case of uneven steps between motors. Also state motor up to speed for info.
    Print("Motor2 Up To Speed")
  ELSE 
    # Otherwise increase or decrease the motor speed
    $motor2speed = $motor2speed + $motor2steps
  ENDIF 
    
  # Add a slight delay as required (increase/decrease the delay in the variable at the top of the script)
  SLEEP($rampdelay)
ENDREPEATUNTIL

Since we need the PWM to ramp as appropriate we either need a script which is constantly running and monitoring the direction or we need to use a custom movement panel. The custom Movement Panel will work in a similar way to the above serial/servo method so for simplicity I'll use this method.

Based on the L298n H-Bridge since this is the more common H-Bridge we need to set the required ports high or low to tell the H-Bridge what to do then ramp the PWM. So, similar to the serial method we need the five movement scripts.

It is assumed In1 to In4 are on D0 to D3 respectively.

Forward


# Set the required end speed for motor 1
$motor1speed_end = 100

# Set the required end speed for motor 2
$motor2speed_end = 100

# Set the high/low for In1 to In4 of the H-Bridge
Set(D0, On)
Set(D1, Off)
Set(D2, On)
Set(D3, Off)

# Start the ramping script going
ControlCommand("Movement Controls", ScriptStart, "Ramp Speed")

Reverse


# Set the required end speed for motor 1
$motor1speed_end = 100

# Set the required end speed for motor 2
$motor2speed_end = 100

# Set the high/low for In1 to In4 of the H-Bridge
Set(D0, Off)
Set(D1, On)
Set(D2, Off)
Set(D3, On)

# Start the ramping script going
ControlCommand("Movement Controls", ScriptStart, "Ramp Speed")

Turn Right


# Set the required end speed for motor 1
$motor1speed_end = 100

# Set the required end speed for motor 2
$motor2speed_end = 100

# Set the high/low for In1 to In4 of the H-Bridge
Set(D0, On)
Set(D1, Off)
Set(D2, Off)
Set(D3, On)

# Start the ramping script going
ControlCommand("Movement Controls", ScriptStart, "Ramp Speed")

Turn Left


# Set the required end speed for motor 1
$motor1speed_end = 100

# Set the required end speed for motor 2
$motor2speed_end = 100

# Set the high/low for In1 to In4 of the H-Bridge
Set(D0, Off)
Set(D1, On)
Set(D2, On)
Set(D3, Off)

# Start the ramping script going
ControlCommand("Movement Controls", ScriptStart, "Ramp Speed")

Stop


# Set the required end speed for motor 1
$motor1speed_end = 0

# Set the required end speed for motor 2
$motor2speed_end = 0

# Keep digital pins for In1 to In4 as they were to ramp down from last movement

# Start the ramping script going
ControlCommand("Movement Controls", ScriptStartWait, "Ramp Speed")

# When ramping down is completed then release all In1 to In4 to low for freewheel

Set(D0, Off)
Set(D1, Off)
Set(D2, Off)
Set(D3, Off)

That should pretty much do it.

Note: This method is currently untested however in theory should work

#2  

Thanks Rich, I'm going to file that for future use.

#4  

Thanks @Rich.

This has been on my do-do list for a while, both for H-Bridge and Continuous Rotation Servos and I just haven't found the time. Glad you were on the case:)

Alan

United Kingdom
#6  

Not a problem. It's one which had me baffled for a while until I stopped over thinking it and since writing it for Gwen it's come in handy a few times so it deserves it's own topic. I know Dave wants similar for a single motor too so I'll cover that eventually too.

#7  

I know this may sound a little novice because i am one. I understand the ini script setting the $motorspeed1 and 2. I am putting this script in my ini script file. I am not sure though where the next code needs to be written.

I am using parallax HB-25 motor controllers. They act like standard modified servos so I am using the first set of code. I just do not know where it should go.

I am slowly learning the EZ-B script but i am having troubles with where to write the scripts. Any help would be greatly appreciated.

Ellis

#8  

Nice done Rich! Thanks for your time and talents doing this! Very timely. This helps a lot.