PID Control Tuning for Autonomous Aiming and Firing
5962 8 2019-9-23
Uploading and Loding Picture ...(0/1)
o(^-^)o
rhoude57 - YUL
lvl.4
Offline

Hi all,

This, perhaps, may be a rather interesting challenge. I have copied the link to the code Mark has published for the S1 Autonomous

https://github.com/markind69/Vis ... iming_and_Firing.py

I'm sure everyone has noticed that the Aiming algorithm, driven by a PID controller, is rather slow and probably would not be very performant in a match situation where both the robot aiming and robot being fired upon move around alot.

The challenge, therefore, is to change the tuning parameters of the program above to make it as performant as possible. This means that the challenge includes defining what is "performant" i.e. by what criteria will you judge aiming andfiring performance?
So... In 3... 2.. 1. Tune!

And don't be afraid to share your thoughts in the comments below...



2019-9-23
Use props
BGA
Second Officer
Offline

I do not think that is the case. It is most likelly just a matter of doing something like:

gimbal_ctrl.set_rotate_speed(360)

The default value for the rotation speed is 30. It can go to as high as 540.

I am not at home now, so I( can not test. Also, although the performance would not change by much, there are several redundant things happening on that program that can be eliminated to at least be more compact (several things coming from the fact that it is a Scratch program converted to python).
2019-9-23
Use props
BGA
Second Officer
Offline

BGA Posted at 9-23 11:28
I do not think that is the case. It is most likelly just a matter of doing something like:

gimbal_ctrl.set_rotate_speed(360)

Hmmmm... The code uses rotate_with_speed(). The documentation is not great but it seems the parameters are actually degrees per second so I see at least 3 obvious possibilities:

1 - The obvious one, multiply the speed by a constant factor, clamping to [-360, 360]. A good way to see if this would actually work is to print the values returned by get_output() on the PID controllers to check what they are actually returning.
2 - Increase Kp and Kd. This should have an effect similar to the one above (Depending on how much you change it, you might need to clamp it too.
3 - Instead of rotate_with_speed(), use angle_ctrl() to translate to absolute positions. It might not work well if the target S1 is moving outside of the view (and i think this is why the original code uses rotate_with_speed()).
2019-9-23
Use props
DJI Stephen
DJI team
Offline

Hello and good day rhoude57 - YUL. Thank you for sharing these information and I hope that our valued DJI members who owns the DJI Robomaster S1 would be able to share there ideas with regards to this matter. Thank you.
2019-9-23
Use props
rhoude57 - YUL
lvl.4
Offline

BGA Posted at 9-23 11:28
I do not think that is the case. It is most likelly just a matter of doing something like:

gimbal_ctrl.set_rotate_speed(360)

That's how the script starts off, but once it has found a target, it switches to a PID Controller to track the target.
The PID Controller parameters are set as:
    pid_Yaw.set_ctrl_params(115,0,5)
    pid_Pitch.set_ctrl_params(85,0,3)

By playing with only the P parameter, I was able to accelerate the tracking rate asI was moving around, but you get to a point as you increase the value where you start overshooting the target.

The name of the game now, is to find the optimal values for both Pitch and Yaw tracking.

Also, the S1 has a shooter calibration function that applies a correction so that the shooter aims at the right Pitch and Yaw to hit the pressure pads. I wish we could access those calibration paramaters from Scratch or Python.
2019-9-23
Use props
JB63
lvl.4
  • >>>
Offline

Not to over-complicate this but, in manual shooting (fixed target), I've noticed that the gel beads always hit BELOW the target i.e., the effects of gravity is not accounted for. Such effect can be easily accounted for if one knows the distance between the S1 and target. Hence the question: is there a way to 'measure' such distance ?

This is possibly what YUL refers to as Pitch Correction.

One way to minimize such pitch offset is to increase the speed by which the beads are ejected, but not sure that's possible/allowed due to safety reasons.

2019-9-24
Use props
MarkusXL
lvl.4
Offline

I've noticed that the gel beads that come in low, bounce off the floor and up into hit detectors and score.  The "spread" of the gel beads is pretty big, so accuracy is not a big thing.  Aim for the middle, lay down lots of fire.  Spray and pray.  As for the IR Blaster - it is a deadly, wide, long range, easily reflected DEATH BOLT.  Just point in the general direction you really can't miss, especially on a white or relflective floor.

Yes the existing program is clunky.  I worked on a more lethal version last night... will continue tonight...  muhuhaaaaa

There are some tips in tuning the PID parameters in the Road to Mastery - near the end of the final chapter.

Edit:  Yes in Robomaster competitions the Rate of Fire and Projectile Velocity are limited by Rule for Safety reasons.


If we ever get around to Official battles with prizes at stake, only purely stock S1's would be allowed.  


Unless maybe there evolves an Unlimited Division...  Super hacked and modified S1's go at it with no holds barred?  


Also note - I am staying with Scratch for this project.  As long as I don't need to import math or pass arguments to functions, it is sufficient.
2019-9-24
Use props
rhoude57 - YUL
lvl.4
Offline

MarkusXL Posted at 9-24 06:11
I've noticed that the gel beads that come in low, bounce off the floor and up into hit detectors and score.  The "spread" of the gel beads is pretty big, so accuracy is not a big thing.  Aim for the middle, lay down lots of fire.  Spray and pray.  As for the IR Blaster - it is a deadly, wide, long range, easily reflected DEATH BOLT.  Just point in the general direction you really can't miss, especially on a white or relflective floor.

Yes the existing program is clunky.  I worked on a more lethal version last night... will continue tonight...  muhuhaaaaa

As RoboMaster S1 owners and drivers gain experience and ability, the "Spray and Pray" tactic will become less and less effective and techniques will be needed to put as many gel beads on the hit detectors as possible. You can see that happen in the RoboMaster league itself. Whereas rookie teams rely a lot on "Spray and Pray", the more senior and competent teams hone their robots and software so that every single round spent scores.

You bring up a point that will be worth validating, that is the computation of the virtual "shooter heating" algorithm. The shooter functions make it possible to specify how many gel beads are to be fired when the shoot command is issued. We need to validate that the number of beads fired actually matches the setting. If the count is accurate, it becomes possible to implement a Shooter Heating and Cooldown algorithm.

And finally, yes, as time moves on and skill levels in terms of hardware "customizing/boosting" and programming progress, it will become necessary to distinguish classes of competition so as not to discourage newcomers from joining competitive events.
2019-9-24
Use props
BGA
Second Officer
Offline

rhoude57 - YUL Posted at 9-23 20:22
That's how the script starts off, but once it has found a target, it switches to a PID Controller to track the target.
The PID Controller parameters are set as:
    pid_Yaw.set_ctrl_params(115,0,5)

I think I solved the overshooting issue. I also improved the program while at it (see below).

The bad news is that while experimenting I noticed that the S1 does not seem to track the other robot when it (the robot tracking, not the one being tracked) is moving. It might be a limitation of how the S1 recognition works (i.e. it is unable to "see" the other robot) or it might be that for some reason moving block it.

I will try the same script but using callbacks to see if the situation improves.

def start():
    # Enable manual control of chassis and gimbal.
    chassis_ctrl.enable_stick_overlay()
    gimbal_ctrl.enable_stick_overlay()
   
    # Enable detection of S1 robots.
    vision_ctrl.enable_detection(rm_define.vision_detection_car)

    # Fire one bead per trigger. This does not
    # affect IR firing.
    gun_ctrl.set_fire_count(1)
   
    # Create PID controllers for pitch and yaw.
    pidPitch = rm_ctrl.PIDCtrl()
    pidYaw = rm_ctrl.PIDCtrl()

    # Set contoller parameters.
    pidPitch.set_ctrl_params(90,0,3)
    pidYaw.set_ctrl_params(120,0,5)
   
    # Smaller or equal error values mean we are
    # aiming straight at robot.
    errThreshold = 0.1
   
    while True:
        # Get list of detected S1 robots.
        robotList=RmList(vision_ctrl.get_car_detection_info())
        if robotList[1] > 0:
            # We found at least one robot.
            
            # Set travel mode to free mode so we can
            # automatically rotate the gimbal.
            robot_ctrl.set_mode(rm_define.robot_mode_free)
            
            # Get coordinates to the center of the first
            # detected S1 robot. This will be our target.
            X = robotList[2]
            Y = robotList[3]
            
            # Compute errors in the X and Y axes.
            errX = X - 0.5
            errY = 0.5 - Y
            
            if abs(errX) <= errThreshold and abs(errY) <= errThreshold:
                # We are centered in our target.
               
                # Stop rotating so we do not move past it.
                gimbal_ctrl.rotate_with_speed(0,0)
               
                # Fire!
                gun_ctrl.fire_once()
               
                # Sleep after firing when not tracking an
                # S1 robot.
                time.sleep(0.5)
               
            else:
                # Set errors into our PID controllers.
                pidYaw.set_error(errX)
                pidPitch.set_error(errY)
               
                # Rotate gimbal to the center of the S1
                # Robot based on the PID controllers.
                gimbal_ctrl.rotate_with_speed(pidYaw.get_output(), pidPitch.get_output())
               
        else:
            # No robot in sight. Stop rotating.
            gimbal_ctrl.rotate_with_speed(0,0)
            robot_ctrl.set_mode(rm_define.robot_mode_chassis_follow)

            # Sleep when not tracking an S1 robot.
            time.sleep(0.1)
2019-9-24
Use props
Advanced
You need to log in before you can reply Login | Register now

Credit Rules