2525parser .add_argument ('--udp' , action = "store" , required = False , type = str , help = "Surveyor IP:Port. E.g: 192.168.2.86:62312" )
2626parser .add_argument ('--tcp' , action = "store" , required = False , type = str , help = "Surveyor IP:Port. E.g: 192.168.2.86:62312" )
2727parser .add_argument ('--range' , action = "store" , required = False , type = str , help = "Set range. E.g: 5000 or 0:5000" )
28- parser .add_argument ('--log' , action = "store" , nargs = '?' , const = True , type = str , help = "Log filename or folder name . Will log if it doesn't exist, or replay all packets inside directory if it does. Left blank creates new log ." )
28+ parser .add_argument ('--log' , action = "store" , nargs = '?' , const = True , type = str , help = "Log filename and/ or directory path . Will create new log if blank or directory is specified. Will replay if file is specified and exists ." )
2929args = parser .parse_args ()
3030if args .device is None and args .udp is None and args .tcp is None and args .log is None :
3131 parser .print_help ()
@@ -45,37 +45,60 @@ def signal_handler(sig, frame):
4545
4646signal .signal (signal .SIGINT , signal_handler )
4747
48- # Make a new Surveyor240
49- mySurveyor240 = Surveyor240 ()
50- if args .device is not None :
51- mySurveyor240 .connect_serial (args .device , args .baudrate )
52- elif args .udp is not None :
53- (host , port ) = args .udp .split (':' )
54- mySurveyor240 .connect_udp (host , int (port ))
55- elif args .tcp is not None :
56- (host , port ) = args .tcp .split (':' )
57- mySurveyor240 .connect_tcp (host , int (port ))
58-
59- # Check for log argument
60- # If no log is specified, create one using date and time
61- # If a log is specified, existing log will be opened
48+ # Check for log argument and make new Surveyor240
49+ # If no .svlog is specified, create one using default directory
50+ # If directory specified, .svlog be created in specified directory
51+ # If a .svlog is specified, existing log will be opened
6252new_log = False
63- new_folder_name = None
53+ log_path = ""
54+ replay_path = None
55+ default_dir = Path ("logs/surveyor" ).resolve ()
6456if args .log is not None :
6557 if args .log is True :
58+ # Logging to default directory
59+ default_dir .mkdir (parents = True , exist_ok = True )
60+ mySurveyor240 = Surveyor240 (logging = True , log_directory = default_dir )
61+ print (f"Logging to new file in: { default_dir } " )
6662 new_log = True
6763 elif isinstance (args .log , str ):
68- log_path = os .path .join ("logs/surveyor" , args .log )
69- if args .log .endswith (".txt" ):
70- new_log = False
71- elif os .path .exists (log_path ):
72- print (f"Replaying from existing log folder: { log_path } " )
73- new_log = False
74- else :
75- new_folder_name = args .log
64+ log_path = Path (args .log ).expanduser ()
65+
66+ if log_path .suffix == ".svlog" and log_path .parent == Path ("." ):
67+ log_path = default_dir / log_path .name
68+
69+ log_path = log_path .resolve ()
70+
71+ if log_path .suffix == ".svlog" :
72+ if log_path .exists () and log_path .is_file ():
73+ # File exists, replaying
74+ new_log = False
75+ mySurveyor240 = Surveyor240 (logging = False )
76+ replay_path = log_path
77+ print (f"Replaying from: { replay_path } " )
78+ else :
79+ raise FileNotFoundError (f"Log file not found: { log_path } " )
80+
81+ elif log_path .is_dir () or log_path .suffix == "" :
82+ # Path is directory, logging to that directory
83+ mySurveyor240 = Surveyor240 (logging = True , log_directory = log_path )
84+ print (f"Logging to new file: { Surveyor240 .current_log } " )
7685 new_log = True
86+
87+ else :
88+ raise ValueError (f"Invalid log argument: { args .log } " )
89+ else :
90+ mySurveyor240 = Surveyor240 ()
7791
7892if args .log is None or new_log :
93+ if args .device is not None :
94+ mySurveyor240 .connect_serial (args .device , args .baudrate )
95+ elif args .udp is not None :
96+ (host , port ) = args .udp .split (':' )
97+ mySurveyor240 .connect_udp (host , int (port ))
98+ elif args .tcp is not None :
99+ (host , port ) = args .tcp .split (':' )
100+ mySurveyor240 .connect_tcp (host , int (port ))
101+
79102 if mySurveyor240 .initialize () is False :
80103 print ("Failed to initialize Surveyor240!" )
81104 exit (1 )
@@ -87,37 +110,55 @@ def signal_handler(sig, frame):
87110
88111input ("Press Enter to continue..." )
89112
90- # Running Surveyor240 from existing log file
113+ # Running surveyor240Example.py from existing log file
91114if args .log is not None and not new_log :
92- log_path = Path ("logs/surveyor" ) / args .log
93- if not log_path .exists ():
94- print (f"Log path does not exist: { log_path } " )
95- sys .exit (1 )
96-
97- if log_path .is_dir ():
98- for file in sorted (log_path .iterdir ()):
99- if file .suffix == ".txt" :
100- print (f"\n ---------Replaying File: { file .name } ---------" )
101- with open (file , 'rb' ) as f :
102- raw_bytes = f .read ()
103- data = PingMessage (msg_data = raw_bytes )
104-
105- if data :
106- print (data )
107- else :
108- print ("Failed to get report" )
109- elif log_path .is_file ():
110- print (f"\n ---------Replaying File: { log_path .name } ---------" )
111- with open (log_path , 'rb' ) as f :
112- raw_bytes = f .read ()
113- data = PingMessage (msg_data = raw_bytes )
114-
115- if data :
116- print (data )
117- else :
118- print ("Failed to get report" )
119- else :
120- print (f"Invalid log path: { log_path } " )
115+ with open (log_path , 'rb' ) as f :
116+ while True :
117+ data = Surveyor240 .read_packet (f )
118+
119+ if data == None :
120+ break # EOF or bad packet
121+
122+ # print(f"ID: {data.message_id}\tName: {data.name}")
123+
124+ ## Surveyor will report the Water Stats packet if temperature and/or pressure sensor is connected
125+ # if data.message_id == definitions.SURVEYOR240_WATER_STATS:
126+ # print(f"Temperature: {(data.temperature * 9/5) + 32} F")
127+ # print(f"Temperature: {data.temperature} C")
128+ # print(f"Pressure: {data.pressure} bar")
129+
130+ if data .message_id == definitions .SURVEYOR240_ATTITUDE_REPORT :
131+ # Print pitch and roll data
132+ vector = (data .up_vec_x , data .up_vec_y , data .up_vec_z )
133+ pitch = math .asin (vector [0 ])
134+ roll = math .atan2 (vector [1 ], vector [2 ])
135+ print (f"Pitch: { pitch } \t Roll: { roll } " )
136+
137+ # if data.message_id == definitions.SURVEYOR240_YZ_POINT_DATA:
138+ # # Display YZ point data in a table
139+ # yz_data = Surveyor240.create_yz_point_data(data)
140+ # print(f"Length of yz_data: {len(yz_data)}\tNum_points: {data.num_points}")
141+ # print("Index\tY\tZ")
142+ # for i in range(0, len(yz_data), 2):
143+ # print(f"{i//2}\t{yz_data[i]:.2f}\t{yz_data[i+1]:.2f}")
144+ # print(f"Temperature: {(data.water_degC * 9/5) + 32} F")
145+ # print(f"Temperature: {data.water_degC} C")
146+ # print(f"Pressure: {data.water_bar} Bar")
147+
148+ # if data.message_id == definitions.SURVEYOR240_ATOF_POINT_DATA:
149+ # # Just an example packet, could check for other packet types and
150+ # # show results from those too
151+
152+ # # Use create_atof_list to get formatted atof_t[num_points] list
153+ # atof_data = Surveyor240.create_atof_list(data)
154+ # if len(atof_data) == 0:
155+ # continue
156+ # else:
157+ # # Just the first data point in atof[]
158+ # distance = 0.5 * data.sos_mps * atof_data[0].tof
159+ # y = distance * math.sin(atof_data[0].angle)
160+ # z = -distance * math.cos(atof_data[0].angle)
161+ # print(f"Distance: {distance:.3f} meters\tY: {y:.3f}\tZ: {z:.3f}\t{atof_data[0]}")
121162
122163# Connected to physical Surveyor
123164else :
@@ -155,94 +196,27 @@ def signal_handler(sig, frame):
155196 )
156197
157198 if new_log :
158- if new_folder_name is None :
159- log_folder_name = datetime .now ().strftime ("%Y-%m-%d_%H-%M-%S" )
160- else :
161- log_folder_name = new_folder_name
162- log_path = os .path .join ("logs/surveyor" , log_folder_name )
163- os .makedirs (log_path , exist_ok = True )
164- print (f"Logging new files in: { log_path } " )
165-
166- print ("\n ---------Attitude Report---------" )
167- while True :
168- data = mySurveyor240 .wait_message ([definitions .SURVEYOR240_ATTITUDE_REPORT ])
169- if data :
170- # Create new log if specified
171- if new_log :
172- attitude_data_path = os .path .join (log_path , "Attitude_Report.txt" )
173- with open (attitude_data_path , 'ab' ) as f :
174- f .write (data .msg_data )
175-
176- # Print pitch and roll data
177- vector = (data .up_vec_x , data .up_vec_y , data .up_vec_z )
178- pitch = math .asin (vector [0 ])
179- roll = math .atan2 (vector [1 ], vector [2 ])
180- print (f"Pitch: { pitch } \t Roll: { roll } " )
181- break
182- else :
183- print ("Failed to get attitude report" )
184- time .sleep (0.1 )
185-
186- print ("\n ---------ATOF Point Data---------" )
187- while True :
188- data = mySurveyor240 .wait_message ([definitions .SURVEYOR240_ATOF_POINT_DATA ])
189- if data :
190- if new_log :
191- atof_data_path = os .path .join (log_path , "ATOF_Point_Data.txt" )
192- with open (atof_data_path , 'ab' ) as f :
193- f .write (data .msg_data )
194-
195- # Use create_atof_list to get formatted atof_t[num_points] list
196- atof_data = Surveyor240 .create_atof_list (data )
197- if len (atof_data ) == 0 :
198- continue
199- else :
200- for i in range (len (atof_data )):
201- distance = 0.5 * data .sos_mps * atof_data [i ].tof
202- y = distance * math .sin (atof_data [i ].angle )
203- z = - distance * math .cos (atof_data [i ].angle )
204- print (f"{ i } .\t Distance: { distance :.3f} meters\t Y: { y :.3f} \t Z: { z :.3f} \t { atof_data [i ]} " )
205- break
206- else :
207- print ("Failed to get atof point data" )
208-
209- print ("\n ---------YZ Point Data---------" )
210- while True :
211- data = mySurveyor240 .wait_message ([definitions .SURVEYOR240_YZ_POINT_DATA ])
212- if data :
213- if new_log :
214- yz_data_path = os .path .join (log_path , "YZ_Point_Data.txt" )
215- with open (yz_data_path , 'ab' ) as f :
216- f .write (data .msg_data )
217-
218- # Display YZ point data in a table
219- yz_data = Surveyor240 .create_yz_point_data (data )
220- print (f"Length of yz_data: { len (yz_data )} \t Num_points: { data .num_points } " )
221- print ("Index\t Y\t Z" )
222- for i in range (0 , len (yz_data ), 2 ):
223- print (f"{ i // 2 } \t { yz_data [i ]:.2f} \t { yz_data [i + 1 ]:.2f} " )
224- print (f"Temperature: { (data .water_degC * 9 / 5 ) + 32 } F" )
225- print (f"Temperature: { data .water_degC } C" )
226- print (f"Pressure: { data .water_bar } Bar" )
227- break
228- else :
229- print ("Failed to get yz point data" )
230-
231- print ("\n ---------Water Stats---------" )
232- while True :
233- data = mySurveyor240 .wait_message ([definitions .SURVEYOR240_WATER_STATS ])
234- if data :
235- if new_log :
236- water_stats_path = os .path .join (log_path , "Water_Stats.txt" )
237- with open (water_stats_path , 'ab' ) as f :
238- f .write (data .msg_data )
239-
240- print (f"Temperature: { (data .temperature * 9 / 5 ) + 32 } F" )
241- print (f"Temperature: { data .temperature } C" )
242- print (f"Pressure: { data .pressure } bar" )
243- break
244- else :
245- print ("Failed to get water stats data" )
199+ print ("Logging...\n CTRL+C to stop logging" )
200+ else :
201+ print ("CTRL-C to end program..." )
202+ try :
203+ while True :
204+ # Set multiple packets to listen for
205+ data = mySurveyor240 .wait_message ([definitions .SURVEYOR240_ATOF_POINT_DATA ,
206+ definitions .SURVEYOR240_ATTITUDE_REPORT ,
207+ definitions .SURVEYOR240_YZ_POINT_DATA ,
208+ definitions .SURVEYOR240_WATER_STATS ])
209+
210+ ## To watch pitch and roll data in real time while recording, uncomment this block
211+ # if data.message_id == definitions.SURVEYOR240_ATTITUDE_REPORT:
212+ # # Print pitch and roll data
213+ # vector = (data.up_vec_x, data.up_vec_y, data.up_vec_z)
214+ # pitch = math.asin(vector[0])
215+ # roll = math.atan2(vector[1], vector[2])
216+ # print(f"Pitch: {pitch}\tRoll: {roll}")
217+
218+ except KeyboardInterrupt :
219+ print ("Stopping logging..." )
246220
247221 # Stop pinging from Surveyor
248222 mySurveyor240 .control_set_ping_parameters (ping_enable = False )
0 commit comments