nxt 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +45 -0
  3. data/lib/communication/bluetooth_communication.rb +85 -0
  4. data/lib/communication/serial_port_profile.rb +71 -0
  5. data/lib/nxt.rb +111 -20
  6. data/lib/ruby-nxt.sublime-project +8 -0
  7. data/lib/ruby-nxt.sublime-workspace +288 -0
  8. data/lib/telegrams/commands/direct/get_battery_level.rb +8 -0
  9. data/lib/telegrams/commands/direct/get_current_program_name.rb +8 -0
  10. data/lib/{nxt/commands/sound.rb → telegrams/commands/direct/get_input_values.rb} +0 -0
  11. data/lib/{nxt/commands/tone.rb → telegrams/commands/direct/keep_alive.rb} +0 -0
  12. data/lib/telegrams/commands/direct/ls_get_status.rb +0 -0
  13. data/lib/telegrams/commands/direct/ls_read.rb +0 -0
  14. data/lib/telegrams/commands/direct/ls_write.rb +0 -0
  15. data/lib/telegrams/commands/direct/message_read.rb +0 -0
  16. data/lib/telegrams/commands/direct/message_write.rb +0 -0
  17. data/lib/telegrams/commands/direct/output_state.rb +229 -0
  18. data/lib/telegrams/commands/direct/play_sound_file.rb +38 -0
  19. data/lib/telegrams/commands/direct/play_tone.rb +34 -0
  20. data/lib/telegrams/commands/direct/replies/get_battery_level_reply.rb +28 -0
  21. data/lib/telegrams/commands/direct/replies/get_current_program_name_reply.rb +30 -0
  22. data/lib/telegrams/commands/direct/replies/play_sound_file_reply.rb +13 -0
  23. data/lib/telegrams/commands/direct/replies/play_tone_reply.rb +14 -0
  24. data/lib/telegrams/commands/direct/replies/reset_motor_position_reply.rb +13 -0
  25. data/lib/telegrams/commands/direct/replies/set_input_mode_reply.rb +11 -0
  26. data/lib/telegrams/commands/direct/replies/set_output_state_reply.rb +11 -0
  27. data/lib/telegrams/commands/direct/replies/start_program_reply.rb +13 -0
  28. data/lib/telegrams/commands/direct/replies/stop_program_reply.rb +13 -0
  29. data/lib/telegrams/commands/direct/replies/stop_sound_playback_reply.rb +13 -0
  30. data/lib/telegrams/commands/direct/reset_input_scaled_value.rb +0 -0
  31. data/lib/telegrams/commands/direct/reset_motor_position.rb +8 -0
  32. data/lib/telegrams/commands/direct/set_input_mode.rb +101 -0
  33. data/lib/telegrams/commands/direct/set_output_state.rb +29 -0
  34. data/lib/telegrams/commands/direct/start_program.rb +30 -0
  35. data/lib/telegrams/commands/direct/stop_program.rb +9 -0
  36. data/lib/telegrams/commands/direct/stop_sound_playback.rb +8 -0
  37. data/lib/telegrams/commands/direct_command.rb +8 -0
  38. data/lib/telegrams/commands/direct_command_reply.rb +10 -0
  39. data/lib/telegrams/commands/message_translator.rb +46 -0
  40. data/lib/telegrams/commands/system/get_device_info.rb +8 -0
  41. data/lib/telegrams/commands/system/replies/get_device_info_reply.rb +41 -0
  42. data/lib/telegrams/commands/system_command.rb +8 -0
  43. data/lib/telegrams/messages/error.rb +0 -0
  44. data/lib/telegrams/messages/message.rb +0 -0
  45. data/lib/telegrams/messages/success.rb +0 -0
  46. data/lib/telegrams/no_message_reply.rb +10 -0
  47. data/lib/telegrams/reply.rb +82 -0
  48. data/lib/telegrams/respondable_telegram.rb +29 -0
  49. data/lib/telegrams/telegram.rb +14 -0
  50. data/spec/communication/bluetooth_communication_spec.rb +170 -0
  51. data/spec/communication/serial_port_profile_spec.rb +139 -0
  52. data/spec/helper.rb +1 -0
  53. data/spec/nxt_spec.rb +438 -0
  54. data/spec/telegrams/commands/direct/get_battery_level_spec.rb +26 -0
  55. data/spec/telegrams/commands/direct/get_current_program_name_spec.rb +26 -0
  56. data/spec/telegrams/commands/direct/output_state_spec.rb +198 -0
  57. data/spec/telegrams/commands/direct/play_sound_file_spec.rb +75 -0
  58. data/spec/telegrams/commands/direct/play_tone_spec.rb +63 -0
  59. data/spec/telegrams/commands/direct/replies/get_battery_level_reply_spec.rb +40 -0
  60. data/spec/telegrams/commands/direct/replies/get_current_program_name_reply_spec.rb +33 -0
  61. data/spec/telegrams/commands/direct/replies/play_sound_file_reply_spec.rb +13 -0
  62. data/spec/telegrams/commands/direct/replies/play_tone_reply_spec.rb +14 -0
  63. data/spec/telegrams/commands/direct/replies/reset_motor_position_reply_spec.rb +13 -0
  64. data/spec/telegrams/commands/direct/replies/set_input_mode_reply_spec.rb +12 -0
  65. data/spec/telegrams/commands/direct/replies/set_output_state_reply_spec.rb +12 -0
  66. data/spec/telegrams/commands/direct/replies/start_program_reply_spec.rb +12 -0
  67. data/spec/telegrams/commands/direct/replies/stop_program_reply_spec.rb +13 -0
  68. data/spec/telegrams/commands/direct/replies/stop_sound_playback_reply_spec.rb +13 -0
  69. data/spec/telegrams/commands/direct/reset_motor_position_spec.rb +31 -0
  70. data/spec/telegrams/commands/direct/set_input_mode_spec.rb +122 -0
  71. data/spec/telegrams/commands/direct/set_output_state_spec.rb +72 -0
  72. data/spec/telegrams/commands/direct/start_program_spec.rb +58 -0
  73. data/spec/telegrams/commands/direct/stop_program_spec.rb +34 -0
  74. data/spec/telegrams/commands/direct/stop_sound_playback_spec.rb +34 -0
  75. data/spec/telegrams/commands/direct_command_reply_spec.rb +7 -0
  76. data/spec/telegrams/commands/direct_command_spec.rb +34 -0
  77. data/spec/telegrams/commands/system/get_device_info_spec.rb +16 -0
  78. data/spec/telegrams/commands/system/replies/get_device_info_reply_spec.rb +63 -0
  79. data/spec/telegrams/commands/system_command_spec.rb +26 -0
  80. data/spec/telegrams/no_message_reply_spec.rb +12 -0
  81. data/spec/telegrams/reply_spec.rb +63 -0
  82. data/spec/telegrams/respondable_telegram_spec.rb +66 -0
  83. data/spec/telegrams/telegram_spec.rb +38 -0
  84. metadata +97 -116
  85. data/README.markdown +0 -52
  86. data/Rakefile +0 -35
  87. data/lib/nxt/commands/base.rb +0 -51
  88. data/lib/nxt/commands/input.rb +0 -60
  89. data/lib/nxt/commands/output.rb +0 -105
  90. data/lib/nxt/commands/program.rb +0 -70
  91. data/lib/nxt/connectors/base.rb +0 -35
  92. data/lib/nxt/connectors/input/color.rb +0 -30
  93. data/lib/nxt/connectors/input/touch.rb +0 -11
  94. data/lib/nxt/connectors/input/ultrasonic.rb +0 -11
  95. data/lib/nxt/connectors/output/motor.rb +0 -114
  96. data/lib/nxt/errors.rb +0 -25
  97. data/lib/nxt/exceptions.rb +0 -26
  98. data/lib/nxt/interfaces/base.rb +0 -36
  99. data/lib/nxt/interfaces/serial_port.rb +0 -88
  100. data/lib/nxt/interfaces/usb.rb +0 -8
  101. data/lib/nxt/nxt_brick.rb +0 -167
  102. data/lib/nxt/patches/module.rb +0 -22
  103. data/lib/nxt/patches/string.rb +0 -29
  104. data/lib/nxt/utils/accessors.rb +0 -24
  105. data/spec/matchers.rb +0 -7
  106. data/spec/nxt/connectors/output/motor_spec.rb +0 -55
  107. data/spec/nxt/interfaces/serial_port_spec.rb +0 -73
  108. data/spec/nxt/nxt_brick_spec.rb +0 -199
  109. data/spec/spec_helper.rb +0 -4
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YzRkYzdlZjJiYTJlMGRmMDgyYWJjMzY5ZmU3ZTQ1NzQ0NGYyMTQ3MQ==
5
+ data.tar.gz: !binary |-
6
+ MDk4YzYwNjg5NDQzYzFhZTM0ZDIzNDFjYTg0ZGNjNWZhMDM1YzhlZg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ZmFjYjE0M2YyNjY5YTdjY2JmNzRhZGM3N2QzNzc1YWQ2NTY0N2Q1NDFkY2My
10
+ ZGY2NGRlODJkNWM5YmVmNzNkZTA4NWU5MGM1NWU3NjZhZDRkOTU3MDYyOTk1
11
+ MmMwN2IzZTYxMDNhZmY1ODQ0YWY0YzM3ZjgwZDVlMTIzZGZjMTE=
12
+ data.tar.gz: !binary |-
13
+ NzliYTQ5ZmUwNTBiOTQzZTY4Nzk5NjkwOWFmOWQ2NTI3NmMzMjhmYTc5NjVh
14
+ NThjYjFjNjJkZTIxMGFmNzk1N2UyMDkyZjM0Y2M0NTVkZDE3OTQ0Nzc3MzM1
15
+ YmE1NTVlZDlhYWU0YzE4Y2Y5OGYxMzFkNjFiNDU2ODBlMmM0OGI=
@@ -0,0 +1,45 @@
1
+ # NXT
2
+ A ruby gem for controlling Lego Mindstorms NXT 2.0
3
+
4
+ ## Installation
5
+ Either install it from the command-line:
6
+
7
+ ```shell
8
+ $ gem install nxt
9
+ ```
10
+
11
+ or add to your Gemfile and install it:
12
+ ```ruby
13
+ source "https://rubygems.org"
14
+
15
+ gem 'nxt'
16
+ ```
17
+ ```shell
18
+ $ bundle install
19
+ ```
20
+
21
+ ## Usage
22
+ The most basic usage can be done using the NXT class by connecting your NXT 2.0
23
+ brick over Bluetooth. In the examples below, the brick is connected at
24
+ ``` /dev/tty.NXT-DevB ```:
25
+
26
+ ```ruby
27
+ require 'nxt'
28
+
29
+ nxt = Nxt.new('/dev/tty.NXT-DevB')
30
+
31
+ puts "Connecting..."
32
+ nxt.connect
33
+
34
+ puts "Moving what is typically the right wheel one rotation..."
35
+ state = OutputState.new :port => :c,
36
+ :power => 55,
37
+ :mode_flags => OutputModeFlags.MOTORON | OutputModeFlags.BRAKE,
38
+ :regulation_mode => :motor_speed,
39
+ :run_state => :running,
40
+ :tacho_limit => 360 # degrees = 1 rotation
41
+
42
+ nxt.set_output_state state
43
+ nxt.disconnect
44
+ ```
45
+
@@ -0,0 +1,85 @@
1
+ require_relative './serial_port_profile'
2
+
3
+ class BluetoothCommunication
4
+ def initialize(device, serial_port_profile=nil)
5
+ raise ArgumentError, "device must be non-nil" if device.nil?
6
+
7
+ @profile = serial_port_profile || SerialPortProfile.new(device)
8
+ end
9
+
10
+ def connect
11
+ @profile.connect
12
+ end
13
+
14
+ def disconnect
15
+ @profile.disconnect
16
+ end
17
+
18
+ def send_message(message, reply_class=nil, &block)
19
+ package = create_bluetooth_data_package(message)
20
+ @profile.send_data_package(package)
21
+
22
+ if message.require_response?
23
+ response = receive_message
24
+
25
+ response = reply_class.new(response) unless reply_class.nil?
26
+
27
+ if block_given?
28
+ yield response
29
+ else
30
+ response
31
+ end
32
+ else
33
+ nil # return nil when no response is required
34
+ end
35
+ end
36
+
37
+ def receive_message
38
+ bluetooth_message = @profile.receive_data_package
39
+ message_parts = split_message_into_header_and_message(bluetooth_message)
40
+ convert_raw_received_message_to_bytes(message_parts[:message])
41
+ end
42
+
43
+
44
+ private
45
+ def create_bluetooth_data_package(message)
46
+ bytes = message.as_bytes
47
+ [calculate_length_lsb(bytes), calculate_length_msb(bytes)].concat(bytes)
48
+ end
49
+
50
+ def calculate_length_lsb(bytes)
51
+ # Filter to only get the least significant byte's worth (and lose anything higher)
52
+ bytes.length & 0xff
53
+ # NOTE: Since the max message length is 64 bytes, the Least Significant Byte
54
+ # should always be the actual length since it fits in one byte
55
+ end
56
+
57
+ def calculate_length_msb(bytes)
58
+ # Bit shift right by a byte, and then filter to only get one byte's worth
59
+ (bytes.length >> 8) & 0xff
60
+ # NOTE: Since the max message length is 64 bytes, the Most Significant Byte
61
+ # should always be zero since the length fits in one byte (LSB)
62
+ end
63
+
64
+ def split_message_into_header_and_message(raw_message)
65
+ { :header => raw_message[0..1],
66
+ :message => raw_message[2..-1]
67
+ }
68
+ end
69
+
70
+ def get_length_of_received_message_from_bluetooth_header(header)
71
+ # note - this moves the @profile's current position
72
+ #
73
+ # This gets the length of the received data from the header that was sent
74
+ # to us. We unpack it, as it's stored as a 16-bit Little Endian number.
75
+ #
76
+ # Reference: Appendix 1, Page 22
77
+ header.unpack('v*')[0] # first element only
78
+ end
79
+
80
+ def convert_raw_received_message_to_bytes(raw_message)
81
+ # 8-bit unsigned characters
82
+ raw_message.unpack("C*")
83
+ end
84
+
85
+ end
@@ -0,0 +1,71 @@
1
+ require 'serialport' # http://rubydoc.info/gems/serialport/1.1.0/frames
2
+
3
+ class SerialPortConnectionError < RuntimeError; end
4
+
5
+ class SerialPortProfile
6
+
7
+ def initialize(device, serial_port_connection_class=SerialPort)
8
+ raise ArgumentError.new('device must be non-nil') if device.nil?
9
+
10
+ @device = device
11
+ @connection_class = serial_port_connection_class
12
+ @connection = nil
13
+ end
14
+
15
+ def connect
16
+ establish_connection if @connection.nil?
17
+ end
18
+
19
+ def disconnect
20
+ @connection.close unless @connection.nil? || @connection.closed?
21
+ end
22
+
23
+ def send_data_package(package)
24
+ # No intelligence here, just send the package
25
+ package.each do |byte|
26
+ @connection.putc byte
27
+ end
28
+ end
29
+
30
+ def receive_data_package(max_length=(64+2))
31
+ # No intelligence here, just read the max length
32
+ # (default is 64 bytes plus 2 length bytes for bluetooth, but that is leaking abstractions)
33
+ # As long as there's SOMETHING on the wire, there will be no EOFError
34
+ @connection.sysread(max_length)
35
+ end
36
+
37
+ def settings
38
+ {
39
+ 'baud' => 57600,
40
+ 'data_bits' => 8,
41
+ 'stop_bits' => 1,
42
+ 'parity' => ::SerialPort::NONE,
43
+ 'flow_control' => ::SerialPort::HARD,
44
+ 'read_timeout' => 5000
45
+ }
46
+
47
+ end
48
+
49
+
50
+ private
51
+ def establish_connection
52
+ @connection = @connection_class.new(
53
+ @device,
54
+ settings['baud'],
55
+ settings['data_bits'],
56
+ settings['stop_bits'],
57
+ settings['parity']
58
+ )
59
+
60
+ unless @connection.nil?
61
+ set_post_connection_controls
62
+ else
63
+ raise SerialPortConnectionError, "Could not establish a SerialPortProfile connection to #{@device}"
64
+ end
65
+ end
66
+
67
+ def set_post_connection_controls
68
+ @connection.flow_control = settings['flow_control']
69
+ @connection.read_timeout = settings['read_timeout']
70
+ end
71
+ end
data/lib/nxt.rb CHANGED
@@ -1,28 +1,119 @@
1
- $:.unshift(File.dirname(__FILE__))
1
+ def should_exclude_file(filename, current_directory)
2
+ filename == File.join(current_directory, __FILE__) ||
3
+ filename == File.join(current_directory, 'telegrams', 'commands', 'direct', 'output_state.rb')
4
+ end
2
5
 
3
- require 'active_support/inflector'
6
+ current_directory = File.dirname(__FILE__)
7
+ files_to_require = Dir.glob(File.join(current_directory, '**/*.rb'))
4
8
 
5
- require 'nxt/utils/accessors'
9
+ files_to_require.each do |filename|
10
+ require filename unless should_exclude_file(filename, current_directory)
11
+ end
6
12
 
7
- require 'nxt/patches/module'
8
13
 
9
- require 'nxt/exceptions'
10
- require 'nxt/errors'
14
+ class NXT
15
+ attr_reader :device_path, :communication, :wait_for_reply
11
16
 
12
- require 'nxt/interfaces/base'
13
- require 'nxt/interfaces/usb'
14
- require 'nxt/interfaces/serial_port'
17
+ def initialize(device_path, communication=nil)
18
+ raise ArgumentError, "device_path must be non-nil" if device_path.nil?
15
19
 
16
- require 'nxt/commands/base'
17
- require 'nxt/commands/input'
18
- require 'nxt/commands/output'
19
- require 'nxt/commands/program'
20
- require 'nxt/commands/sound'
21
- require 'nxt/commands/tone'
20
+ @wait_for_reply = true
21
+ @device_path = device_path
22
+ @communication = communication || BluetoothCommunication.new(device_path)
23
+ @async = nil
24
+ end
22
25
 
23
- require 'nxt/connectors/input/color'
24
- require 'nxt/connectors/input/touch'
25
- require 'nxt/connectors/input/ultrasonic'
26
- require 'nxt/connectors/output/motor'
26
+ def connect
27
+ @communication.connect
28
+ self
29
+ end
27
30
 
28
- require 'nxt/nxt_brick'
31
+ def disconnect
32
+ @communication.disconnect
33
+ self
34
+ end
35
+
36
+ def async
37
+ @async = NXTAsync.new(@device_path, @communication) if @async.nil?
38
+ @async
39
+ end
40
+
41
+ # Direct commands
42
+ def stop_program
43
+ send_message(StopProgram.new(wait_for_reply), StopProgramReply)
44
+ end
45
+
46
+ def start_program(program_name)
47
+ send_message(StartProgram.new(program_name, wait_for_reply), StartProgramReply)
48
+ end
49
+
50
+ def get_current_program_name
51
+ # always requires a reply, so no constructor argument to allow an override
52
+ send_message(GetCurrentProgramName.new, GetCurrentProgramNameReply)
53
+ end
54
+
55
+ def stop_sound_playback
56
+ send_message(StopSoundPlayback.new(wait_for_reply), StopSoundPlaybackReply)
57
+ end
58
+
59
+ def play_sound_file(sound_filename, loop_sound=false)
60
+ send_message(PlaySoundFile.new(sound_filename, loop_sound, wait_for_reply), PlaySoundFileReply)
61
+ end
62
+
63
+ def play_tone(frequency_hz, duration_ms)
64
+ send_message(PlayTone.new(frequency_hz, duration_ms, wait_for_reply), PlayToneReply)
65
+ end
66
+
67
+ def set_input_mode(input_port, sensor_type, sensor_mode)
68
+ send_message(SetInputMode.new(input_port, sensor_type, sensor_mode, wait_for_reply), SetInputModeReply)
69
+ end
70
+
71
+ def set_output_state(output_state)
72
+ send_message(SetOutputState.new(output_state, wait_for_reply),SetOutputStateReply)
73
+ end
74
+
75
+ def get_battery_level
76
+ send_message(GetBatteryLevel.new, GetBatteryLevelReply)
77
+ end
78
+
79
+ def reset_motor_position
80
+ send_message(ResetMotorPosition.new(wait_for_reply), ResetMotorPositionReply)
81
+ end
82
+
83
+ private
84
+ def yet_to_be_implemented_method
85
+ raise NotImplementedError, "This method is not yet implemented"
86
+ end
87
+
88
+ public
89
+ [:get_output_state, :get_input_values, :reset_input_scaled_value,
90
+ :message_write, :keep_alive,
91
+ :ls_get_status, :ls_write, :ls_read,
92
+ :message_read].each do |method|
93
+ alias_method method, :yet_to_be_implemented_method
94
+ end
95
+
96
+ # System commands
97
+ def get_device_info
98
+ # always requires a reply, so no constructor argument to allow an override
99
+ send_message(GetDeviceInfo.new, GetDeviceInfoReply)
100
+ end
101
+
102
+ # Lowest-level API
103
+ def send_message(command, reply_type=nil)
104
+ @communication.send_message(command, reply_type)
105
+ end
106
+ end
107
+
108
+
109
+
110
+ class NXTAsync < NXT
111
+ def initialize(device_path, communication=nil)
112
+ super(device_path, communication)
113
+ @wait_for_reply = false
114
+ end
115
+
116
+ def async
117
+ self
118
+ end
119
+ end
@@ -0,0 +1,8 @@
1
+ {
2
+ "folders":
3
+ [
4
+ {
5
+ "path": "/Users/theupel/Projects/ruby-nxt"
6
+ }
7
+ ]
8
+ }
@@ -0,0 +1,288 @@
1
+ {
2
+ "auto_complete":
3
+ {
4
+ "selected_items":
5
+ [
6
+ [
7
+ "cla",
8
+ "cla class .. < ParentClass .. initialize .. end"
9
+ ],
10
+ [
11
+ "sen",
12
+ "sensor_mode"
13
+ ],
14
+ [
15
+ "validate_sens",
16
+ "validate_sensor_mode"
17
+ ],
18
+ [
19
+ "rep",
20
+ "no-repeat"
21
+ ],
22
+ [
23
+ "block",
24
+ "inline-block"
25
+ ],
26
+ [
27
+ "back",
28
+ "background-color"
29
+ ]
30
+ ]
31
+ },
32
+ "buffers":
33
+ [
34
+ ],
35
+ "build_system": "",
36
+ "command_palette":
37
+ {
38
+ "height": 27.0,
39
+ "selected_items":
40
+ [
41
+ [
42
+ "remov",
43
+ "Package Control: Remove Package"
44
+ ],
45
+ [
46
+ "install",
47
+ "Package Control: Install Package"
48
+ ],
49
+ [
50
+ "remove page",
51
+ "Package Control: Remove Package"
52
+ ],
53
+ [
54
+ "install pack",
55
+ "Package Control: Install Package"
56
+ ]
57
+ ],
58
+ "width": 530.0
59
+ },
60
+ "console":
61
+ {
62
+ "height": 125.0
63
+ },
64
+ "distraction_free":
65
+ {
66
+ "menu_visible": true,
67
+ "show_minimap": false,
68
+ "show_open_files": false,
69
+ "show_tabs": false,
70
+ "side_bar_visible": false,
71
+ "status_bar_visible": false
72
+ },
73
+ "file_history":
74
+ [
75
+ "/Users/theupel/Projects/ruby-nxt/lib/nxt.rb",
76
+ "/Users/theupel/Library/Application Support/Sublime Text 2/Packages/User/Preferences.sublime-settings",
77
+ "/Users/theupel/Projects/ruby-nxt/ruby-nxt.sublime-project",
78
+ "/Users/theupel/Projects/shooter/bot_console.rb",
79
+ "/Users/theupel/Projects/shooter/shooter_bot.rb",
80
+ "/Users/theupel/Downloads/com.infospace.search.Gopher-release/AndroidManifest.xml",
81
+ "/Users/theupel/Projects/ruby-nxt2/.gitignore",
82
+ "/Users/theupel/Projects/ruby-nxt2/lib/telegrams/commands/direct/set_input_mode.rb",
83
+ "/Users/theupel/Projects/ruby-nxt2/lib/telegrams/commands/direct/replies/set_input_mode_reply.rb",
84
+ "/Users/theupel/Projects/ruby-nxt2/lib/telegrams/commands/direct/replies/start_program_reply.rb",
85
+ "/Users/theupel/Projects/ruby-nxt2/spec/telegrams/commands/direct/play_tone_spec.rb",
86
+ "/Users/theupel/Projects/ruby-nxt2/lib/telegrams/commands/direct/play_tone.rb",
87
+ "/Users/theupel/Projects/ruby-nxt2/Gemfile",
88
+ "/Users/theupel/Projects/mobile/search_app_android/src/com/infospace/search/android/activities/MainActivity.java",
89
+ "/Users/theupel/Downloads/LEGO-NXT-2.00-1/lib/LEGO/NXT.pm",
90
+ "/Users/theupel/Projects/cep/site_builder/public/stylesheets/builder.css",
91
+ "/Users/theupel/Projects/cep/caprica/.foreman",
92
+ "/Users/theupel/Projects/cep/site_builder/index.html",
93
+ "/Users/theupel/Projects/cep/site_builder/stylesheets/builder.css",
94
+ "/Users/theupel/Projects/cep/site_builder/images/Info_favicon1-fav_16x16.png",
95
+ "/Users/theupel/Projects/cep/site_builder/tonys-theme.css",
96
+ "/Users/theupel/Projects/DogPack/DogPack.UnitTests/CalendarTests.cs",
97
+ "/Users/theupel/Projects/DogPack/DogPack.Engine/BasicCalendar.cs"
98
+ ],
99
+ "find":
100
+ {
101
+ "height": 35.0
102
+ },
103
+ "find_in_files":
104
+ {
105
+ "height": 0.0,
106
+ "where_history":
107
+ [
108
+ ]
109
+ },
110
+ "find_state":
111
+ {
112
+ "case_sensitive": false,
113
+ "find_history":
114
+ [
115
+ "current_directory",
116
+ "StopProgramReply",
117
+ "PlaySoundFile",
118
+ "play_sound_file",
119
+ "SetInputMode",
120
+ "StartProgramReply",
121
+ "start_program",
122
+ ".keys",
123
+ "SetInputMode",
124
+ ":four",
125
+ "duration",
126
+ "input_mode",
127
+ "500",
128
+ "frequency",
129
+ "type",
130
+ "PlayTone",
131
+ "port",
132
+ "sensor_type",
133
+ "prompt"
134
+ ],
135
+ "highlight": true,
136
+ "in_selection": false,
137
+ "preserve_case": false,
138
+ "regex": false,
139
+ "replace_history":
140
+ [
141
+ "mode",
142
+ "SetInputMode"
143
+ ],
144
+ "reverse": false,
145
+ "show_context": true,
146
+ "use_buffer2": true,
147
+ "whole_word": false,
148
+ "wrap": true
149
+ },
150
+ "groups":
151
+ [
152
+ {
153
+ "sheets":
154
+ [
155
+ ]
156
+ }
157
+ ],
158
+ "incremental_find":
159
+ {
160
+ "height": 0.0
161
+ },
162
+ "input":
163
+ {
164
+ "height": 0.0
165
+ },
166
+ "layout":
167
+ {
168
+ "cells":
169
+ [
170
+ [
171
+ 0,
172
+ 0,
173
+ 1,
174
+ 1
175
+ ]
176
+ ],
177
+ "cols":
178
+ [
179
+ 0.0,
180
+ 1.0
181
+ ],
182
+ "rows":
183
+ [
184
+ 0.0,
185
+ 1.0
186
+ ]
187
+ },
188
+ "menu_visible": true,
189
+ "output.exec":
190
+ {
191
+ "height": 124.0
192
+ },
193
+ "replace":
194
+ {
195
+ "height": 64.0
196
+ },
197
+ "save_all_on_build": true,
198
+ "select_file":
199
+ {
200
+ "height": 0.0,
201
+ "selected_items":
202
+ [
203
+ [
204
+ "lib/n",
205
+ "lib/nxt.rb"
206
+ ],
207
+ [
208
+ "shooter_",
209
+ "shooter_bot.rb"
210
+ ],
211
+ [
212
+ "bot",
213
+ "bot_console.rb"
214
+ ],
215
+ [
216
+ "ns",
217
+ "spec/nxt_spec.rb"
218
+ ],
219
+ [
220
+ "sprs",
221
+ "spec/telegrams/commands/direct/replies/start_program_reply_spec.rb"
222
+ ],
223
+ [
224
+ "spr",
225
+ "lib/telegrams/commands/direct/replies/start_program_reply.rb"
226
+ ],
227
+ [
228
+ "pts",
229
+ "spec/telegrams/commands/direct/play_tone_spec.rb"
230
+ ],
231
+ [
232
+ "play_ton",
233
+ "lib/telegrams/commands/direct/play_tone.rb"
234
+ ],
235
+ [
236
+ "nxt",
237
+ "lib/nxt.rb"
238
+ ],
239
+ [
240
+ "mainact",
241
+ "src/com/infospace/search/android/activities/MainActivity.java"
242
+ ],
243
+ [
244
+ "ser",
245
+ "new/lib/communication/serial_port_profile.rb"
246
+ ],
247
+ [
248
+ "seri",
249
+ "new/lib/communication/serial_port_profile.rb"
250
+ ],
251
+ [
252
+ "serial_",
253
+ "new/spec/communication/serial_port_profile_spec.rb"
254
+ ],
255
+ [
256
+ ".fore",
257
+ "caprica/.foreman"
258
+ ],
259
+ [
260
+ "inde",
261
+ "site_builder/public/index.html"
262
+ ],
263
+ [
264
+ "cal",
265
+ "DogPack.UnitTests/CalendarTests.cs"
266
+ ]
267
+ ],
268
+ "width": 0.0
269
+ },
270
+ "select_project":
271
+ {
272
+ "height": 500.0,
273
+ "selected_items":
274
+ [
275
+ [
276
+ "",
277
+ "/Users/theupel/Projects/ruby-nxt/lib/ruby-nxt.sublime-project"
278
+ ]
279
+ ],
280
+ "width": 380.0
281
+ },
282
+ "show_minimap": false,
283
+ "show_open_files": false,
284
+ "show_tabs": true,
285
+ "side_bar_visible": false,
286
+ "side_bar_width": 150.0,
287
+ "status_bar_visible": true
288
+ }