Skip to content

Commit

Permalink
Merge pull request #632 from retiutut/development
Browse files Browse the repository at this point in the history
4.1.7-beta.0
  • Loading branch information
retiutut authored Nov 7, 2019
2 parents 48c3d15 + 7dd5af5 commit fa3e1ca
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 108 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# v4.1.7
Use OpenBCIHub v2.1.0 please.

## Beta 0

### Improvements
* Dropped Packet Interpolation!
* Make UDPx3 default Transfer protocol Cyton+Wifi

### Bug Fixes
* Playback mode update and bug fixes #633
* Update channelSelect in BandPower and SSVEP widgets when new playback file is loaded

# v4.1.6
Use OpenBCIHub v2.1.0 please.

Expand Down
48 changes: 24 additions & 24 deletions OpenBCI_GUI/ControlPanel.pde
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ public void controlEvent(ControlEvent theEvent) {
latencyCyton10ms.setColorNotPressed(isSelected_color);
latencyCyton20ms.setColorNotPressed(colorNotPressed);
hub.setLatency(LATENCY_10_MS);
wifiInternetProtocolCytonTCP.setColorNotPressed(isSelected_color);
wifiInternetProtocolCytonTCP.setColorNotPressed(colorNotPressed);
wifiInternetProtocolCytonUDP.setColorNotPressed(colorNotPressed);
wifiInternetProtocolCytonUDPBurst.setColorNotPressed(colorNotPressed);
hub.setWifiInternetProtocol(TCP);
wifiInternetProtocolCytonUDPBurst.setColorNotPressed(isSelected_color);
hub.setWifiInternetProtocol(UDP_BURST);
hub.setWiFiStyle(WIFI_DYNAMIC);
wifiIPAddressDynamic.setColorNotPressed(isSelected_color);
wifiIPAddressStatic.setColorNotPressed(colorNotPressed);
Expand Down Expand Up @@ -249,32 +249,32 @@ public void controlEvent(ControlEvent theEvent) {
}
}

//Check for event in PlaybackHistory Widget MenuList
if (eegDataSource == DATASOURCE_PLAYBACKFILE) {
if(theEvent.isFrom("playbackMenuList")) {
//Check to make sure value of clicked item is in valid range. Fixes #480
float valueOfItem = theEvent.getValue();
if (valueOfItem < 0 || valueOfItem > (((MenuList)theEvent.getController()).items.size() - 1) ) {
//println("CP: No such item " + value + " found in list.");
} else {
Map m = ((MenuList)theEvent.getController()).getItem(int(valueOfItem));
//println("got a menu event from item " + value + " : " + m);
userSelectedPlaybackMenuList(m.get("copy").toString(), int(valueOfItem));
}
//Check for event in PlaybackHistory Dropdown List in Control Panel
if (theEvent.isFrom("recentFiles")) {
int s = (int)(theEvent.getController()).getValue();
//println("got a menu event from item " + s);
String filePath = controlPanel.recentPlaybackBox.longFilePaths.get(s);
if (new File(filePath).isFile()) {
playbackFileSelected(filePath, s);
} else {
outputError("Playback History: Selected file does not exist. Try another file or clear settings to remove this entry.");
}
}

//Check control events from widgets
if (systemMode >= SYSTEMMODE_POSTINIT) {
//Check for event in PlaybackHistory Dropdown List in Control Panel
if (theEvent.isFrom("recentFiles")) {
int s = (int)(theEvent.getController()).getValue();
//println("got a menu event from item " + s);
String filePath = controlPanel.recentPlaybackBox.longFilePaths.get(s);
if (new File(filePath).isFile()) {
playbackFileSelected(filePath, s);
} else {
outputError("Playback History: Selected file does not exist. Try another file or clear settings to remove this entry.");
//Check for event in PlaybackHistory Widget MenuList
if (eegDataSource == DATASOURCE_PLAYBACKFILE) {
if(theEvent.isFrom("playbackMenuList")) {
//Check to make sure value of clicked item is in valid range. Fixes #480
float valueOfItem = theEvent.getValue();
if (valueOfItem < 0 || valueOfItem > (((MenuList)theEvent.getController()).items.size() - 1) ) {
//println("CP: No such item " + value + " found in list.");
} else {
Map m = ((MenuList)theEvent.getController()).getItem(int(valueOfItem));
//println("got a menu event from item " + value + " : " + m);
userSelectedPlaybackMenuList(m.get("copy").toString(), int(valueOfItem));
}
}
}
//Check for event in band power channel select checkBoxes, if needed
Expand Down
2 changes: 1 addition & 1 deletion OpenBCI_GUI/DataLogging.pde
Original file line number Diff line number Diff line change
Expand Up @@ -1548,7 +1548,7 @@ void convert8channelLine() {
}
}
dataWriter.println();
println(consoleMsg);
println("convert8channelLine: " + consoleMsg);
return;
}
for (int i=0; i<hexNums.length; i++) {
Expand Down
15 changes: 9 additions & 6 deletions OpenBCI_GUI/DataProcessing.pde
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,21 @@ void process_input_file() throws Exception {
try {
while (!hasRepeated) {
currentTableRowIndex = getPlaybackDataFromTable(playbackData_table, currentTableRowIndex, cyton.get_scale_fac_uVolts_per_count(), cyton.get_scale_fac_accel_G_per_count(), dataPacketBuff[lastReadDataPacketInd]);
if (!curTimestamp.equals("null")) {
if (curTimestamp != null) {
index_of_times.put(indices, curTimestamp.substring(1)); //remove white space from timestamp
} else {
index_of_times.put(indices, "notFound");
}
indices++;
}
println("number of indexes "+indices);
println("Finished filling hashmap");
has_processed = true;
}
catch (Exception e) {
e.printStackTrace();
throw new Exception();
}
println("number of indexes "+indices);
println("Finished filling hashmap");
has_processed = true;
}

/*************************/
Expand Down Expand Up @@ -308,14 +311,14 @@ int getPlaybackDataFromTable(Table datatable, int currentTableRowIndex, float sc
}
}
// if available, get time stamp for use in playback
if (row.getColumnCount() == nchan + NUM_ACCEL_DIMS + 2) {
if (row.getColumnCount() >= nchan + NUM_ACCEL_DIMS + 2) {
try{
if (!isOldData) curTimestamp = row.getString(row.getColumnCount() - 1);
} catch (ArrayIndexOutOfBoundsException e) {
println("Data does not exist... possibly an old file.");
}
} else {
curTimestamp = "null";
curTimestamp = "-1";
}
} //end else
return currentTableRowIndex;
Expand Down
4 changes: 2 additions & 2 deletions OpenBCI_GUI/Info.plist.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<key>CFBundleShortVersionString</key>
<string>4</string>
<key>CFBundleVersion</key>
<string>4.1.6</string>
<string>4.1.7-beta.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>NSHumanReadableCopyright</key>
Expand All @@ -32,7 +32,7 @@
Copyright © 2019 OpenBCI
</string>
<key>CFBundleGetInfoString</key>
<string>September 2019</string>
<string>November 2019</string>
<!-- End of the set that can be customized -->

@@jvm_runtime@@
Expand Down
12 changes: 10 additions & 2 deletions OpenBCI_GUI/Interactivity.pde
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,15 @@ void parseKey(char val) {
output("Screenshot captured! Saved to /Documents/OpenBCI_GUI/Screenshots/" + picfname);
saveFrame(settings.guiDataPath + "Screenshots" + System.getProperty("file.separator") + picfname); // take a shot of that!
break;

/*
//Used for testing marker mode
case 'M':
if (eegDataSource == DATASOURCE_CYTON) {
hub.sendCommand("`9");
println("Cyton: Setting a Marker +++++");
}
break;
*/
default:
if (eegDataSource == DATASOURCE_CYTON) {
println("Interactivity: '" + key + "' Pressed...sending to Cyton...");
Expand Down Expand Up @@ -868,7 +876,7 @@ void openURLInBrowser(String _url){
output("Attempting to use your default browser to launch: " + _url);
}
catch (java.io.IOException e) {
println(e.getMessage());
//println(e.getMessage());
println("Error launching url in browser: " + _url);
}
}
Expand Down
6 changes: 4 additions & 2 deletions OpenBCI_GUI/OpenBCI_GUI.pde
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import gifAnimation.*; //for animated gifs
import java.lang.reflect.*; // For callbacks
import java.io.InputStreamReader; // For input
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.FileNotFoundException;
import java.awt.MouseInfo;
import java.lang.Process;
import java.text.DateFormat; //Used in DataLogging.pde
Expand All @@ -56,8 +58,8 @@ import com.sun.jna.Pointer;
// Global Variables & Instances
//------------------------------------------------------------------------
//Used to check GUI version in TopNav.pde and displayed on the splash screen on startup
String localGUIVersionString = "v4.1.6";
String localGUIVersionDate = "September 2019";
String localGUIVersionString = "v4.1.7-beta.0";
String localGUIVersionDate = "November 2019";
String guiLatestReleaseLocation = "https://github.com/OpenBCI/OpenBCI_GUI/releases/latest";
Boolean guiVersionCheckHasOccured = false;
DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
Expand Down
15 changes: 10 additions & 5 deletions OpenBCI_GUI/W_BandPower.pde
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,7 @@ class W_BandPower extends Widget {
}
);

//Activate all channel checkboxes by default for this widget
for (int i = 0; i < nchan; i++) {
bpChanSelect.checkList.activate(i);
bpChanSelect.activeChan.add(i);
}

} //end of constructor

void update() {
Expand Down Expand Up @@ -149,4 +145,13 @@ class W_BandPower extends Widget {
bp_plot.setOuterDim(w, h + navHeight);
}
}

void activateAllChannels() {
bpChanSelect.activeChan.clear();
//Activate all channel checkboxes by default for this widget
for (int i = 0; i < nchan; i++) {
bpChanSelect.checkList.activate(i);
bpChanSelect.activeChan.add(i);
}
}
};
1 change: 1 addition & 0 deletions OpenBCI_GUI/W_Networking.pde
Original file line number Diff line number Diff line change
Expand Up @@ -1519,6 +1519,7 @@ class Stream extends Thread {
} else if (this.protocol.equals("LSL")) {
float[] _dataToSend = new float[numChan * 125];
for (int i = 0; i < numChan; i++) {
//EEG/FFT readings above 125Hz don't typically travel through the skull
for (int j = 0; j < 125; j++) {
_dataToSend[j+125*i] = fftBuff[i].getBand(j);
}
Expand Down
76 changes: 67 additions & 9 deletions OpenBCI_GUI/W_Playback.pde
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,12 @@ void playbackFileSelected (String longName, String shortName) {
processNewPlaybackFile();
if (playbackFileIsEmpty) return;
//Determine the number of channels
determineNumChanFromFile(playbackData_table);
if (playbackData_table != null) {
determineNumChanFromFile(playbackData_table);
} else {
outputError("playbackFileSelected: Data table appears to be null! Please submit an issue on GitHub!");
return;
}
//Output new playback settings to GUI as success
outputSuccess("You have selected \""
+ shortName + "\" for playback. "
Expand Down Expand Up @@ -335,19 +340,66 @@ void initPlaybackFileToTable() { //also used in OpenBCI_GUI.pde on system start
//open and load the data file
println("OpenBCI_GUI: initSystem: loading playback data from " + playbackData_fname);
playbackFileIsEmpty = false; //reset this flag each time playback data is loaded
boolean errorLoadingTable = false;

errorLoadingTable = loadTableFromCSV();

//Sometimes the SD card converted files have blank space at the end, remove it and try to connect again
if (errorLoadingTable) {
println("initPlaybackFileToTable: Deleting last line of file and trying again...");
try {
RandomAccessFile f = new RandomAccessFile(playbackData_fname, "rw");
long length = f.length() - 1;
byte b;
do {
length -= 1;
f.seek(length);
b = f.readByte();
} while (b != 10 && length > 0);
f.setLength(length+1);
f.close();
errorLoadingTable = loadTableFromCSV();
} catch (FileNotFoundException e) {
println("initPlaybackFileToTable: Unable to locate file : " + playbackData_fname);
} catch (IOException e) {
println("initPlaybackFileToTable: Unable to locate file : " + playbackData_fname);
}
}

//If we are still unable to load data into a table from file, exit method
if (errorLoadingTable) {
return;
}

try {
int rowCount = playbackData_table.getRowCount();
int fileDurationInSeconds = round(float(playbackData_table.getRowCount())/getSampleRateSafe());
println("OpenBCI_GUI: initSystem: loading complete. "
+ rowCount
+ " rows of data, which is "
+ fileDurationInSeconds
+ " seconds of EEG data");

//If a playback file has less than one second of data, throw an error using a flag
if (playbackData_table.getRowCount() <= settings.minNumRowsPlaybackFile) {
playbackFileIsEmpty = true;
}
} catch (NullPointerException e) {
println("initPlaybackFileToTable: Encountered an error - " + e);
e.printStackTrace();
}
}

boolean loadTableFromCSV () {
try {
playbackData_table = null;
playbackData_table = new Table_CSV(playbackData_fname);
//removing first column of data from data file...the first column is a time index and not eeg data
playbackData_table.removeColumn(0);
return false;
} catch (Exception e) {
println("initPlaybackFileToTable: Encountered an error while loading " + playbackData_fname);
}

println("OpenBCI_GUI: initSystem: loading complete. " + playbackData_table.getRowCount() + " rows of data, which is " + round(float(playbackData_table.getRowCount())/getSampleRateSafe()) + " seconds of EEG data");

//If a playback file has less than one second of data, throw an error using a flag
if (playbackData_table.getRowCount() <= settings.minNumRowsPlaybackFile) {
playbackFileIsEmpty = true;
return true;
}
}

Expand All @@ -365,6 +417,7 @@ void haltLoadingFile(String _filePath) {
outputError("Playback file appears empty. Try loading a different file.");
}

//This gets called when a playback file is selected from the Playback History Widget
void reinitializeCoreDataAndFFTBuffer() {
//println("Data Processing Number of Channels is: " + dataProcessing.nchan);
dataProcessing.nchan = nchan;
Expand Down Expand Up @@ -397,7 +450,12 @@ void reinitializeCoreDataAndFFTBuffer() {
//Update the number of channels for HeadPlot
w_headPlot.headPlot = null;
w_headPlot.updateHeadPlot(nchan);


//Update channelSelect in bandPower and SSVEP widgets
w_bandPower.bpChanSelect.createCheckList(nchan);
w_bandPower.activateAllChannels();
w_ssvep.ssvepChanSelect.createCheckList(nchan);
w_ssvep.activateDefaultChannels();
}

void savePlaybackFileToHistory(String fileName) {
Expand Down
34 changes: 19 additions & 15 deletions OpenBCI_GUI/W_SSVEP.pde
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,7 @@ class W_SSVEP extends Widget {
s = w;
}

//Activate default channels
numActiveChannels = 2;
int firstChan;
int secondChan;
if (nchan == 4) {
firstChan = 2;
secondChan = 3;
} else {
firstChan = 6;
secondChan = 7;
}
ssvepChanSelect.checkList.activate(firstChan);
ssvepChanSelect.checkList.activate(secondChan);
ssvepChanSelect.activeChan.add(firstChan);
ssvepChanSelect.activeChan.add(secondChan);
activateDefaultChannels();

cp5_ssvep.setAutoDraw(false);
showAbout = false; //set Default start value for showing about section as fault
Expand Down Expand Up @@ -324,6 +310,24 @@ class W_SSVEP extends Widget {
}
}

void activateDefaultChannels() {
//Activate default channels
numActiveChannels = 2;
int firstChan;
int secondChan;
if (nchan == 4) {
firstChan = 2;
secondChan = 3;
} else {
firstChan = 6;
secondChan = 7;
}
ssvepChanSelect.checkList.activate(firstChan);
ssvepChanSelect.checkList.activate(secondChan);
ssvepChanSelect.activeChan.add(firstChan);
ssvepChanSelect.activeChan.add(secondChan);
}

void setFreqDropdownSizes() {
//int dropdownsItemsToShow = int((h0 * widgetDropdownScaling) / (navH - 4));
int _dropdownHeight = (dropdownOptions.size() + 1) * (navH - 2);
Expand Down
Loading

0 comments on commit fa3e1ca

Please sign in to comment.