Загрузка данных


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Clover Gazebo. map frame, z=1.0.
LED after arriving. set_altitude keeps offboard during waits (no re-navigate).

X_FIX: sim offset +1 m on X for right side (x >= 4).
After red: navigate_target hops without gap.
"""

import math
import rospy
from clover import srv
from clover.srv import SetLEDEffect
from std_srvs.srv import Trigger

Z = 1.0
SPD = 0.5
SPD_SLOW = 0.4
WAIT_EXTRA = 2.5
X_FIX = -1.0
FRAME_MAP = 'map'
FRAME_REL = 'navigate_target'

rospy.init_node('clover_autonomous_mission')
navigate = rospy.ServiceProxy('navigate', srv.Navigate)
set_altitude = rospy.ServiceProxy('set_altitude', srv.SetAltitude)
land = rospy.ServiceProxy('land', Trigger)
set_effect = rospy.ServiceProxy('led/set_effect', SetLEDEffect)

pos_x, pos_y = 0.0, 0.0


def led(r, g, b):
    try:
        set_effect(effect='fill', r=r, g=g, b=b)
    except rospy.ServiceException:
        pass


def wait_sec(sec):
    end = rospy.Time.now() + rospy.Duration(sec)
    while rospy.Time.now() < end and not rospy.is_shutdown():
        set_altitude(z=Z, frame_id=FRAME_MAP)
        rospy.sleep(0.3)


def leg_time(dx, dy, speed):
    return math.hypot(dx, dy) / speed + WAIT_EXTRA


def fix_x(x, y):
    if x >= 4.0:
        return x + X_FIX, y
    return x, y


def go(x, y, t=None, speed=SPD):
    global pos_x, pos_y
    if t is None:
        t = leg_time(x - pos_x, y - pos_y, speed)
    set_altitude(z=Z, frame_id=FRAME_MAP)
    navigate(x=x, y=y, z=Z, speed=speed, frame_id=FRAME_MAP)
    wait_sec(t)
    pos_x, pos_y = x, y


def go_rel(dx, dy, t=None, speed=SPD_SLOW):
    global pos_x, pos_y
    if t is None:
        t = leg_time(dx, dy, speed)
    set_altitude(z=Z, frame_id=FRAME_MAP)
    navigate(x=dx, y=dy, z=Z, speed=speed, frame_id=FRAME_REL)
    wait_sec(t)
    pos_x += dx
    pos_y += dy


def go_led(x, y, r, g, b, t=None, speed=SPD):
    go(x, y, t, speed)
    led(r, g, b)
    wait_sec(1.0)


def go_rel_led(dx, dy, r, g, b, t=None, speed=SPD_SLOW):
    go_rel(dx, dy, t, speed)
    led(r, g, b)
    wait_sec(0.8)


def marker_xy(mid):
    row = mid // 7
    col = mid % 7
    return col * 1.0, (6 - row) * 1.0


def mid(a, b):
    xa, ya = marker_xy(a)
    xb, yb = marker_xy(b)
    return (xa + xb) / 2.0, (ya + yb) / 2.0


try:
    led(255, 255, 255)
    navigate(x=0, y=0, z=Z, speed=0.5, frame_id='body', auto_arm=True)
    rospy.sleep(6.0)
    set_altitude(z=Z, frame_id=FRAME_MAP)
    pos_x, pos_y = 0.0, 0.0

    x, y = marker_xy(44)
    go(x, y)

    x, y = marker_xy(38)
    go_led(x, y, 255, 0, 255)

    x, y = fix_x(*mid(26, 33))
    go_led(x, y, 255, 165, 0)

    x, y = fix_x(5.0, 4.0)
    go(x, y)

    x, y = fix_x(*mid(19, 20))
    go_led(x, y, 0, 255, 255)

    x, y = fix_x(*marker_xy(12))
    go_led(x, y, 128, 0, 255)

    x, y = fix_x(*marker_xy(11))
    go(x, y)

    x, y = marker_xy(17)
    go_led(x, y, 255, 0, 0)

    go_rel(-1.0, 0.0)
    go_rel(0.0, 1.0)
    go_rel_led(-1.0, 0.0, 255, 255, 0)

    gx, gy = mid(14, 21)
    go(1.0, gy, speed=SPD_SLOW)
    go_led(gx, gy, 0, 255, 0, speed=SPD_SLOW)

    bx, by = mid(22, 23)
    go(1.0, by, speed=SPD_SLOW)
    go_led(bx, by, 0, 0, 139, speed=SPD_SLOW)

    go(1.0, 1.0, speed=SPD_SLOW)
    go(2.0, 1.0, speed=SPD_SLOW)
    x, y = marker_xy(38)
    go_led(x, y, 255, 0, 255, speed=SPD_SLOW)

    go(3.0, 0.0, speed=SPD_SLOW)
    go(2.0, 0.0, speed=SPD_SLOW)
    go(1.0, 0.0, speed=SPD_SLOW)
    go(0.0, 0.0, speed=SPD_SLOW)

    land()
    rospy.sleep(2.0)
    led(0, 0, 0)

except rospy.ROSInterruptException:
    pass
except KeyboardInterrupt:
    try:
        land()
        led(0, 0, 0)
    except rospy.ServiceException:
        pass