Skip to content

Commit

Permalink
Merge pull request #956 from NASA-AMMOS/contrib-sampl-res-update
Browse files Browse the repository at this point in the history
  • Loading branch information
ewferg authored Jun 1, 2023
2 parents 01c436c + 9921c3a commit 42dd18c
Showing 1 changed file with 34 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,35 +1,67 @@
package gov.nasa.jpl.aerie.contrib.models;

import gov.nasa.jpl.aerie.merlin.framework.resources.discrete.DiscreteResource;
import gov.nasa.jpl.aerie.merlin.protocol.types.Duration;

import java.util.Objects;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;

import static gov.nasa.jpl.aerie.merlin.framework.ModelActions.*;
import static gov.nasa.jpl.aerie.merlin.protocol.types.Duration.SECOND;

/**
* Simple resource that samples arbitrarily many existing resources/values at a specified period (default period is once
* per second).
*/
public class SampledResource<T> implements DiscreteResource<T> {
private final Register<T> result;
private final Supplier<T> sampler;
private final Register<Double> period = Register.forImmutable(1.0);

/**
* Constructor that does not require caller to specify a period and therefore assumes a sample
* period of 1 sample per second.
*/
public SampledResource(final Supplier<T> sampler, final UnaryOperator<T> duplicator) {
this.result = Register.create(sampler.get(), duplicator);
this.sampler = Objects.requireNonNull(sampler);
spawn(this::takeSamples);
}

/**
* Constructor that requires caller to specify an initial sample period
*/
public SampledResource(final Supplier<T> sampler, final UnaryOperator<T> duplicator, final double period) {
this.result = Register.create(sampler.get(), duplicator);
this.sampler = Objects.requireNonNull(sampler);
this.period.set(period);
spawn(this::takeSamples);
}

/**
* Method that samples the supplied resource at the current specified period
*/
private void takeSamples() {
while (true) {
var sample = sampler.get();
if (!result.get().equals(sample)) {
result.set(sample);
}
delay(1, SECOND);
delay( Duration.roundNearest(period.get(), Duration.SECONDS) );
}
}

/**
* Get current sample period (seconds per sample)
*/
public double getPeriod() { return period.get(); }

/**
* Method to adjust the specified period of sampling. Note if takeSamples() is currently waiting, the
* new period will not take effect until after the current wait cycle.
*/
public void setPeriod(final double newPeriod ) { period.set( newPeriod ); }

@Override
public T getDynamics() {
return this.result.getDynamics();
Expand Down

0 comments on commit 42dd18c

Please sign in to comment.