-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathgimbal.py
102 lines (86 loc) · 3.39 KB
/
gimbal.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
from enum import IntEnum
from logging import getLogger
from serial import Serial
from simplebgc.command_ids import CMD_CONTROL, CMD_GET_ANGLES, CMD_CONFIRM
from simplebgc.command_parser import parse_cmd
from simplebgc.commands import ControlOutCmd, GetAnglesInCmd
from simplebgc.serial_example import create_message, \
pack_message, read_message, Message, read_cmd
from simplebgc.units import from_degree_per_sec, from_degree
logger = getLogger(__name__)
class ControlMode(IntEnum):
"""Modes of the outgoing command CMD_CONTROL
"""
no_control = 0
speed = 1
angle = 2
speed_angle = 3
rc = 4
rc_high_res = 6
angle_rel_frame = 5
# TODO flags
class Gimbal:
def __init__(self, connection: Serial = None) -> None:
if connection is None:
connection = Serial('/dev/ttyUSB0', baudrate=115200, timeout=10)
self._connection = connection
def send_message(self, message: Message):
logger.debug(f'send message: {message}')
self._connection.write(pack_message(message))
def control(
self,
yaw_mode: ControlMode = ControlMode.speed,
yaw_speed: float = 0,
yaw_angle: float = 0,
pitch_mode: ControlMode = ControlMode.speed,
pitch_speed: float = 0,
pitch_angle: float = 0,
roll_mode: ControlMode = ControlMode.speed,
roll_speed: float = 0,
roll_angle: float = 0):
control_data = ControlOutCmd(
roll_mode=int(roll_mode),
roll_speed=from_degree_per_sec(roll_speed),
roll_angle=from_degree(roll_angle),
pitch_mode=int(pitch_mode),
pitch_speed=from_degree_per_sec(pitch_speed),
pitch_angle=from_degree(pitch_angle),
yaw_mode=int(yaw_mode),
yaw_speed=from_degree_per_sec(yaw_speed),
yaw_angle=from_degree(yaw_angle))
logger.debug(f'send control cmd: {control_data}')
message = create_message(CMD_CONTROL, control_data.pack())
self.send_message(message)
confirmation: Message = read_message(self._connection, 1)
assert confirmation.command_id == CMD_CONFIRM, \
f'expected confirmation, but received command with ID' \
f' {confirmation.command_id}'
def stop(self):
self.control(roll_mode=ControlMode.no_control,
pitch_mode=ControlMode.no_control,
yaw_mode=ControlMode.no_control)
def get_angles(self) -> GetAnglesInCmd:
self.send_message(create_message(CMD_GET_ANGLES))
cmd = read_cmd(self._connection)
assert cmd.id == CMD_GET_ANGLES
return parse_cmd(cmd)
def _main():
from time import sleep
import logging
logging.basicConfig(level=logging.DEBUG)
gimbal = Gimbal()
pitch_speed = 12
yaw_speed = 60
gimbal.control(
pitch_mode=ControlMode.angle, pitch_speed=pitch_speed, pitch_angle=0,
yaw_mode=ControlMode.angle, yaw_speed=yaw_speed, yaw_angle=0)
sleep(3)
gimbal.control(
pitch_mode=ControlMode.angle, pitch_speed=pitch_speed, pitch_angle=-60,
yaw_mode=ControlMode.angle, yaw_speed=yaw_speed, yaw_angle=360)
sleep(3)
gimbal.control(
pitch_mode=ControlMode.angle, pitch_speed=pitch_speed, pitch_angle=0,
yaw_mode=ControlMode.angle, yaw_speed=yaw_speed, yaw_angle=0)
if __name__ == '__main__':
_main()