XTDrone/communication/rover_communication.py

171 lines
7.0 KiB
Python
Raw Normal View History

2020-05-05 21:16:54 +08:00
import rospy
2021-02-25 20:04:29 +08:00
from mavros_msgs.msg import State, PositionTarget
from mavros_msgs.srv import CommandBool, SetMode
2020-05-07 23:32:15 +08:00
from geometry_msgs.msg import PoseStamped, Pose, Twist
from nav_msgs.msg import Odometry
2020-05-05 21:16:54 +08:00
from gazebo_msgs.srv import GetModelState
from std_msgs.msg import String
from pyquaternion import Quaternion
import math
import sys
class Communication:
def __init__(self, vehicle_id):
self.vehicle_type = 'rover'
self.vehicle_id = vehicle_id
self.local_pose = None
self.target_motion = PositionTarget()
self.arm_state = False
self.motion_type = 0
self.flight_mode = None
self.mission = None
2020-05-07 23:32:15 +08:00
self.motion_type = 1
self.coordinate_frame = 1
2020-05-05 21:16:54 +08:00
'''
ros subscribers
'''
2020-05-08 21:11:45 +08:00
self.local_pose_sub = rospy.Subscriber(self.vehicle_type+'_'+self.vehicle_id+"/mavros/local_position/pose", PoseStamped, self.local_pose_callback)
self.mavros_sub = rospy.Subscriber(self.vehicle_type+'_'+self.vehicle_id+"/mavros/state", State, self.mavros_state_callback)
self.cmd_pose_flu_sub = rospy.Subscriber("/xtdrone/"+self.vehicle_type+'_'+self.vehicle_id+"/cmd_pose_flu", Pose, self.cmd_pose_flu_callback)
self.cmd_pose_enu_sub = rospy.Subscriber("/xtdrone/"+self.vehicle_type+'_'+self.vehicle_id+"/cmd_pose_enu", Pose, self.cmd_pose_enu_callback)
self.cmd_vel_flu_sub = rospy.Subscriber("/xtdrone/"+self.vehicle_type+'_'+self.vehicle_id+"/cmd_vel_flu", Twist, self.cmd_vel_flu_callback)
self.cmd_vel_enu_sub = rospy.Subscriber("/xtdrone/"+self.vehicle_type+'_'+self.vehicle_id+"/cmd_vel_enu", Twist, self.cmd_vel_enu_callback)
2020-05-05 21:16:54 +08:00
2020-05-08 21:11:45 +08:00
self.cmd_sub = rospy.Subscriber("/xtdrone/"+self.vehicle_type+'_'+self.vehicle_id+"/cmd",String,self.cmd_callback)
2020-05-05 21:16:54 +08:00
'''
ros publishers
'''
2020-05-08 21:11:45 +08:00
self.target_motion_pub = rospy.Publisher(self.vehicle_type+'_'+self.vehicle_id+"/mavros/setpoint_raw/local", PositionTarget, queue_size=10)
self.odom_groundtruth_pub = rospy.Publisher('/xtdrone/'+self.vehicle_type+'_'+self.vehicle_id+'/ground_truth/odom', Odometry, queue_size=10)
2020-05-05 21:16:54 +08:00
'''
ros services
'''
2020-05-08 21:11:45 +08:00
self.armService = rospy.ServiceProxy(self.vehicle_type+'_'+self.vehicle_id+"/mavros/cmd/arming", CommandBool)
self.flightModeService = rospy.ServiceProxy(self.vehicle_type+'_'+self.vehicle_id+"/mavros/set_mode", SetMode)
2020-05-05 21:16:54 +08:00
self.gazeboModelstate = rospy.ServiceProxy('gazebo/get_model_state', GetModelState)
2020-05-08 21:11:45 +08:00
print(self.vehicle_type+'_'+self.vehicle_id+": "+"communication initialized")
2020-05-05 21:16:54 +08:00
def start(self):
2020-05-08 21:11:45 +08:00
rospy.init_node(self.vehicle_type+'_'+self.vehicle_id+"_communication")
2020-05-05 21:16:54 +08:00
rate = rospy.Rate(100)
'''
main ROS thread
'''
2020-05-14 12:50:41 +08:00
while not rospy.is_shutdown():
2020-05-05 21:16:54 +08:00
self.target_motion_pub.publish(self.target_motion)
try:
response = self.gazeboModelstate (self.vehicle_type+'_'+self.vehicle_id,'ground_plane')
except rospy.ServiceException, e:
print "Gazebo model state service call failed: %s"%e
2020-05-07 23:32:15 +08:00
odom = Odometry()
odom.header = response.header
odom.pose.pose = response.pose
odom.twist.twist = response.twist
self.odom_groundtruth_pub.publish(odom)
2020-05-05 21:16:54 +08:00
if (self.flight_mode is "LAND") and (self.local_pose.pose.position.z < 0.15):
if(self.disarm()):
self.flight_mode = "DISARMED"
rate.sleep()
def local_pose_callback(self, msg):
self.local_pose = msg
def mavros_state_callback(self, msg):
self.mavros_state = msg.mode
2020-05-07 23:32:15 +08:00
def construct_target(self, x=0, y=0, z=0, vx=0, vy=0, vz=0, yaw=0):
2020-05-05 21:16:54 +08:00
target_raw_pose = PositionTarget()
2020-05-07 23:32:15 +08:00
target_raw_pose.coordinate_frame = self.coordinate_frame
2020-05-05 21:16:54 +08:00
2020-12-14 19:22:34 +08:00
target_raw_pose.position.x = x
target_raw_pose.position.y = y
target_raw_pose.position.z = z
2020-05-05 21:16:54 +08:00
2020-12-14 19:22:34 +08:00
target_raw_pose.velocity.x = vx
target_raw_pose.velocity.y = vy
target_raw_pose.velocity.z = vz
2020-05-05 21:16:54 +08:00
target_raw_pose.yaw = yaw
2020-05-07 23:32:15 +08:00
if(self.motion_type == 0):
2020-05-05 21:16:54 +08:00
target_raw_pose.type_mask = PositionTarget.IGNORE_VX + PositionTarget.IGNORE_VY + PositionTarget.IGNORE_VZ \
2020-05-07 16:53:02 +08:00
+ PositionTarget.IGNORE_AFX + PositionTarget.IGNORE_AFY + PositionTarget.IGNORE_AFZ + PositionTarget.IGNORE_YAW_RATE
2020-05-07 23:32:15 +08:00
if(self.motion_type == 1):
2020-05-05 21:16:54 +08:00
target_raw_pose.type_mask = PositionTarget.IGNORE_PX + PositionTarget.IGNORE_PY + PositionTarget.IGNORE_PZ \
+ PositionTarget.IGNORE_AFX + PositionTarget.IGNORE_AFY + PositionTarget.IGNORE_AFZ \
2020-05-07 16:53:02 +08:00
+ PositionTarget.IGNORE_YAW_RATE
2020-05-05 21:16:54 +08:00
return target_raw_pose
def cmd_pose_flu_callback(self, msg):
2020-05-07 23:32:15 +08:00
self.coordinate_frame=9
self.motion_type=0
self.target_motion = self.construct_target(x=msg.position.x,y=msg.position.y,z=msg.position.z,yaw=0)
2020-05-05 21:16:54 +08:00
def cmd_pose_enu_callback(self, msg):
2020-05-07 23:32:15 +08:00
self.coordinate_frame=1
self.motion_type=0
self.target_motion = self.construct_target(x=msg.position.x,y=msg.position.y,z=msg.position.z,yaw=0)
2020-05-05 21:16:54 +08:00
def cmd_vel_flu_callback(self, msg):
2020-05-07 23:32:15 +08:00
self.coordinate_frame=8
self.motion_type=1
2020-12-15 00:07:07 +08:00
self.target_motion = self.construct_target(vx=msg.linear.x,vy=msg.angular.z,vz=msg.linear.z,yaw=0)
2020-05-05 21:16:54 +08:00
def cmd_vel_enu_callback(self, msg):
2020-05-07 23:32:15 +08:00
self.coordinate_frame=1
self.motion_type=1
2020-12-15 00:07:07 +08:00
self.target_motion = self.construct_target(vx=msg.linear.x,vy=msg.angular.z,vz=msg.linear.z,yaw=0)
2020-05-05 21:16:54 +08:00
def cmd_callback(self, msg):
if msg.data == '':
return
elif msg.data == 'ARM':
self.arm_state =self.arm()
2020-05-12 17:28:54 +08:00
print(self.vehicle_type+'_'+self.vehicle_id+": Armed "+str(self.arm_state))
2020-05-05 21:16:54 +08:00
elif msg.data == 'DISARM':
2020-05-07 23:32:15 +08:00
self.arm_state =not self.disarm()
2020-05-12 17:28:54 +08:00
print(self.vehicle_type+'_'+self.vehicle_id+": Armed "+str(self.arm_state))
2020-05-05 21:16:54 +08:00
elif msg.data[:-1] == "mission" and not msg.data == self.mission:
self.mission = msg.data
2020-05-08 21:11:45 +08:00
print(self.vehicle_type+'_'+self.vehicle_id+": "+msg.data)
2020-05-05 21:16:54 +08:00
elif not msg.data == self.flight_mode:
self.flight_mode = msg.data
self.flight_mode_switch()
def arm(self):
if self.armService(True):
return True
else:
2020-05-08 21:11:45 +08:00
print(self.vehicle_type+'_'+self.vehicle_id+": arming failed!")
2020-05-05 21:16:54 +08:00
return False
def disarm(self):
if self.armService(False):
return True
else:
2020-05-08 21:11:45 +08:00
print(self.vehicle_type+'_'+self.vehicle_id+": disarming failed!")
2020-05-05 21:16:54 +08:00
return False
def flight_mode_switch(self):
if self.flightModeService(custom_mode=self.flight_mode):
2020-05-08 21:11:45 +08:00
print(self.vehicle_type+'_'+self.vehicle_id+": "+self.flight_mode)
2020-05-05 21:16:54 +08:00
return True
else:
2020-05-08 21:11:45 +08:00
print(self.vehicle_type+'_'+self.vehicle_id+": "+self.flight_mode+"failed")
2020-05-05 21:16:54 +08:00
return False
if __name__ == '__main__':
communication = Communication(sys.argv[1])
communication.start()