Hello Andy and Aswin,
Thanks for your help. I simplified the fitness assessment to be simply the average of the absolute power values applied to the motors over 500 iterations of the PID loop and added a "nudge" by applying an additional fixed power value to the wheels every 50 iterations. I save the best PID values while it tests each permutation from the GA. The robot falls a lot at first but when I reset, it starts with the "best" PID gains from the previous cycle even if the whole cycle was not completed. I'm pleased to say that it seems to work and after about 6 incomplete cycles it can withstand all the nudges and continue to balance indefinitely, eventually the PID gains no longer change significantly.
The factor that has the biggest impact is the loop delay in the PID loop. The robot has to evolve for several cycles before it is stable enough to risk mutating this value so I've been doing it by hand, making it smaller and re-evolving the PID values. For each reduced loop delay the PID Gains are also smaller, but the robot eventually gets too frisky to use the gains from the previous cycle.
When I take the Genetic Algorithm Test & Save thread out, the PID Gain values are probably no longer optimum, but they are much more stable than I've been able to work out through trial and error.