In the basic magnetic guided AGV setup, the Roboteq controller will read the position of the magnetic tape from the MGS sensor and will  convert it to a steering command for the vehicle. The steering command will be proportional to the distance of the magnetic tape from the sensor’s middle position. The vehicle's speed command can be independent of the tape position and can be given directly by the user.  A microbasic script is used on the controller that reads the sensor data, calculates the steering and throttle command and applies them to the motor.


Sensor connection and configuration

To get the position of the magnetic tape, the sensor needs to be connected to the controller with multiPWM communication. The multiPWM communication uses the pulse output of the sensor, a common ground, and a pulse input of the controller, from where the sensor’s parameters can be read. The sensor datasheet should be consulted to find the GND and pulse pins.


On the Track senor utility, the pulse output should be configured as MultiPWM.

On the Roboteq controller configuration Utility (Roborun+) the pulse input that will be used should be configured as “MagSensor”


WarningIn controllers featured with STO, avoid using the pulse inputs that are shared with the STO inputs because the signal will be distorted due to the STO circuitry.

Now test the MultiPWM communication by sending the below serial command on a Roboteq controller’s command box:

The sensor should reply the tape’s position.


Roboteq Controller configurations

The controller must be set to one of the three mixed modes and must be configured and tuned in Closed Loop speed


The following of the magnetic tape will not be successful if the operating mode is Open Loop, because precise speed control is needed for that. The PID tuning must be performed that way that the vehicle is as responsive as possible with its nominal load. Finally, the acceleration/deceleration of the controller should be the highest possible (higher than 2000 RPM). This is because the differential driving function of the controller is using the acceleration/deceleration values for the steering of the vehicle. The higher the acceleration/deceleration values are, the more responsive the vehicle will be to the steering commands and the more sufficiently it will follow the tape.


Warning: Using high accelerations that the motor cannot achieve is not useful. Use the higher acceleration that the motor can follow and work on the PID tuning to optimize it.

So, to recap, the controller configuration steps are the following:

  1. Tune both channels in Closed Loop Speed
  2. Perform the tuning with the higher acceleration possible
  3. Set the controller to one of the three available mixed modes

The mixed mode corresponds to the way that the controller will allocate the motor command on both motors to achieve the desired steering. More information can be found at the Roboteq Controllers User manual.


Roboteq controller's Script

The main task of the script running on Roboteq controller is to read the position error from the sensor (tape distance from the sensor’s middle point) and give a steering command that is proportional to that error. The higher the position error is, the higher the steering command given to the motors will be, in order correct that error. This error is being multiplied by a value that the user can configure from the script. From what is mentioned it is clear that the script is performing a simple P control. 

In cases that the system is not responsive, and the P control is not sufficient, we have noticed that adding a Differential part in the formula sometimes helps. The user can give different values to the differential gain or disable it by setting it to 0. 

The parameters that play a role in the response of the vehicle and the user can finetune on the script are:


P_GAIN and D_GAIN are the proportional and differential gains accordingly. They should not be confused with the Closed Loop Speed PID gains, as these have to do only with the following of the tape.

TIME is the time interval of the script loop. The script can work with different intervals, from 1 to 100 ms. Of course, the bigger the time interval, the less accurate the control will be. The script will be checking the tape’s position only once every a time interval in the loop. For the differential part, the time interval plays a major role since it will define how big the difference between current and previous error will be.

Sensor readings that are below a value can be ignored by giving the DEADBAND parameter a value higher than zero. This can add in some cases stability to the system.

DEFAULT_THROTTLE is the speed command that will be used on the vehicle. Since the controller operates in mixed mode, the vehicle will reach this speed weather it is steering at the same time or not. 

All these parameters are defined in the start of the script. The following script performs a very basic AGV driving operation by giving a default throttle command when the magnetic tape is present. It can be used for the very first tuning of the AGV and it's only function is to make the AGV follow the tape.



' This script provide basic control for an AGV.

' Motor will turn on upon the presence of a track and stop when track disappears.

' The track position information is used to provide left/right steering.


option explicit


#define P_GAIN 1

#define D_GAIN 1

#define TIME 30 ' Loop period in ms

#define DEADBAND 3



' declare variables


dim TapeDetect as boolean

dim Throttle as integer

dim TapePosition as integer

dim Steering as integer

dim Error as integer

dim previousError as integer


' Main Loop




' read sensor data


TapeDetect getvalue(_MGD)

TapePosition getvalue(_MGT1)


' ignore values less than Deadband


if ((abs(TapePosition) < DEADBAND )) then

    TapePosition 0

end if


' Use TapeDetect to apply throttle or not


if (TapeDetect)



    Error TapePosition

    Steering = (P_GAIN * Error) + (D_GAIN * (Error previousError))

    previousError Error



    Throttle 0

    Error 0

    Steering 0

    previousError 0

end if






' Log output. Useful for troubleshooting. Comment out when done.

'print("\r", TapeDetect,"\t", Tape_Position,"\t", MarkerLeft,"\t", MarkerRight,"\t", Throttle,"\t", Steering,"\t",RunState,"\t",LineSelect)


wait(TIME' Loop period in ms


goto top ' Loop forever