Debugging and Data Analysis

In robotic applications there are several types of problems that require debugging. It is very common to have a need for program debugging, but also once the program is operational, there is often a need for evaluation algorithm performance. This tutorial makes extensive use of Linux commands, therefore may only work in this operating system. However, it could serve as a guideline for a solution that Windows users can implement. Users should install Octave that is used as the main plotting program. The programs should also work in Matlab.

Program Debugging
Debugging the program itself is often needed, for example in order to verify that and algorithm or a function is properly implemented. This type of problems can be addressed using a debugger such as gdb and in many cases even printing some intermediate results on the screen.

Algorithm Performance Evaluation
Verifying an algorithm performance is somewhat more difficult, especially if the algorithm involves checking multiple sensor outputs at the same time. Many programs use involved graphical user interfaces to accomplish this task. Luckily, there are a couple of alternatives that can be applied and are simple, yet very powerful.
As we have seen, it is possible to start a ssh-server (dropbear) in the EV3 brick, which allows transferring to(scp) and running programs in (ssh) the EV3 brick. There is yet another use for use for the ssh program, it can be used to execute a remote command (i.e. in EV3 brick), while still using the local resources (i.e. a PC). Before using this method, it is necessary to create a shell program that will execute a series of instructions on the EV3. The following file named “run_main.sh” can be used for this purpose, it must be copied in the /media/card directory:

#!/bin/bash
export LD_LIBRARY_PATH="/media/card/lib:$LD_LIBRARY_PATH"
cd /media/card
./main

The first instruction makes the dynamic libraries available. Then, it moves to the /media/card directory and finally executes the main program.

Offline Data Analysis
The immediate use of the ssh command is log all the program output data in a log file, which can be latter parsed and separated in the different variables. The ssh command can be used to execute the “run_main.sh” shell program remotely and log the data at the same time in the local computer. On the computer side call the following command (use your EV3 IP address).

ssh -t root@192.168.43.114 'sh /media/card/run_main.sh' > data.log

The “-t” flag indicates that the user may use the local keyboard and the “sh /media/card/run_main.sh” instruction will execute shell program. Finally the “> data.log” instructs the operating system to store the data in the log file. This setup allows running an algorithm and storing all the system states that for offline processing. The following octave file can be used to process the data log file and show an animation of the robot trajectory. This program was designed to read the position X and Y coordinates of the robot as well as the heading, and make a plot of the path and current robot heading. It could be modified to display any other signals.

%PLOT_OFFLINE.M
%Plotting constants
HEADING_LINE = 50; %[mm]
%Runtime variables
robot_path = []; % will store all the x_pos and y_pos positions
%Create a new figure a define the plot handlers for the robot path and heading
figure;
hold on;grid on;axis equal;
plt_robot_path = plot(0,0,'Color',[0,.5,0]);
plt_heading = line([0,0],[0,0],'Color','k','LineWidth',3);
xlabel('X [mm]');
ylabel('Y [mm]');
%Drawing path loop
system(' grep POSITION data.log | sed s/.*POSITION.*://g > data.tmp');
fid = fopen('data.tmp', 'r');
while (1)
	%Read data from file
	log_line = fgetl(fid);
	if(log_line== -1) 
		break;
	end;
	[data] = sscanf(log_line,' %f ', [1,5]);
	x_pos = data(end,1);
	y_pos = data(end,2);
	heading = data(end,3) * pi/180;
	%Update path
	robot_path = [robot_path; [x_pos, y_pos]];
	set(plt_robot_path, 'XData', robot_path(:,1), 'YData', robot_path(:,2));
	set(plt_heading, 'XData', [x_pos, x_pos + HEADING_LINE * cos(heading)], 'YData', [y_pos,y_pos + HEADING_LINE * sin(heading)]);
	drawnow;
end
fclose(fid);

The key part in this program is the system call that runs a a combination of Linux commands:

tail -n 15 data.log | grep POSITION | sed s/.*POS.*://g > data.tmp;

The instruction “grep POSITION data.log” selects only the lines containing the word POSITION. Next “sed s/.*POSITION.*://g” eliminates the non-numerical part of the line containing the position information. Finally, “> data.tmp” stores the result in a temporary file. After this, the temporary file can be read using octave commands and displayed on the screen as shown below.
lego_ev3_octave_ssh_plot

Real-Time Data Analysis
In certain cases, off-line data analysis will not be enough, since certain problems can only be reproduced or observed while the robot performs an action (real-time). For this cases, it is possible to run a modified version of the octave program that reads the data log file while it is still been created. In other words, we need to run the octave program while the ssh command is still running. The easiest way to accomplish this is by using two terminal windows.
Lego_Ev3_remote_data_visualization
The following octave program is used in this example:

%PLOT_REALTIME.M
%Plotting constants
HEADING_LINE = 50; %[mm]
DELAY = 0.1; %[s]
%Runtime variables
robot_path = []; % will store all the x_pos and y_pos positions
%Create a new figure a define the plot handlers for the robot path and heading
figure;
hold on;grid on;axis equal;
plt_robot_path = plot(0,0,'Color',[0,.5,0]);
plt_heading = line([0,0],[0,0],'Color','k','LineWidth',3);
xlabel('X [mm]');
ylabel('Y [mm]');
%Drawing path loop
while (1)
	pause(DELAY);
	%Read data from file
	system(' tail -n 15 data.log | grep POSITION | sed s/.*POSITION.*://g > data.tmp');
	fid = fopen('data.tmp', 'r');
	log_line = fgetl(fid);
	if(log_line == -1) 
		continue; %did not have any data
	end;
	fclose(fid);
	[data] = sscanf(log_line,' %f ', [1, 5]);
	x_pos = data(end,1);
	y_pos = data(end,2);
	heading = data(end,3) * pi/180;
	%Update path
	robot_path = [robot_path; [x_pos, y_pos]];
	set(plt_robot_path, 'XData', robot_path(:,1), 'YData', robot_path(:,2));
	set(plt_heading, 'XData', [x_pos, x_pos + HEADING_LINE * cos(heading)], 'YData' ,[y_pos,y_pos + HEADING_LINE * sin(heading)]);
	drawnow;
end

Notice that we introduce another system instruction, “tail -n 15 data.log”, which reads only the last 15 lines of the log file. This should give enough information about the last state of the robot.

The following video demonstrates the real-time data visualization method. The position is computed using the gyro-enhanced method with a Microinfinity XG1300L sensor :