How to hover a drone at certian height?

hello there, i have a simulation where iam trying to work on line following drone! for that i have used the environment of the line following turtlebot from this git down bellow;

and then i altered the launch file(lf.launch) of the above .git so that i can remove the turtlebot robot from that environment!

<launch>
<include file="$(find gazebo_ros)/launch/empty_world.launch">
<arg name = "world_name" value = "$(find line_follower_turtlebot)/Maps/lfm1.world"/>
</include>
</launch>

and used the command “roslaunch line_follower_turtlebot lf.launch”, and then i spawned the ardrone from the package https://github.com/eborghi10/AR.Drone-ROS.git using the command “roslaunch cvg_sim_gazebo spawn_quadrotor.launch” and it got succesfully spawned in the simulation as i wanted! like in the picture below!


and iam going to apply the code as instructed in this ROS Construct Live Sessions ROS Developers LIVE Class #86: How to use OpenCV with ROS - YouTube
so for me to use that code i want the ardrone 2.0 to take-off and hover in a particular altitude so i can enable the bellow code to make it follow the line in the simulation env!!

#!/usr/bin/env python

import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
import cv2
import numpy as np
from geometry_msgs.msg import Twist


class LineFollower(object):

    def __init__(self):

        self.image_sub = rospy.Subscriber(
            "/camera/rgb/image_raw", Image, self.camera_callback)
        self.bridge_object = CvBridge()
        self.speed_pub = rospy.Publisher("/cmd_vel", Twist, queue_size=1)

    def camera_callback(self, data):
        try:
            # We select bgr8 because its the OpenCV encoding by default
            cv_image = self.bridge_object.imgmsg_to_cv2(
                data, desired_encoding="bgr8")
        except CvBridgeError as e:
            print(e)

        height, width, channels = cv_image.shape
        descentre = 160
        rows_to_watch = 60
        crop_img = cv_image[(height)/2+descentre:(height) /
                            2+(descentre+rows_to_watch)][1:width]
        hsv = cv2.cvtColor(crop_img, cv2.COLOR_BGR2HSV)
        upper_yellow = np.array([70, 48, 255])
        lower_yellow = np.array([50, 28, 245])

        # Threshold the HSV image to get only yellow colors
        mask = cv2.inRange(hsv, lower_yellow, upper_yellow)

        m = cv2.moments(mask, False)
        try:
            cx, cy = m['m10']/m['m00'], m['m01']/m['m00']
        except ZeroDivisionError:
            cy, cx = height/2, width/2

        error_x = cx - width / 2
        speed_cmd = Twist()
        speed_cmd.linear.x = 0.2
        speed_cmd.angular.z = -error_x / 100

        self.speed_pub.publish(speed_cmd)


def main():

    rospy.init_node('line_following_node', anonymous=True)
    line_follower_object = LineFollower()

    try:
        rospy.spin()
    except KeyboardInterrupt:
        print("Shutting down")


if __name__ == '__main__':
    main()

but the issue is when i ever i give the command takeoff from the keyboard_controller the drone just takes off from the ground plane and keeps on moving upwards and never stops/hover in an particular altitude and lands if i give land commnad!! i thought that the issues is with the controller of the package, but i have tried various packages for the ardrone like

  1. Ardrone_autopilot- https://github.com/Barahlush/ardrone_autopilot.git - “roslaunch ardrone_autopilot autopilot.launch”
    autopilot.launch
<launch>
    <node name="interface" pkg="ardrone_autopilot" type="interface.py" output="screen">
        <remap from="/in/image/" to="/ui/image/"/>
        <param name="swap_red_blue" value="True" />
    </node>
    <node name="controller" pkg="ardrone_autopilot" type="controller" output="screen">
    </node>
    <node name="imgHandler" pkg="ardrone_autopilot" type="imgHandler" output="screen">
    </node>
</launch>
  1. Ardrone_tutorials - https://github.com/mikehamer/ardrone_tutorials.git - “roslaunch ardrone_tutorials keyboard_controller.launch”
    keyboard_controller.py
#!/usr/bin/env python

# The Keyboard Controller Node for the tutorial "Up and flying with the AR.Drone and ROS | Getting Started"
# https://github.com/mikehamer/ardrone_tutorials

# This controller extends the base DroneVideoDisplay class, adding a keypress handler to enable keyboard control of the drone

# Import the ROS libraries, and load the manifest file which through <depend package=... /> will give us access to the project dependencies
import roslib; roslib.load_manifest('ardrone_tutorials')
import rospy

# Load the DroneController class, which handles interactions with the drone, and the DroneVideoDisplay class, which handles video display
from drone_controller import BasicDroneController
from drone_video_display import DroneVideoDisplay

# Finally the GUI libraries
from PySide import QtCore, QtGui


# Here we define the keyboard map for our controller (note that python has no enums, so we use a class)
class KeyMapping(object):
	PitchForward     = QtCore.Qt.Key.Key_E
	PitchBackward    = QtCore.Qt.Key.Key_D
	RollLeft         = QtCore.Qt.Key.Key_S
	RollRight        = QtCore.Qt.Key.Key_F
	YawLeft          = QtCore.Qt.Key.Key_W
	YawRight         = QtCore.Qt.Key.Key_R
	IncreaseAltitude = QtCore.Qt.Key.Key_Q
	DecreaseAltitude = QtCore.Qt.Key.Key_A
	Takeoff          = QtCore.Qt.Key.Key_Y
	Land             = QtCore.Qt.Key.Key_H
	Emergency        = QtCore.Qt.Key.Key_Space


# Our controller definition, note that we extend the DroneVideoDisplay class
class KeyboardController(DroneVideoDisplay):
	def __init__(self):
		super(KeyboardController,self).__init__()
		
		self.pitch = 0
		self.roll = 0
		self.yaw_velocity = 0 
		self.z_velocity = 0

# We add a keyboard handler to the DroneVideoDisplay to react to keypresses
	def keyPressEvent(self, event):
		key = event.key()

		# If we have constructed the drone controller and the key is not generated from an auto-repeating key
		if controller is not None and not event.isAutoRepeat():
			# Handle the important cases first!
			if key == KeyMapping.Emergency:
				controller.SendEmergency()
			elif key == KeyMapping.Takeoff:
				controller.SendTakeoff()
			elif key == KeyMapping.Land:
				controller.SendLand()
			else:
				# Now we handle moving, notice that this section is the opposite (+=) of the keyrelease section
				if key == KeyMapping.YawLeft:
					self.yaw_velocity += 1
				elif key == KeyMapping.YawRight:
					self.yaw_velocity += -1

				elif key == KeyMapping.PitchForward:
					self.pitch += 1
				elif key == KeyMapping.PitchBackward:
					self.pitch += -1

				elif key == KeyMapping.RollLeft:
					self.roll += 1
				elif key == KeyMapping.RollRight:
					self.roll += -1

				elif key == KeyMapping.IncreaseAltitude:
					self.z_velocity += 1
				elif key == KeyMapping.DecreaseAltitude:
					self.z_velocity += -1

			# finally we set the command to be sent. The controller handles sending this at regular intervals
			controller.SetCommand(self.roll, self.pitch, self.yaw_velocity, self.z_velocity)


	def keyReleaseEvent(self,event):
		key = event.key()

		# If we have constructed the drone controller and the key is not generated from an auto-repeating key
		if controller is not None and not event.isAutoRepeat():
			# Note that we don't handle the release of emergency/takeoff/landing keys here, there is no need.
			# Now we handle moving, notice that this section is the opposite (-=) of the keypress section
			if key == KeyMapping.YawLeft:
				self.yaw_velocity -= 1
			elif key == KeyMapping.YawRight:
				self.yaw_velocity -= -1

			elif key == KeyMapping.PitchForward:
				self.pitch -= 1
			elif key == KeyMapping.PitchBackward:
				self.pitch -= -1

			elif key == KeyMapping.RollLeft:
				self.roll -= 1
			elif key == KeyMapping.RollRight:
				self.roll -= -1

			elif key == KeyMapping.IncreaseAltitude:
				self.z_velocity -= 1
			elif key == KeyMapping.DecreaseAltitude:
				self.z_velocity -= -1

			# finally we set the command to be sent. The controller handles sending this at regular intervals
			controller.SetCommand(self.roll, self.pitch, self.yaw_velocity, self.z_velocity)



# Setup the application
if __name__=='__main__':
	import sys
	# Firstly we setup a ros node, so that we can communicate with the other packages
	rospy.init_node('ardrone_keyboard_controller')

	# Now we construct our Qt Application and associated controllers and windows
	app = QtGui.QApplication(sys.argv)
	controller = BasicDroneController()
	display = KeyboardController()

	display.show()

	# executes the QT application
	status = app.exec_()

	# and only progresses to here once the application has been shutdown
	rospy.signal_shutdown('Great Flying!')
	sys.exit(status)

keyboard_controller.launch

<launch>
	<!-- Launches the AR.Drone driver -->
	<node name="ardrone_driver" pkg="ardrone_autonomy" type="ardrone_driver" output="screen" clear_params="true">
	    <param name="outdoor" value="0" /> <!-- If we are flying outdoors, will select more aggressive default settings -->
	    <param name="flight_without_shell" value="0" /> <!-- Changes internal controller gains if we are flying without the propeller guard -->
	    
	    <param name="altitude_max" value="3000" /> <!-- in millimeters = 3 meters = 9' -->
        <param name="altitude_min" value="50" /> <!-- in millimeters = 5cm = 2" -->
        <param name="euler_angle_max" value="0.1" /> <!-- maximum allowable body angle in radians = 5 degrees -->
        <param name="control_vz_max" value="200" /> <!-- maximum z velocity in mm/sec = 0.2m/sec -->
	    <param name="control_yaw" value="0.7" /> <!-- maximum rotation rate in radians/sec = 40 degrees per second (1/9 rev/sec) -->
	</node>
	
	<!-- Launches the keyboard controller -->
	<node name="keyboard_controller" pkg="ardrone_tutorials" type="keyboard_controller.py" required="true"/>
</launch>

sorry for the long question! please do suggest me with some solution for this!(Note iam working in my ROS Kinetic and gazebo 7 vesrion in my Ubuntu 16.04!)

Hi @BadhriROS ,

It is a quite interesting question in a complex environment.
It’s quite hard to say what is right or wrong in this kind of situation, because there are many variables involved.

A first step to have some help in this forum would be creating a rosject in ROSDS and sharing it. It is a forum for all users of the platform, so you could have some help from other users on questions not related to our material (e.g: Courses, live classes, etc.)

Regards

hello @marco.nc.arruda ,
sorry for the late reply, i have added my rosject down below and added the steps in which i have done in the jupiter notepad. I have been stuck with this issue for a long time now! it would be great if this issue could be helped!

thank you,

regards