Skip to content

Commit c066958

Browse files
committed
Merge branch 'master' into build/findBugs
2 parents 8eef0ae + 8079328 commit c066958

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1807
-411
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,6 @@ node_modules
8585
bower_components
8686

8787
#Generated files should be ignored as the are regenerated as a build step
88-
*/src/generated
88+
**/generated
89+
*/generated_tests
8990
/bin/

build.gradle

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,21 @@ def getGitCommit = { ->
2727
return COMMIT_HASH
2828
}
2929

30+
idea.project {
31+
ipr.withXml { provider ->
32+
def node = provider.asNode()
33+
def compilerConfig = node.component.find { it.'@name' == 'CompilerConfiguration'}
34+
compilerConfig.annotationProcessing[0].'@enabled' = 'true'
35+
// def ccfg = node.component.find { it.@name == 'CompilerConfiguration' }
36+
// ccfg.remove(ccfg.annotationProcessing)
37+
// ccfg.append(new NodeBuilder().annotationProcessing() {
38+
// profile(default: true, name: 'Default', enabled: true) {
39+
// processorPath(useClasspath: true)
40+
// }
41+
// })
42+
}
43+
}
44+
3045
/*
3146
* Gets the version name from the latest Git tag
3247
* http://ryanharter.com/blog/2013/07/30/automatic-versioning-with-git-and-gradle/
@@ -156,6 +171,9 @@ project(":core") {
156171
maven {
157172
url = "http://first.wpi.edu/FRC/roborio/maven/development"
158173
}
174+
maven {
175+
url = "https://github.com/WPIRoboticsProjects/rosjava_mvn_repo/raw/master"
176+
}
159177
}
160178
}
161179

@@ -170,11 +188,16 @@ project(":core") {
170188
compile group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.4.8'
171189
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4'
172190
compile group: 'com.google.guava', name: 'guava', version: '19.0'
191+
compile group: 'com.google.auto.value', name: 'auto-value', version: '1.1'
173192
// We use the no_aop version of Guice because the aop isn't avaiable in arm java
174193
// http://stackoverflow.com/a/15235190/3708426
175194
// https://github.com/google/guice/wiki/OptionalAOP
176195
compile group: 'com.google.inject', name: 'guice', version: '4.0', classifier: 'no_aop'
177196
compile group: 'com.google.inject.extensions', name: 'guice-assistedinject', version: '4.0'
197+
198+
// Network publishing dependencies
199+
compile group: 'org.ros.rosjava_core', name: 'rosjava', version: '[0.2,0.3)'
200+
compile group: 'org.ros.rosjava_messages', name: 'grip_msgs', version: '0.0.1'
178201
compile group: 'edu.wpi.first.wpilib.networktables.java', name: 'NetworkTables', version: '3.0.0-SNAPSHOT', classifier: 'desktop'
179202
compile group: 'edu.wpi.first.wpilib.networktables.java', name: 'NetworkTables', version: '3.0.0-SNAPSHOT', classifier: 'arm'
180203
}
@@ -243,8 +266,8 @@ project(":core") {
243266

244267
idea.module {
245268
sourceDirs += sourceSets.generated.java.srcDirs
269+
sourceDirs += file('generated')
246270
}
247-
// End IDE setup
248271
}
249272

250273
project(":ui") {

buildSrc/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ configurations {
1212
dependencies {
1313
compile gradleApi()
1414
compile localGroovy()
15-
compile group: 'com.google.guava', name: 'guava', version: '18.0'
15+
compile group: 'com.google.guava', name: 'guava', version: '19.0'
1616
compile group: 'com.github.javaparser', name: 'javaparser-core', version: '2.2.2'
1717
source group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.0.0-1.1', classifier: 'sources'
1818
testCompile group: 'junit', name: 'junit', version: '4.11'

core/src/main/java/edu/wpi/grip/core/GRIPCoreModule.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import com.google.inject.spi.TypeEncounter;
1111
import com.google.inject.spi.TypeListener;
1212
import edu.wpi.grip.core.events.UnexpectedThrowableEvent;
13-
import edu.wpi.grip.core.operations.networktables.NTManager;
1413
import edu.wpi.grip.core.serialization.Project;
1514
import edu.wpi.grip.core.sources.CameraSource;
1615
import edu.wpi.grip.core.sources.ImageFileSource;
@@ -101,8 +100,6 @@ public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
101100

102101
bind(EventBus.class).toInstance(eventBus);
103102

104-
bind(NTManager.class).asEagerSingleton();
105-
106103
install(new FactoryModuleBuilder().build(new TypeLiteral<Connection.Factory<Object>>() {
107104
}));
108105

core/src/main/java/edu/wpi/grip/core/Main.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import edu.wpi.grip.core.events.ExceptionClearedEvent;
88
import edu.wpi.grip.core.events.ExceptionEvent;
99
import edu.wpi.grip.core.operations.Operations;
10+
import edu.wpi.grip.core.operations.network.GRIPNetworkModule;
1011
import edu.wpi.grip.core.serialization.Project;
1112
import edu.wpi.grip.generated.CVOperations;
1213

@@ -24,11 +25,12 @@ public class Main {
2425
@Inject private Project project;
2526
@Inject private PipelineRunner pipelineRunner;
2627
@Inject private EventBus eventBus;
28+
@Inject private Operations operations;
2729
@Inject private Logger logger;
2830

2931
@SuppressWarnings("PMD.SystemPrintln")
3032
public static void main(String[] args) throws IOException, InterruptedException {
31-
final Injector injector = Guice.createInjector(new GRIPCoreModule());
33+
final Injector injector = Guice.createInjector(new GRIPCoreModule(), new GRIPNetworkModule());
3234
injector.getInstance(Main.class).start(args);
3335
}
3436

@@ -41,7 +43,7 @@ public void start(String[] args) throws IOException, InterruptedException {
4143
logger.log(Level.INFO, "Loading file " + args[0]);
4244
}
4345

44-
Operations.addOperations(eventBus);
46+
operations.addOperations();
4547
CVOperations.addOperations(eventBus);
4648

4749
final String projectPath = args[0];

core/src/main/java/edu/wpi/grip/core/Operation.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package edu.wpi.grip.core;
22

3+
import com.google.common.collect.ImmutableSet;
34
import com.google.common.eventbus.EventBus;
45

56
import java.io.InputStream;
@@ -24,6 +25,14 @@ enum Category {
2425
*/
2526
String getName();
2627

28+
/**
29+
* @return Any old unique user-facing names of the operation. This is used to preserve compatibility with
30+
* old versions of GRIP if the operation name changes.
31+
*/
32+
default ImmutableSet<String> getAliases() {
33+
return ImmutableSet.of();
34+
}
35+
2736

2837
/**
2938
* @return A description of the operation.

core/src/main/java/edu/wpi/grip/core/Palette.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.util.Map;
1212
import java.util.Optional;
1313

14+
import static com.google.common.base.Preconditions.checkArgument;
1415
import static com.google.common.base.Preconditions.checkNotNull;
1516

1617
/**
@@ -31,7 +32,21 @@ public class Palette {
3132
@Subscribe
3233
public void onOperationAdded(OperationAddedEvent event) {
3334
final Operation operation = event.getOperation();
34-
this.operations.put(operation.getName(), operation);
35+
map(operation.getName(), operation);
36+
for(String alias : operation.getAliases()) {
37+
map(alias, operation);
38+
}
39+
}
40+
41+
/**
42+
* Maps the key to the given operation
43+
* @param key The key the operation should be mapped to
44+
* @param operation The operation to map the key to
45+
* @throws IllegalArgumentException if the key is already in the {@link #operations} map.
46+
*/
47+
private void map(String key, Operation operation) {
48+
checkArgument(!operations.containsKey(key), "Operation name or alias already exists: " + key);
49+
operations.put(key, operation);
3550
}
3651

3752
/**

core/src/main/java/edu/wpi/grip/core/PipelineRunner.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
import edu.wpi.grip.core.events.RenderEvent;
1414
import edu.wpi.grip.core.events.RunPipelineEvent;
1515
import edu.wpi.grip.core.events.StopPipelineEvent;
16+
import edu.wpi.grip.core.util.SinglePermitSemaphore;
1617
import edu.wpi.grip.core.util.service.AutoRestartingService;
1718
import edu.wpi.grip.core.util.service.LoggingListener;
1819
import edu.wpi.grip.core.util.service.RestartableService;
1920

2021
import javax.annotation.Nullable;
2122
import javax.inject.Inject;
2223
import java.util.concurrent.Executor;
23-
import java.util.concurrent.Semaphore;
2424
import java.util.concurrent.TimeUnit;
2525
import java.util.concurrent.TimeoutException;
2626
import java.util.function.Supplier;
@@ -37,7 +37,7 @@ public class PipelineRunner implements RestartableService {
3737
/**
3838
* This is used to flag that the pipeline needs to run because of an update
3939
*/
40-
private final Semaphore pipelineFlag = new Semaphore(0);
40+
private final SinglePermitSemaphore pipelineFlag = new SinglePermitSemaphore();
4141
private final Supplier<ImmutableList<Source>> sourceSupplier;
4242
private final Supplier<ImmutableList<Step>> stepSupplier;
4343
private final AutoRestartingService pipelineService;
@@ -62,13 +62,7 @@ public class PipelineRunner implements RestartableService {
6262
protected void runOneIteration() throws InterruptedException {
6363
if (!super.isRunning()) return;
6464

65-
// Acquire the first this one should permit if there is at least one permit
6665
pipelineFlag.acquire();
67-
// Acquire the rest of the permits from the flag
68-
// Every time release is called another permit is added.
69-
// We need to clean up any old permits that we may have been given.
70-
pipelineFlag.acquire(
71-
Math.max(0, pipelineFlag.availablePermits()));
7266

7367
if (!super.isRunning()) return;
7468
runPipeline(super::isRunning);
Lines changed: 84 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,99 @@
11
package edu.wpi.grip.core.operations;
22

3+
import com.google.common.collect.ImmutableList;
34
import com.google.common.eventbus.EventBus;
5+
import com.google.inject.Inject;
6+
import com.google.inject.Singleton;
7+
import com.google.inject.name.Named;
8+
import edu.wpi.grip.core.Operation;
49
import edu.wpi.grip.core.events.OperationAddedEvent;
510
import edu.wpi.grip.core.operations.composite.*;
6-
import edu.wpi.grip.core.operations.networktables.NTNumber;
7-
import edu.wpi.grip.core.operations.networktables.NTPublishOperation;
8-
import edu.wpi.grip.core.operations.networktables.NTVector2D;
11+
import edu.wpi.grip.core.operations.network.BooleanPublishable;
12+
import edu.wpi.grip.core.operations.network.MapNetworkPublisherFactory;
13+
import edu.wpi.grip.core.operations.network.NumberPublishable;
14+
import edu.wpi.grip.core.operations.network.Vector2D;
15+
import edu.wpi.grip.core.operations.network.networktables.NTPublishAnnotatedOperation;
16+
import edu.wpi.grip.core.operations.network.ros.JavaToMessageConverter;
17+
import edu.wpi.grip.core.operations.network.ros.ROSNetworkPublisherFactory;
18+
import edu.wpi.grip.core.operations.network.ros.ROSPublishOperation;
919
import edu.wpi.grip.core.operations.opencv.MatFieldAccessor;
1020
import edu.wpi.grip.core.operations.opencv.MinMaxLoc;
1121
import edu.wpi.grip.core.operations.opencv.NewPointOperation;
1222
import edu.wpi.grip.core.operations.opencv.NewSizeOperation;
1323

14-
import static org.bytedeco.javacpp.opencv_core.*;
24+
import java.util.function.Supplier;
1525

16-
public final class Operations {
26+
import static com.google.common.base.Preconditions.checkNotNull;
27+
import static org.bytedeco.javacpp.opencv_core.Point;
28+
import static org.bytedeco.javacpp.opencv_core.Size;
1729

18-
private Operations() { /* no op */}
30+
@Singleton
31+
public class Operations {
32+
private final EventBus eventBus;
33+
private final ImmutableList<Supplier<Operation>> operations;
1934

20-
public static void addOperations(EventBus eventBus) {
21-
// Add the default built-in operations to the palette
22-
eventBus.post(new OperationAddedEvent(new ResizeOperation()));
23-
eventBus.post(new OperationAddedEvent(new BlurOperation()));
24-
eventBus.post(new OperationAddedEvent(new DesaturateOperation()));
25-
eventBus.post(new OperationAddedEvent(new RGBThresholdOperation()));
26-
eventBus.post(new OperationAddedEvent(new HSVThresholdOperation()));
27-
eventBus.post(new OperationAddedEvent(new HSLThresholdOperation()));
28-
eventBus.post(new OperationAddedEvent(new FindContoursOperation()));
29-
eventBus.post(new OperationAddedEvent(new FilterContoursOperation()));
30-
eventBus.post(new OperationAddedEvent(new ConvexHullsOperation()));
31-
eventBus.post(new OperationAddedEvent(new FindBlobsOperation()));
32-
eventBus.post(new OperationAddedEvent(new FindLinesOperation()));
33-
eventBus.post(new OperationAddedEvent(new FilterLinesOperation()));
34-
eventBus.post(new OperationAddedEvent(new MaskOperation()));
35-
eventBus.post(new OperationAddedEvent(new MinMaxLoc()));
36-
eventBus.post(new OperationAddedEvent(new MatFieldAccessor()));
37-
eventBus.post(new OperationAddedEvent(new NewPointOperation()));
38-
eventBus.post(new OperationAddedEvent(new NewSizeOperation()));
39-
eventBus.post(new OperationAddedEvent(new NTPublishOperation<>(Number.class, NTNumber.class, NTNumber::new)));
40-
eventBus.post(new OperationAddedEvent(new NTPublishOperation<>(Point.class, NTVector2D.class, NTVector2D::new)));
41-
eventBus.post(new OperationAddedEvent(new NTPublishOperation<>(Size.class, NTVector2D.class, NTVector2D::new)));
42-
eventBus.post(new OperationAddedEvent(new NTPublishOperation<>(ContoursReport.class)));
43-
eventBus.post(new OperationAddedEvent(new NTPublishOperation<>(BlobsReport.class)));
44-
eventBus.post(new OperationAddedEvent(new NTPublishOperation<>(LinesReport.class)));
45-
eventBus.post(new OperationAddedEvent(new PublishVideoOperation()));
46-
eventBus.post(new OperationAddedEvent(new DistanceTransformOperation()));
47-
eventBus.post(new OperationAddedEvent(new NormalizeOperation()));
48-
eventBus.post(new OperationAddedEvent(new WatershedOperation()));
35+
@Inject
36+
Operations(EventBus eventBus, @Named("ntManager") MapNetworkPublisherFactory ntPublisherFactory, @Named("rosManager") ROSNetworkPublisherFactory rosPublishFactory) {
37+
this.eventBus = checkNotNull(eventBus, "EventBus cannot be null");
38+
checkNotNull(ntPublisherFactory, "ntPublisherFactory cannot be null");
39+
checkNotNull(rosPublishFactory, "rosPublishFactory cannot be null");
40+
this.operations = ImmutableList.of(
41+
ResizeOperation::new,
42+
BlurOperation::new,
43+
DesaturateOperation::new,
44+
RGBThresholdOperation::new,
45+
HSVThresholdOperation::new,
46+
HSLThresholdOperation::new,
47+
FindContoursOperation::new,
48+
FilterContoursOperation::new,
49+
ConvexHullsOperation::new,
50+
FindBlobsOperation::new,
51+
FindLinesOperation::new,
52+
FilterLinesOperation::new,
53+
MaskOperation::new,
54+
MinMaxLoc::new,
55+
MatFieldAccessor::new,
56+
NewPointOperation::new,
57+
NewSizeOperation::new,
58+
() -> new NTPublishAnnotatedOperation<Number, NumberPublishable, Double>(ntPublisherFactory, NumberPublishable::new) {
59+
},
60+
() -> new NTPublishAnnotatedOperation<Boolean, BooleanPublishable, Boolean>(ntPublisherFactory, BooleanPublishable::new) {
61+
},
62+
() -> new NTPublishAnnotatedOperation<Point, Vector2D, Double>(ntPublisherFactory, Vector2D::new) {
63+
},
64+
() -> new NTPublishAnnotatedOperation<Size, Vector2D, Double>(ntPublisherFactory, Vector2D::new) {
65+
},
66+
() -> new NTPublishAnnotatedOperation<ContoursReport, ContoursReport, double[]>(ntPublisherFactory) {
67+
},
68+
() -> new NTPublishAnnotatedOperation<BlobsReport, BlobsReport, double[]>(ntPublisherFactory) {
69+
},
70+
() -> new NTPublishAnnotatedOperation<LinesReport, LinesReport, double[]>(ntPublisherFactory) {
71+
},
72+
() -> new ROSPublishOperation<Number>(rosPublishFactory, JavaToMessageConverter.FLOAT) {
73+
},
74+
() -> new ROSPublishOperation<Boolean>(rosPublishFactory, JavaToMessageConverter.BOOL) {
75+
},
76+
// () -> new ROSPublishOperation<Point, Vector2D, Double>(rosManager, Vector2D::new) {
77+
// },
78+
// () -> new ROSPublishOperation<Size, Vector2D, Double>(rosManager, Vector2D::new) {
79+
// },
80+
() -> new ROSPublishOperation<ContoursReport>(rosPublishFactory, JavaToMessageConverter.CONTOURS) {
81+
},
82+
() -> new ROSPublishOperation<BlobsReport>(rosPublishFactory, JavaToMessageConverter.BLOBS) {
83+
},
84+
() -> new ROSPublishOperation<LinesReport>(rosPublishFactory, JavaToMessageConverter.LINES) {
85+
},
86+
PublishVideoOperation::new,
87+
DistanceTransformOperation::new,
88+
NormalizeOperation::new,
89+
WatershedOperation::new
90+
);
91+
}
92+
93+
public void addOperations() {
94+
operations.stream()
95+
.map(s -> s.get())
96+
.map(OperationAddedEvent::new)
97+
.forEach(eventBus::post);
4998
}
5099
}

core/src/main/java/edu/wpi/grip/core/operations/composite/BlobsReport.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import com.google.common.base.MoreObjects;
44
import edu.wpi.grip.core.NoSocketTypeLabel;
5-
import edu.wpi.grip.core.operations.networktables.NTPublishable;
6-
import edu.wpi.grip.core.operations.networktables.NTValue;
5+
import edu.wpi.grip.core.operations.network.PublishValue;
6+
import edu.wpi.grip.core.operations.network.Publishable;
77

88
import java.util.Collections;
99
import java.util.List;
@@ -14,7 +14,7 @@
1414
* This class is used as the output of operations that detect blobs in an image
1515
*/
1616
@NoSocketTypeLabel
17-
public class BlobsReport implements NTPublishable {
17+
public class BlobsReport implements Publishable {
1818
private final Mat input;
1919
private final List<Blob> blobs;
2020

@@ -60,7 +60,7 @@ public Mat getInput() {
6060
return this.input;
6161
}
6262

63-
@NTValue(key = "x", weight = 0)
63+
@PublishValue(key = "x", weight = 0)
6464
public double[] getX() {
6565
final double[] x = new double[blobs.size()];
6666
for (int i = 0; i < blobs.size(); i++) {
@@ -69,7 +69,7 @@ public double[] getX() {
6969
return x;
7070
}
7171

72-
@NTValue(key = "y", weight = 1)
72+
@PublishValue(key = "y", weight = 1)
7373
public double[] getY() {
7474
final double[] y = new double[blobs.size()];
7575
for (int i = 0; i < blobs.size(); i++) {
@@ -78,7 +78,7 @@ public double[] getY() {
7878
return y;
7979
}
8080

81-
@NTValue(key = "size", weight = 2)
81+
@PublishValue(key = "size", weight = 2)
8282
public double[] getSize() {
8383
final double[] sizes = new double[blobs.size()];
8484
for (int i = 0; i < blobs.size(); i++) {

0 commit comments

Comments
 (0)