nxt 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }