Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | jarlowrey | |
Old Version | Published before Godot 3 was released. |
I want my bullets (RigidBody2D) to be able to track other nodes like a homing missile. Having lots of issues setting up this system. I read over the recommendations here and here and tried to go with a PID controller. Unfortunately it’s not working, and I’m not sure where to go next.
var Kp = 1000
var Ki = 1000
var Kd = 100
var prevError = 0
var P =0
var I =0
var D =0
func _get_PID_output(currentError, delta):
P = currentError;
I += P * delta;
D = (P - prevError) / delta;
prevError = currentError;
return P*Kp + I*Ki + D*Kd;
func _track_target(delta):
var angle_btw = get_global_pos().angle_to(target.get_global_pos())
var angle_diff = get_global_rot() - angle_btw
var torque = _get_PID_output(angle_diff,delta)
prevError = angle_diff
set_applied_torque(torque)
_set_vel_from_angle(get_global_rot())
get_node("Sprite 2").set_global_rot(angle_btw) #debugging, show desired angle
Blue is the rigid body bullet, red is “Sprite 2” that is supposed to be pointing the the angle_btw direction. It looks like the angle_to is not even the right direction!
Yay it works! That took forever, thanks @mollusca
var Kp = 1000.0
var Ki = 100.0
var Kd = 1000.0
var _prev_error = 0
var _P =0
var _I =0
var _D =0
func _get_PID_output(currentError, delta):
_P = currentError;
_I += _P * delta;
_D = (_P - _prev_error) / delta;
_prev_error = currentError;
return _P*Kp + _I*Ki + _D*Kd;
func _track_target(delta):
var angle_btw = get_global_pos().angle_to_point(target.get_global_pos()) + PI/2
var error = get_global_rot() - angle_btw
#deal with angle discontinuity
#https://stackoverflow.com/questions/10697844/how-to-deal-with-the-discontinuity-of-yaw-angle-at-180-degree
if(error > PI):
error = error - PI * 2
elif(error < -PI):
error = error + PI * 2
var torque = _get_PID_output(error,delta)
set_applied_torque(torque)
_set_vel_from_angle(get_global_rot())