Skip to content

Commit 86c69c6

Browse files
committed
Rewrites Publishing to use GRIP ROS Types
1 parent da02353 commit 86c69c6

38 files changed

+727
-524
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: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@ def getGitCommit = { ->
2121
return COMMIT_HASH
2222
}
2323

24+
idea.project {
25+
ipr.withXml { provider ->
26+
def node = provider.asNode()
27+
def compilerConfig = node.component.find { it.'@name' == 'CompilerConfiguration'}
28+
compilerConfig.annotationProcessing[0].'@enabled' = 'true'
29+
// def ccfg = node.component.find { it.@name == 'CompilerConfiguration' }
30+
// ccfg.remove(ccfg.annotationProcessing)
31+
// ccfg.append(new NodeBuilder().annotationProcessing() {
32+
// profile(default: true, name: 'Default', enabled: true) {
33+
// processorPath(useClasspath: true)
34+
// }
35+
// })
36+
}
37+
}
38+
2439
/*
2540
* Gets the version name from the latest Git tag
2641
* http://ryanharter.com/blog/2013/07/30/automatic-versioning-with-git-and-gradle/
@@ -146,7 +161,7 @@ project(":core") {
146161
url = "http://first.wpi.edu/FRC/roborio/maven/development"
147162
}
148163
maven {
149-
url = "https://github.com/rosjava/rosjava_mvn_repo/raw/master"
164+
url = "https://github.com/WPIRoboticsProjects/rosjava_mvn_repo/raw/master"
150165
}
151166
}
152167
}
@@ -162,6 +177,7 @@ project(":core") {
162177
compile group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.4.8'
163178
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.4'
164179
compile group: 'com.google.guava', name: 'guava', version: '19.0'
180+
compile group: 'com.google.auto.value', name: 'auto-value', version: '1.1'
165181
// We use the no_aop version of Guice because the aop isn't avaiable in arm java
166182
// http://stackoverflow.com/a/15235190/3708426
167183
// https://github.com/google/guice/wiki/OptionalAOP
@@ -170,6 +186,7 @@ project(":core") {
170186

171187
// Network publishing dependencies
172188
compile group: 'org.ros.rosjava_core', name: 'rosjava', version: '[0.2,0.3)'
189+
compile group: 'org.ros.rosjava_messages', name: 'grip_msgs', version: '0.0.1'
173190
compile group: 'edu.wpi.first.wpilib.networktables.java', name: 'NetworkTables', version: '3.0.0-SNAPSHOT', classifier: 'desktop'
174191
compile group: 'edu.wpi.first.wpilib.networktables.java', name: 'NetworkTables', version: '3.0.0-SNAPSHOT', classifier: 'arm'
175192
}
@@ -238,8 +255,8 @@ project(":core") {
238255

239256
idea.module {
240257
sourceDirs += sourceSets.generated.java.srcDirs
258+
sourceDirs += file('generated')
241259
}
242-
// End IDE setup
243260
}
244261

245262
project(":ui") {

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);

core/src/main/java/edu/wpi/grip/core/operations/Operations.java

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
import edu.wpi.grip.core.events.OperationAddedEvent;
1010
import edu.wpi.grip.core.operations.composite.*;
1111
import edu.wpi.grip.core.operations.network.BooleanPublishable;
12-
import edu.wpi.grip.core.operations.network.Manager;
12+
import edu.wpi.grip.core.operations.network.MapNetworkPublisherFactory;
1313
import edu.wpi.grip.core.operations.network.NumberPublishable;
1414
import edu.wpi.grip.core.operations.network.Vector2D;
15-
import edu.wpi.grip.core.operations.network.networktables.NTKeyValuePublishOperation;
16-
import edu.wpi.grip.core.operations.network.ros.ROSKeyValuePublishOperation;
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;
1719
import edu.wpi.grip.core.operations.opencv.MatFieldAccessor;
1820
import edu.wpi.grip.core.operations.opencv.MinMaxLoc;
1921
import edu.wpi.grip.core.operations.opencv.NewPointOperation;
@@ -31,10 +33,10 @@ public class Operations {
3133
private final ImmutableList<Supplier<Operation>> operations;
3234

3335
@Inject
34-
Operations(EventBus eventBus, @Named("ntManager") Manager ntManager, @Named("rosManager") Manager rosManager) {
36+
Operations(EventBus eventBus, @Named("ntManager") MapNetworkPublisherFactory ntPublisherFactory, @Named("rosManager") ROSNetworkPublisherFactory rosPublishFactory) {
3537
this.eventBus = checkNotNull(eventBus, "EventBus cannot be null");
36-
checkNotNull(ntManager, "ntManager cannot be null");
37-
checkNotNull(rosManager, "rosManager cannot be null");
38+
checkNotNull(ntPublisherFactory, "ntPublisherFactory cannot be null");
39+
checkNotNull(rosPublishFactory, "rosPublishFactory cannot be null");
3840
this.operations = ImmutableList.of(
3941
ResizeOperation::new,
4042
BlurOperation::new,
@@ -53,33 +55,33 @@ public class Operations {
5355
MatFieldAccessor::new,
5456
NewPointOperation::new,
5557
NewSizeOperation::new,
56-
() -> new NTKeyValuePublishOperation<Number, NumberPublishable, Number>(ntManager, NumberPublishable::new) {
58+
() -> new NTPublishAnnotatedOperation<Number, NumberPublishable, Double>(ntPublisherFactory, NumberPublishable::new) {
5759
},
58-
() -> new NTKeyValuePublishOperation<Boolean, BooleanPublishable, Boolean>(ntManager, BooleanPublishable::new) {
60+
() -> new NTPublishAnnotatedOperation<Boolean, BooleanPublishable, Boolean>(ntPublisherFactory, BooleanPublishable::new) {
5961
},
60-
() -> new NTKeyValuePublishOperation<Point, Vector2D, Double>(ntManager, Vector2D::new) {
62+
() -> new NTPublishAnnotatedOperation<Point, Vector2D, Double>(ntPublisherFactory, Vector2D::new) {
6163
},
62-
() -> new NTKeyValuePublishOperation<Size, Vector2D, Double>(ntManager, Vector2D::new) {
64+
() -> new NTPublishAnnotatedOperation<Size, Vector2D, Double>(ntPublisherFactory, Vector2D::new) {
6365
},
64-
() -> new NTKeyValuePublishOperation<ContoursReport, ContoursReport, double[]>(ntManager) {
66+
() -> new NTPublishAnnotatedOperation<ContoursReport, ContoursReport, double[]>(ntPublisherFactory) {
6567
},
66-
() -> new NTKeyValuePublishOperation<BlobsReport, BlobsReport, double[]>(ntManager) {
68+
() -> new NTPublishAnnotatedOperation<BlobsReport, BlobsReport, double[]>(ntPublisherFactory) {
6769
},
68-
() -> new NTKeyValuePublishOperation<LinesReport, LinesReport, double[]>(ntManager) {
70+
() -> new NTPublishAnnotatedOperation<LinesReport, LinesReport, double[]>(ntPublisherFactory) {
6971
},
70-
() -> new ROSKeyValuePublishOperation<Number, NumberPublishable, Number>(ntManager, NumberPublishable::new) {
72+
() -> new ROSPublishOperation<Number>(rosPublishFactory, JavaToMessageConverter.FLOAT) {
7173
},
72-
() -> new ROSKeyValuePublishOperation<Boolean, BooleanPublishable, Boolean>(ntManager, BooleanPublishable::new) {
74+
() -> new ROSPublishOperation<Boolean>(rosPublishFactory, JavaToMessageConverter.BOOL) {
7375
},
74-
() -> new ROSKeyValuePublishOperation<Point, Vector2D, Double>(ntManager, Vector2D::new) {
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) {
7581
},
76-
() -> new ROSKeyValuePublishOperation<Size, Vector2D, Double>(ntManager, Vector2D::new) {
82+
() -> new ROSPublishOperation<BlobsReport>(rosPublishFactory, JavaToMessageConverter.BLOBS) {
7783
},
78-
() -> new ROSKeyValuePublishOperation<ContoursReport, ContoursReport, double[]>(ntManager) {
79-
},
80-
() -> new ROSKeyValuePublishOperation<BlobsReport, BlobsReport, double[]>(ntManager) {
81-
},
82-
() -> new ROSKeyValuePublishOperation<LinesReport, LinesReport, double[]>(ntManager) {
84+
() -> new ROSPublishOperation<LinesReport>(rosPublishFactory, JavaToMessageConverter.LINES) {
8385
},
8486
PublishVideoOperation::new,
8587
DistanceTransformOperation::new,

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

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package edu.wpi.grip.core.operations.composite;
22

3+
import com.google.auto.value.AutoValue;
34
import edu.wpi.grip.core.NoSocketTypeLabel;
4-
import edu.wpi.grip.core.operations.network.Publishable;
55
import edu.wpi.grip.core.operations.network.PublishValue;
6+
import edu.wpi.grip.core.operations.network.Publishable;
67

8+
import java.util.ArrayList;
9+
import java.util.List;
710
import java.util.Optional;
811

912
import static org.bytedeco.javacpp.opencv_core.*;
@@ -46,6 +49,39 @@ public MatVector getContours() {
4649
return this.contours;
4750
}
4851

52+
@AutoValue
53+
public static abstract class Contour {
54+
static Contour create(double area, double centerX, double centerY, double width, double height, double solidity) {
55+
return new AutoValue_ContoursReport_Contour(area, centerX, centerY, width, height, solidity);
56+
}
57+
58+
public abstract double area();
59+
60+
public abstract double centerX();
61+
62+
public abstract double centerY();
63+
64+
public abstract double width();
65+
66+
public abstract double height();
67+
68+
public abstract double solidity();
69+
}
70+
71+
public List<Contour> getProcessedContours() {
72+
final List<Contour> processedContours = new ArrayList<>((int) contours.size());
73+
double area[] = getArea();
74+
double centerX[] = getCenterX();
75+
double centerY[] = getCenterY();
76+
double width[] = getWidth();
77+
double height[] = getHeights();
78+
double solidity[] = getSolidity();
79+
for (int i = 0; i < contours.size(); i++) {
80+
processedContours.add(Contour.create(area[i], centerX[i], centerY[i], width[i], height[i], solidity[i]));
81+
}
82+
return processedContours;
83+
}
84+
4985
/**
5086
* Compute the bounding boxes of all contours (if they haven't already been computed). Bounding boxes are used
5187
* to compute several different properties, so it's probably not a good idea to compute them over and over again.

core/src/main/java/edu/wpi/grip/core/operations/network/BooleanPublishable.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import java.util.function.Function;
55

66
/**
7-
* An adapter to allow booleans to be published from GRIP sockets into a {@link NetworkKeyValuePublisher}
7+
* An adapter to allow booleans to be published from GRIP sockets into a {@link NetworkPublisher}
88
*
9-
* @see KeyValuePublishOperation#PublishOperation(Manager, Class, Class, Function)
9+
* @see PublishAnnotatedOperation#PublishAnnotatedOperation(MapNetworkPublisherFactory, Function)
1010
*/
1111
@Immutable
1212
public final class BooleanPublishable implements Publishable {

core/src/main/java/edu/wpi/grip/core/operations/network/GRIPNetworkModule.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.google.inject.name.Names;
55
import edu.wpi.grip.core.operations.network.networktables.NTManager;
66
import edu.wpi.grip.core.operations.network.ros.ROSManager;
7+
import edu.wpi.grip.core.operations.network.ros.ROSNetworkPublisherFactory;
78

89
/**
910
* Defines any concrete implementation mappings between
@@ -15,10 +16,10 @@
1516
public final class GRIPNetworkModule extends AbstractModule {
1617
@Override
1718
protected void configure() {
18-
bind(Manager.class)
19+
bind(MapNetworkPublisherFactory.class)
1920
.annotatedWith(Names.named("ntManager"))
2021
.to(NTManager.class);
21-
bind(Manager.class)
22+
bind(ROSNetworkPublisherFactory.class)
2223
.annotatedWith(Names.named("rosManager"))
2324
.to(ROSManager.class);
2425
}
Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,9 @@
11
package edu.wpi.grip.core.operations.network;
22

33

4-
import java.util.Set;
5-
64
/**
75
* A network manager that handles all of the API overhead for dealing with
86
* a specific network protocol.
97
*/
108
public interface Manager {
11-
/**
12-
*
13-
* @param keys The possible set of keys that this network publisher can publish.
14-
* @return A network publisher for the specific protocol.
15-
*/
16-
<P> NetworkKeyValuePublisher<P> createPublisher(Class<P> publishType, Set<String> keys);
179
}

core/src/main/java/edu/wpi/grip/core/operations/network/NetworkKeyValuePublisher.java renamed to core/src/main/java/edu/wpi/grip/core/operations/network/MapNetworkPublisher.java

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,19 @@
77
import java.util.Set;
88

99
import static com.google.common.base.Preconditions.checkArgument;
10-
import static com.google.common.base.Preconditions.checkNotNull;
1110

1211
/**
13-
* Manages the interface between the {@link KeyValuePublishOperation} and the actual network
14-
* protocol implemented by a specific {@link Manager}.
15-
* <p>
16-
* This class is designed to be in one of two states, either the set of keys
17-
* will be empty. In which case the name will be used as the publish key.
18-
* In the other case the keys list will be populated and each value will
19-
* need to be published with a specific key.
12+
* Publishes a map of keys to values
13+
*
14+
* @param <T> The type of the 'value' in the string, value map that is being published
2015
*/
21-
public abstract class NetworkKeyValuePublisher<T> extends NetworkPublisher {
16+
public abstract class MapNetworkPublisher<T> extends NetworkPublisher<Map<String, T>> {
2217
private final ImmutableSet<String> keys;
23-
private final Class<T> publishType;
2418

25-
protected NetworkKeyValuePublisher(Class<T> publishType, Set<String> keys) {
19+
protected MapNetworkPublisher(Set<String> keys) {
20+
super();
2621
checkArgument(!keys.contains(""), "Keys can not contain the empty string");
2722
this.keys = ImmutableSet.copyOf(keys);
28-
this.publishType = checkNotNull(publishType, "The publishType cannot be null");
29-
}
30-
31-
protected final Class<T> getPublishType() {
32-
return publishType;
3323
}
3424

3525
/**
@@ -38,26 +28,26 @@ protected final Class<T> getPublishType() {
3828
*
3929
* @param publishMap the keyValues to publish
4030
*/
41-
final void publish(Map<String, T> publishMap) {
31+
@Override
32+
public final void publish(Map<String, T> publishMap) {
4233
final Map<String, T> publishMapCopy = ImmutableMap.copyOf(publishMap);
4334
if (!keys.isEmpty()) {
4435
publishMap.entrySet().forEach(key -> checkArgument(keys.contains(key), "Key must be in keys list: " + key));
4536
}
4637
checkNamePresent();
4738
if (!publishMapCopy.containsKey("")) {
4839
doPublish(publishMapCopy);
49-
} else if(!publishMapCopy.keySet().isEmpty()){
50-
doPublish(publishMapCopy.get(""));
40+
} else if (!publishMapCopy.keySet().isEmpty()) {
41+
doPublishSingle(publishMapCopy.get(""));
5142
} else {
5243
doPublish();
5344
}
5445
}
5546

5647
/**
57-
* Perform the publish with the key and value. The key is guaranteed to be in the
58-
* {@link #keys} set.
48+
* Publishes a key value mapping
5949
*
60-
* @param publishMap the keyValues to publish
50+
* @param publishMap The mapping of keys to values to be published
6151
*/
6252
protected abstract void doPublish(Map<String, T> publishMap);
6353

@@ -66,15 +56,10 @@ final void publish(Map<String, T> publishMap) {
6656
*
6757
* @param value The value to be published
6858
*/
69-
protected abstract void doPublish(T value);
59+
protected abstract void doPublishSingle(T value);
7060

7161
/**
7262
* Publishes nothing.
7363
*/
7464
protected abstract void doPublish();
75-
76-
/**
77-
* Close the network publisher. This should not throw an exception.
78-
*/
79-
public abstract void close();
8065
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package edu.wpi.grip.core.operations.network;
2+
3+
4+
import java.util.Set;
5+
6+
/**
7+
* A factory to create {@link MapNetworkPublisher MapNetworkPublishers}
8+
*/
9+
@FunctionalInterface
10+
public interface MapNetworkPublisherFactory {
11+
<T> MapNetworkPublisher<T> create(Set<String> keys);
12+
}

0 commit comments

Comments
 (0)