Autohotkey to Mini Maestro 6 for simulatenous servo control

Hi everyone, this is my first post although I have been using this forum as a resource for a little while now. I only have experience with small projects using the Mini Maestro 6 and the scripts are usually very simple. As usual I have used bits and pieces from different post on this forum to create my script, and that usually works, but this time I am having trouble proofing it because of my lack of scripting/programming skills. I could really use a little help if anyone wants to give it a shot :smiley:

Here is the basic layou of my project. I have constructed a simple robot that uses two Invacare wheelchair motors driven by Talon SR speed controllers that receive servo signals from the Mini Maestro 6 which is connected to a small netbook running Autohotkey which is in turn receiving keystrokes from another laptop over VNC on my home wifi network. - Whew! That was a mouthful :laughing: I have successfully tested the robot using a simple RC transmitter and receiver to control the Talons instead of the Maestro and everything worked fine. I want to control the robot over wifi and eventually through a mobile hotspot using VPN to connect the two laptops, but first I need to get this script working correctly. I keep getting “USCCmd has stopped working” whether I am controlling the robot directly from the onboard netbook or the remote laptop, and if I had to guess I have an obvious script error. I only have Autohotkey running and the Maestro control center is not running, but I still get the error. It happens almost randomly, but especially when I make quick changes in direction. What I would like to achieve is simple forward, reverse, left spin, right spin using the WASD keys. So in my script you will see an attempt to make both motors drive forward when the “W” key is depressed and held, “S” as reverse, and “A” and “D” as left spin right spin, which will require one motor to go forward and the other to reverse.

Here is my novice script:

[code];Servo control script1
;Use this script to control servos via the keyboard using a Micro Maestro

#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.

w:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,5400,,Hide Run usccmd --servo 0,5400,Hide

}
return

w Up:: ;key released
{
key_down := false
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,6000,,Hide Run usccmd --servo 0,6000,Hide

}
return

s:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,6600,,Hide Run usccmd --servo 0,6600,Hide

}
return

s Up:: ;key released
{
key_down := false
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,6000,,Hide Run usccmd --servo 0,6000,Hide

}
return

d:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,6600,,Hide Run usccmd --servo 0,5400,Hide

}
return

d Up:: ;key released
{
key_down := false
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,6000,,Hide Run usccmd --servo 0,6000,Hide

}
return

a:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,5400,,Hide Run usccmd --servo 0,6600,Hide

}
return

a Up:: ;key released
{
key_down := false
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,6000,,Hide Run usccmd --servo 0,6000,Hide

}
return

q:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,6000,,Hide Run usccmd --servo 0,5400,Hide

}
return

q Up:: ;key released
{
key_down := false
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,6000,,Hide Run usccmd --servo 0,6000,Hide

}
return

e:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,5400,,Hide Run usccmd --servo 0,6000,Hide

}
return

e Up:: ;key released
{
key_down := false
RunWait usccmd --accel 0,0,,Hide RunWait usccmd --speed 0,0,Hide
Run usccmd --servo 1,6000,,Hide Run usccmd --servo 0,6000,Hide

}
return[/code]

Here are a couple of images of the Robot in one of its configurations:




Hello.

It sounds like you are most likely getting this problem because your commands are sent too quickly. Only one instance of the command-line utility can be running at a time; if you try to run two commands in a row without using AutoHotkey’s RunWait, the command-line utility will not work.

Even if you change all of your Run commands to RunWait, I suspect AutoHotkey might still try to run two different scripts in parallel if you press two different buttons at nearly the same time.

-Brandon

Thank you very much for your help Brandon :slight_smile: I tried a few other things, but ultimately I am coming to the conclusion that this is probably not the best method for controlling this robot. It would seem that synced motor operation and reliable a start and stop is not as easy to script as I originally anticipated.

Thanks again for your help.

After a little more effort, I was able to achieve some satisfactory simultaneous controls using autohotkey to run maestro sequences :smiley:
I was able to operate the robot successfully from 10 miles away using vnc through vpn and a wifi hotspot! Currently I am using the netbook’s webcam to see ahead of the robot although it is a bit laggy. The autohotkey script is setup to use Ctrl+W,A,S,D for basic forward, reverse, left spin, right spin, but I also added Ctrl+Q,E for pivot left and right. I have a few questions, if anyone has time to help:

I cannot yet figure out how to run two sequences at once for combined forward and turn, I have added sequences that are issued through Ctrl+1,3 for combined forward and left or forward and right, but it is not really that helpful. Basically I have to go forward, then stop, then turn, the proceed forward again. I cannot turn momentarily while traveling forward :frowning: How would I script the ability to run one sequence such as forward, but then allow for left or right to be added while still running the forward sequence?

Release of any key runs the “stop” sequence from AutoHotkey, but I am still looking for a better failsafe stop command that could be written directly into the maestro script so that when I have the occasional USCcmd error, I don’t have an out of control robot that is still running the last sent command. I have had to chase it down the street a couple of times so far, and there have been a few interesting death spins :laughing: Could this be accomplished using an if/else statement that listens for all repeated commands and runs the “stop” sequence when no commands are being received?

I am also struggling to hide the single cmd window that flashes on the screen on the use of each Hotkey. I would be fine with the cmd window being up all the time or off all the time, but the momentary flashing is driving me mad. I have tried using the “hide” or “show” at the beginning of my scripts, but to be honest I am not sure which program(AutoHotkey or MCC) is flashing the window. I think it is AutoHokey, but it disappears too fast for me to figure out which one it is. How would the show or hide window need to be used in either script to make the cmd window always open or always closed?

This has been a fun project so far, even with all my scripting frustrations.
Here is the maestro script:

### Sequence subroutines: ###

# Sequence 0
sub Sequence_0
begin
 500 4000 4000 5 5 0 0 frame_0..5 # stop
repeat
  return
# Sequence 1
sub Sequence_1
begin
  800 6500 6500 5 5 0 0 frame_0..5 # forward
repeat
  return
# Sequence 2
sub Sequence_2
begin
  800 6400 6400 5 5 0 0 frame_0..5 # reverse
repeat
  return
# Sequence 3
sub Sequence_3
begin
  800 6000 5600 5 5 0 0 frame_0..5 # turnleft
repeat
  return
# Sequence 4
sub Sequence_4
begin
  800 5600 6000 5 5 0 0 frame_0..5 # turnright
repeat
  return
# Sequence 5
sub Sequence_5
begin
  800 6500 5600 5 5 0 0 frame_0..5 # spinleft
repeat
  return
# Sequence 6
sub Sequence_6
begin
  800 5600 6500 5 5 0 0 frame_0..5 # spinright
repeat
  return
# Sequence 7
sub Sequence_7
begin
  800 5800 5600 5 5 0 0 frame_0..5 # SlightLeft
repeat
  return
# Sequence 8
sub Sequence_8
begin
  800 5600 5800 5 5 0 0 frame_0..5 # SlightRight
repeat
  return

sub frame_0..5
  5 servo
  4 servo
  3 servo
  2 servo
  1 servo
  0 servo
  delay
  return

and the corresponding AutoHotkey Script:

[code];Servo control script1
;Use this script to control servos via the keyboard using a Micro Maestro

#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.

^w:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --sub 1

}
return

^w Up:: ;key released
{
key_down := false
RunWait usccmd --sub 0

}
return

^s:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --sub 2

}
return

^s Up:: ;key released
{
key_down := false
RunWait usccmd --sub 0

}
return

^a:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --sub 3

}
return

^a Up:: ;key released
{
key_down := false
RunWait usccmd --sub 0

}
return

^d:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --sub 4

}
return

^d Up:: ;key released
{
key_down := false
RunWait usccmd --sub 0

}
return

^q:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --sub 5

}
return

^q Up:: ;key released
{
key_down := false
RunWait usccmd --sub 0

}
return

^e:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --sub 6

}
return

^e Up:: ;key released
{
key_down := false
RunWait usccmd --sub 0

}
return

^1:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --sub 7

}
return

^1 Up:: ;key released
{
key_down := false
RunWait usccmd --sub 0

}
return

^3:: ;key pressed
if (!key_down) ;a toggle so that it doesn’t keep repeating
{
key_down := true
RunWait usccmd --sub 8

}
return

^3 Up:: ;key released
{
key_down := false
RunWait usccmd --sub 0

}
return[/code]
The scripts are pretty repetitive, but I am still a rookie :blush:

Thanks for sharing your code and progress; it sounds like your project is coming along nicely. To address your question about making the robot turn while going forward, I would suggest writing a separate subroutine in your Maestro script specifically for this case. Then, you could try modifying your AutoHotkey script to consider the states of multiple buttons when deciding which subroutine to activate. However, this would probably be a much more complicated program.

I think the easiest way to prevent your robot from running away uncontrollably would probably be to use the serial timeout setting in the “Serial Settings” tab of the Maestro Control Center. By default, all of the channels will turn off if the Maestro does not receive a command in the specified time. Unfortunately, the command for running a subroutine does not count, so you would have to add a second invocation of UscCmd that issues a normal “Set Target” command. For example, if channel 5 is not used, you could just do “UscCmd --servo 5,0” to reset the timer for serial timeout.

To stop the command window from flashing, you should try passing “Hide” as a parameter in the right spot to RunWait (in your AutoHotkey script). The “Using AutoHotkey with Pololu USB Products” application note has an example of this. Additional information on the “Hide” parameter can be found in the AutoHotkey documentation for the Run/RunWait command.

I am glad you have had a fun time with your project so far; hopefully you continue to enjoy it. I would definitely be interested in hearing more about it when it is completed. It would be fun to see a video of it in action.

-Brandon