forked from bskari/pi-rc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
control.py
executable file
·145 lines (118 loc) · 4.07 KB
/
control.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python
"""Manually send commands to the RC car."""
import argparse
import socket
import sys
from common import dead_frequency
from common import format_command
from common import server_up
# pylint: disable=superfluous-parens
def input_function(type_cast):
"""Returns the input function for the running version of Python for reading
data from stdin.
"""
# pylint: disable=bad-builtin
if sys.version_info.major == 2:
return lambda message: type_cast(raw_input(message))
else:
return lambda message: type_cast(input(message))
def get_command_array(parser):
"""Returns an array of command information that can be used in the
format_command function.
"""
args = parser.parse_args()
read_float = input_function(float)
read_int = input_function(int)
option_to_prompt_and_function = {
'frequency': ('Command frequency? ', read_float),
'microseconds': ('Microseconds? ', read_int),
'sync_multiplier': ('Synchronization multiplier? ', read_int),
'sync_repeats': ('Synchronization repeats? ', read_int),
}
for option, prompt_and_function in option_to_prompt_and_function.items():
if getattr(args, option) is None:
prompt, function = prompt_and_function
setattr(args, option, function(prompt))
return [
float(args.frequency),
int(args.microseconds),
int(args.sync_multiplier),
int(args.sync_repeats),
0, # Signal repeats, to be read in and configured later
]
def make_parser():
"""Builds and returns an argument parser."""
parser = argparse.ArgumentParser(
description='Sends burst commands to Raspberry Pi RC.'
)
parser.add_argument(
'-p',
'--port',
dest='port',
help='The port to send control commands to.',
default=12345,
type=int
)
parser.add_argument(
'-s',
'--server',
dest='server',
help='The server to send control commands to.',
default='127.1'
)
parser.add_argument(
'-f',
'--frequency',
dest='frequency',
help='The frequency to broadcast commands on.'
)
parser.add_argument(
'-u',
'--microseconds',
dest='microseconds',
help='The interval in microseconds for the commands.'
)
parser.add_argument(
'--sync-multiplier',
dest='sync_multiplier',
help='The multiplier of the interval microseconds for the'
' synchronization burst. For example, if the microseconds is 100'
' and the multiplier is 3, each synchronization burst will have'
' 300 us of signal and 100 us of dead signal.'
)
parser.add_argument(
'--sync-repeats',
dest='sync_repeats',
help='The number of times to repeat the synchronization bursts.'
)
return parser
def send_signal_repeats(host, port, command_array):
"""Reads signal repeat bursts and sends commands to the Raspberry Pi."""
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
read_int = input_function(int)
while True:
try:
command_array[4] = read_int('Signal repeats? ')
except ValueError:
pass
# pylint: disable=star-args
command = format_command(*command_array)
if sys.version_info.major == 3:
command = bytes(command, 'utf-8')
sock.sendto(command, (host, port))
def main():
"""Parses command line arguments and runs the simple controller."""
parser = make_parser()
args = parser.parse_args()
if args.frequency is not None:
frequency = dead_frequency(args.frequency)
else:
frequency = 49.830
if not server_up(args.server, args.port, frequency):
print('Server does not appear to be listening for messages, aborting')
return
command_array = get_command_array(parser)
print('Sending commands to ' + args.server + ':' + str(args.port))
send_signal_repeats(args.server, args.port, command_array)
if __name__ == '__main__':
main()