Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Ganglion decompression #1173

Merged
merged 7 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ libDataHandler.so
libGanglionLib.so
libGanglionScan.so
libunicorn.so
OpenBCI_GUI/out/
retiutut marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# v5.2.2

### Improvements
- Update Ganglion decompression to support Ganglion firmware v3 and v2 #1173 Awesome work! @philippitts

# v5.2.1

### Improvements
Expand Down
8 changes: 6 additions & 2 deletions OpenBCI_GUI/BoardBrainflow.pde
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,13 @@ abstract class BoardBrainFlow extends Board {
time_last_datapoint = -1.0;
}
catch (BrainFlowError e) {
println("ERROR: Exception when stoppping stream");
outputError("ERROR: Exception when stopping stream. Please restart the Board and Session.");
e.printStackTrace();
streaming = true;
//If no data was received in X seconds, there is a serious problem with communications. Go ahead and stop trying to collect data.
//Prevents feedback loop of errors.
if (data_popup_displayed) {
streaming = false;
}
}

if (eegDataSource != DATASOURCE_PLAYBACKFILE && eegDataSource != DATASOURCE_STREAMING) {
Expand Down
47 changes: 43 additions & 4 deletions OpenBCI_GUI/BoardGanglion.pde
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,27 @@ class BoardGanglionNative extends BoardGanglion {

private PacketLossTrackerGanglionBLE packetLossTrackerGanglionNative;
private String boardName;
private int firmwareVersion = 0;

public BoardGanglionNative() {
super();
}

public BoardGanglionNative(String name) {
public BoardGanglionNative(String name, boolean showUpgradePopup) {
super();
this.boardName = name;

if (name.indexOf("Ganglion 1.3") != -1) {
this.firmwareVersion = 3;
output("Detected Ganglion firmware version 3");
}
else {
this.firmwareVersion = 2;
output("Detected Ganglion firmware version 2");
if (showUpgradePopup) {
PopupMessage msg = new PopupMessage("Warning", "Ganglion firmware version 2 detected. Please update to version 3 for better performance. \n\nhttps://docs.openbci.com/Ganglion/GanglionProgram");
}
}
}

@Override
Expand Down Expand Up @@ -37,24 +50,43 @@ class BoardGanglionNative extends BoardGanglion {

@Override
protected PacketLossTracker setupPacketLossTracker() {
packetLossTrackerGanglionNative = new PacketLossTrackerGanglionBLE(getSampleIndexChannel(), getTimestampChannel());
if (firmwareVersion == 2) {
packetLossTrackerGanglionNative = new PacketLossTrackerGanglionBLE2(getSampleIndexChannel(), getTimestampChannel());
}
else if (firmwareVersion == 3) {
packetLossTrackerGanglionNative = new PacketLossTrackerGanglionBLE3(getSampleIndexChannel(), getTimestampChannel());
}

packetLossTrackerGanglionNative.setAccelerometerActive(isAccelerometerActive());
return packetLossTrackerGanglionNative;
}
};

class BoardGanglionBLE extends BoardGanglion {

private int firmwareVersion = 0;
private PacketLossTrackerGanglionBLE packetLossTrackerGanglionBLE;

public BoardGanglionBLE() {
super();
}

public BoardGanglionBLE(String serialPort, String macAddress) {
public BoardGanglionBLE(String deviceName, String serialPort, String macAddress, boolean showUpgradePopup) {
super();
this.serialPort = serialPort;
this.macAddress = macAddress;

if (deviceName.indexOf("Ganglion 1.3") != -1) {
this.firmwareVersion = 3;
output("Detected Ganglion firmware version 3");
}
else {
this.firmwareVersion = 2;
if (showUpgradePopup) {
PopupMessage msg = new PopupMessage("Warning", "Ganglion firmware version 2 detected. Please update to version 3 for better performance. \n\nhttps://docs.openbci.com/Ganglion/GanglionProgram");
}
output("Detected Ganglion firmware version 2");
}
}

@Override
Expand All @@ -75,7 +107,13 @@ class BoardGanglionBLE extends BoardGanglion {

@Override
protected PacketLossTracker setupPacketLossTracker() {
packetLossTrackerGanglionBLE = new PacketLossTrackerGanglionBLE(getSampleIndexChannel(), getTimestampChannel());
if (firmwareVersion == 2) {
packetLossTrackerGanglionBLE = new PacketLossTrackerGanglionBLE2(getSampleIndexChannel(), getTimestampChannel());
}
else if (firmwareVersion == 3) {
packetLossTrackerGanglionBLE = new PacketLossTrackerGanglionBLE3(getSampleIndexChannel(), getTimestampChannel());
}

packetLossTrackerGanglionBLE.setAccelerometerActive(isAccelerometerActive());
return packetLossTrackerGanglionBLE;
}
Expand Down Expand Up @@ -141,6 +179,7 @@ abstract class BoardGanglion extends BoardBrainFlow implements AccelerometerCapa
protected String serialPort = "";
protected String macAddress = "";
protected String ipAddress = "";

private boolean isCheckingImpedance = false;
private boolean isGettingAccel = false;

Expand Down
12 changes: 11 additions & 1 deletion OpenBCI_GUI/GuiSettings.pde
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum ExpertModeEnum implements GuiSettingsEnum {
public class GuiSettingsValues {
public ExpertModeEnum expertMode = ExpertModeEnum.OFF;
public boolean showCytonSmoothingPopup = true;
public boolean showGanglionUpgradePopup = true;

public GuiSettingsValues() {
}
Expand All @@ -43,7 +44,7 @@ class GuiSettings {

private GuiSettingsValues values;
private String filename;
private List<String> valueKeys = Arrays.asList("expertMode", "showCytonSmoothingPopup");
private List<String> valueKeys = Arrays.asList("expertMode", "showCytonSmoothingPopup", "showGanglionUpgradePopup");

GuiSettings(String settingsDirectory) {

Expand Down Expand Up @@ -164,7 +165,16 @@ class GuiSettings {
saveToFile();
}

public void setShowGanglionUpgradePopup(boolean b) {
values.showGanglionUpgradePopup = b;
saveToFile();
}

public boolean getShowCytonSmoothingPopup() {
return values.showCytonSmoothingPopup;
}

public boolean getShowGanglionUpgradePopup() {
return values.showGanglionUpgradePopup;
}
}
2 changes: 1 addition & 1 deletion 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>5</string>
<key>CFBundleVersion</key>
<string>5.2.1</string>
<string>5.2.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>NSHumanReadableCopyright</key>
Expand Down
19 changes: 13 additions & 6 deletions OpenBCI_GUI/OpenBCI_GUI.pde
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
// Global Variables & Instances
//------------------------------------------------------------------------
//Used to check GUI version in TopNav.pde and displayed on the splash screen on startup
String localGUIVersionString = "v5.2.1";
String localGUIVersionDate = "July 2023";
String localGUIVersionString = "v5.2.2";
String localGUIVersionDate = "August 2023";
String guiLatestVersionGithubAPI = "https://api.github.com/repos/OpenBCI/OpenBCI_GUI/releases/latest";
String guiLatestReleaseLocation = "https://github.com/OpenBCI/OpenBCI_GUI/releases/latest";
Boolean guiIsUpToDate;
Expand Down Expand Up @@ -606,19 +606,26 @@ void initSystem() {
}
break;
case DATASOURCE_GANGLION:
boolean showUpgradePopup = false;
if (guiSettings.getShowGanglionUpgradePopup())
{
showUpgradePopup = true;
guiSettings.setShowGanglionUpgradePopup(false);
}

if (selectedProtocol == BoardProtocol.WIFI) {
currentBoard = new BoardGanglionWifi(wifi_ipAddress, selectedSamplingRate);
} else if (selectedProtocol == BoardProtocol.BLED112) {
String ganglionName = (String)(controlPanel.bleBox.bleList.getItem(controlPanel.bleBox.bleList.activeItem).get("headline"));
String ganglionPort = (String)(controlPanel.bleBox.bleList.getItem(controlPanel.bleBox.bleList.activeItem).get("subline"));
String ganglionMac = controlPanel.bleBox.bleMACAddrMap.get(ganglionName);
println("MAC address for Ganglion is " + ganglionMac);
currentBoard = new BoardGanglionBLE(ganglionPort, ganglionMac);
currentBoard = new BoardGanglionBLE(ganglionName, ganglionPort, ganglionMac, showUpgradePopup);
} else if (selectedProtocol == BoardProtocol.NATIVE_BLE) {
String ganglionName = (String)(controlPanel.bleBox.bleList.getItem(controlPanel.bleBox.bleList.activeItem).get("headline"));
String ganglionMac = controlPanel.bleBox.bleMACAddrMap.get(ganglionName);
println("MAC address for Ganglion is " + ganglionName);
currentBoard = new BoardGanglionNative(ganglionName);
println("MAC address for Ganglion is " + ganglionMac);
currentBoard = new BoardGanglionNative(ganglionName, showUpgradePopup);
}
break;
case DATASOURCE_STREAMING:
Expand All @@ -641,7 +648,7 @@ void initSystem() {
println("OpenBCI_GUI: Configuring Cyton Channel Count...");
if (currentBoard instanceof BoardCytonSerial) {
Pair<Boolean, String> res = ((BoardBrainFlow)currentBoard).sendCommand("c");
//println(res.getKey().booleanValue(), res.getValue());
//println(res.getKey().booleanValue(), res.getValue());guiSettings
if (res.getValue().startsWith("daisy removed")) {
println("OpenBCI_GUI: Daisy is physically attached, using Cyton 8 Channels instead.");
}
Expand Down
85 changes: 56 additions & 29 deletions OpenBCI_GUI/PacketLossTracker.pde
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,6 @@ class PacketLossTrackerCytonSerialDaisy extends PacketLossTracker {
}
}

// with accel: sample index range 0-100, all sample indexes are duplicated except for zero.
// eg 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, ... , 99, 99, 100, 100, 0, 1, 1, 2, 2, 3, 3, ...
// without acceL: sample 0, then 101-200
class PacketLossTrackerGanglionBLE extends PacketLossTracker {

ArrayList<Integer> sampleIndexArrayAccel = new ArrayList<Integer>();
Expand All @@ -225,32 +222,6 @@ class PacketLossTrackerGanglionBLE extends PacketLossTracker {

PacketLossTrackerGanglionBLE(int _sampleIndexChannel, int _timestampChannel, TTQTimeProvider _timeProvider) {
super(_sampleIndexChannel, _timestampChannel, _timeProvider);

{
// add indices to array of indices
// With accel: 0-100, all sample indexes are duplicated except for zero
sampleIndexArrayAccel.add(0);
int firstIndex = 1;
int lastIndex = 100;
for (int i = firstIndex; i <= lastIndex; i++) {
sampleIndexArrayAccel.add(i);
sampleIndexArrayAccel.add(i);
}
}

{
// add indices to array of indices
// Without accel: 0, then 101 to 200, all sample indexes are duplicated except for zero
sampleIndexArrayNoAccel.add(0);
int firstIndex = 101;
int lastIndex = 200;
for (int i = firstIndex; i <= lastIndex; i++) {
sampleIndexArrayNoAccel.add(i);
sampleIndexArrayNoAccel.add(i);
}
}

setAccelerometerActive(true);
}

public void setAccelerometerActive(boolean active) {
Expand All @@ -264,4 +235,60 @@ class PacketLossTrackerGanglionBLE extends PacketLossTracker {

reset();
}
}

// With acceleration: sample index range 0-100, all sample indexes are duplicated except for zero.
// E.g. 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, ... , 99, 99, 100, 100, 0, 1, 1, 2, 2, 3, 3, ...
// Without acceleration: sample 0, then 101-200
class PacketLossTrackerGanglionBLE2 extends PacketLossTrackerGanglionBLE {
PacketLossTrackerGanglionBLE2(int _sampleIndexChannel, int _timestampChannel) {
this(_sampleIndexChannel, _timestampChannel, new RealTimeProvider());
}

PacketLossTrackerGanglionBLE2(int _sampleIndexChannel, int _timestampChannel, TTQTimeProvider _timeProvider) {
super(_sampleIndexChannel, _timestampChannel, _timeProvider);

// Add indices to array of indices
// With acceleration: 0-100, all sample indexes are duplicated except for zero
sampleIndexArrayAccel.add(0);
for (int i = 1; i <= 100; i++) {
sampleIndexArrayAccel.add(i);
sampleIndexArrayAccel.add(i);
}

// Add indices to array of indices
// Without acceleration: 0, then 101 to 200, all sample indexes are duplicated except for zero
sampleIndexArrayNoAccel.add(0);
for (int i = 101; i <= 200; i++) {
sampleIndexArrayNoAccel.add(i);
sampleIndexArrayNoAccel.add(i);
}

setAccelerometerActive(true);
}
}

// With acceleration: sample index range 0-100, all sample indexes are duplicated (including zero).
// E.g. 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, ... , 99, 99, 100, 100, 0, 0, 1, 1, 2, 2, 3, 3, ...
// Without acceleration: 101-200
class PacketLossTrackerGanglionBLE3 extends PacketLossTrackerGanglionBLE {
PacketLossTrackerGanglionBLE3(int _sampleIndexChannel, int _timestampChannel) {
this(_sampleIndexChannel, _timestampChannel, new RealTimeProvider());
}

PacketLossTrackerGanglionBLE3(int _sampleIndexChannel, int _timestampChannel, TTQTimeProvider _timeProvider) {
super(_sampleIndexChannel, _timestampChannel, _timeProvider);

for (int i = 0; i < 100; i++) {
sampleIndexArrayAccel.add(i);
sampleIndexArrayAccel.add(i);
}

for (int i = 100; i < 200; i++) {
sampleIndexArrayNoAccel.add(i);
sampleIndexArrayNoAccel.add(i);
}

setAccelerometerActive(true);
}
}
Binary file modified OpenBCI_GUI/libraries/brainflow/library/brainflow.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions OpenBCI_GUI_unittests/PacketLossTrackerGanglion_UnitTests.pde
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import org.junit.Before;

public static class PacketLossTrackerGanglionBLE_UnitTests{

PacketLossTrackerGanglionBLE packetLossTracker;
PacketLossTrackerGanglionBLE2 packetLossTracker;
FakeTimeProvider fakeTimeProvider;

@Before
public void setUp() {
int sampleIndexChannel = 0;
int timestampChannel = 1;
fakeTimeProvider = currentApplet.new FakeTimeProvider();
packetLossTracker = currentApplet.new PacketLossTrackerGanglionBLE(
packetLossTracker = currentApplet.new PacketLossTrackerGanglionBLE2(
sampleIndexChannel, timestampChannel, fakeTimeProvider);
packetLossTracker.silent = true;
}
Expand Down