OK. I have been doing more testing, and it seems to me that there is some bug in the implementation of the guided mode altitude control or altitude source. I changed the control from vehicle:set_target_location to vehicle:set_target_velocity_NED(target_vel) , but it did not change anything as far as altitude drift is concerned.
I did two test flights
In the first test flight, there was an unsolicited variation of baro altitude from 31 to 47 (i.e. 16 meters), and the copter was doing cycles of slowly climbing and going down. The target altitude was set to 174.1 meters (which is equal to 40 meters plus home altitude). This did not change during the flight.
The copter altitude was obtained using current_pos = ahrs:get_position()/100. Once the copter climbed to that target altitude, the copter remained very close to that altitude (± 1m), Accordingly, the vz was 0 if there was a differene of less than 1 meter. current_pos altitude and 174 meters were within 1 meter. But the copter visually climbed slowly up and down several
times in a very pronounced manner, and the baro data also reflects it (as well as GPS data).
There was automatic yaw tracking by means of injecting:
if in_yaw then in_yaw:set_override(1500-math.floor(yaw_PWM_offset)) end
which would generate PWM around 1450..1550. The option to allow yaw override was set, so that the pilot (or script by injecting RC channel) can change yaw in guide mode.
The .bin file contains messages with all the parameters used for setting vz:
gcs:send_text(6, string.format( "sign:%.0f dalt:%.1f vz:%.1f dist::%.1f C:%.1f T:%.1f ",vzdirection,dalt,vz,dist,current_pos:alt()/100,Copter_target:alt()/100))
tyícal output once the copter climbed to position:
sign:1 dalt:0.4 vz:0.0 dist::0.9 C:174.5 T:174.1
In the second flight, there was unsolicited variation of baro altitude of from 24 to 34 meters (10 meters). The target altitude was set to 176.6 meters (which is equal to 40 meters plus home altitude). The whole time it stayed pretty close to 176.6 meters, varying by ± 1 meter. There are messages in the .bin file where one can check that. During this second flight, the automatic yaw tracking was disabled. Towards the end of the flight I started yawing the copter manually. Overall, the second flight had slighly lower visible variation of altitude compared to the first flight.
Below is the section responsible for setting vz, vx, and vy for the speed controller:
local current_pos = ahrs:get_position()
if current_pos then – if current_pos and vehicle:get_mode()~=9
local target_vel = Vector3f()
– if vehicle:get_mode()~=4 then vehicle:set_mode(4) end – To prevent accidental disengagement due to mode change
local dist=current_pos:get_distance(Copter_target)
local bearing=current_pos:get_bearing(Copter_target)
local dalt=(Copter_target:alt()-current_pos:alt())/100 -- 40 -
local vzdirection=0
if dalt>0 then vzdirection=-1 end
if dalt<0 then vzdirection=1 end --
dalt=math.abs(dalt)
local vz=dalt/2
if vz > Max_Descent_Vertical_Speed then vz=Max_Descent_Vertical_Speed end
vz=vzdirection*vz
if math.abs(dalt)<1 then vz=0 end
speed=dist/6
if speed>Max_Descent_Horizontal_Speed then speed =Max_Descent_Horizontal_Speed end
if dist<1 then speed=0 end
gcs:send_text(6, string.format( "sign:%.0f dalt:%.1f vz:%.1f dist::%.1f C:%.1f T:%.1f ",vzdirection,dalt,vz,dist,current_pos:alt()/100,Copter_target:alt()/100))
target_vel:x(math.cos(bearing) * speed)
target_vel:y(math.sin(bearing) * speed)
target_vel:z(vz)
vehicle:set_target_velocity_NED(target_vel)
-- We have: TARGET: Copter_target, NOW: current_pos these are locations.
-- Obtain distance from Target to NOW.
-- Obtain bearing from Target to NOW
-- Obtain alt diff from Target to NOW
-- Depending on the distance establish the speed (the smaller the distance, the smaller the speed)
-- Depending on the alt diff, establish vertical speed
-- verify that vertical speed and horizontal speed is within limits
local Copter_pitch_rad = ahrs:get_pitch_rad()
local Copter_pitch_deg = math.deg(Copter_pitch_rad)
local distance_to_Plane = current_pos:get_distance(Plane_Pos)
local bearing_to_Plane_radians = current_pos:get_bearing(Plane_Pos)
local heading_to_Plane_deg = math.deg (bearing_to_Plane_radians)
local copter_yaw=ahrs:get_yaw_rad() -- yaw correction using injection of yaw PWM
local copter_yawdeg=math.deg (copter_yaw)
if copter_yawdeg<0 then copter_yawdeg= 360 + copter_yawdeg end
local yaw_PWM_offset = 0
local diff=copter_yawdeg- heading_to_Plane_deg
local normalized_diff = ( diff + 180) % 360 - 180 -- normalized angle
yaw_PWM_offset=normalized_diff*6
if yaw_PWM_offset>80 then yaw_PWM_offset=70 end
if yaw_PWM_offset<-80 then yaw_PWM_offset=-70 end
if math.abs(normalized_diff)<3 then yaw_PWM_offset=0 end
local in_yaw = rc:get_channel(4) -- yaw
if in_yaw then in_yaw:set_override(1500-math.floor(yaw_PWM_offset)) end
end
end
Reworked script which was used: RETRANSLATOR_012.lua (37.8 KB)