I am trying to do Orbit determination with BatchLSEstimator for GEO satellites. I have solar radiation pressure as a perturbation force. I am using IsotropicRadiationSingleCoefficient to model the spacecraft. Since the satellite’s mass and area are not precisely known, I am estimating Cr ( reflective coefficient) along with the 6 state vectors ( in Cartesian Orbit). I am using TDOA measurements.
Depending on the size of the measurement data set, I am getting significantly different values for Cr.
The 6 state vector values only change slightly and this is expected. But I am confused about the Cr.

Satellite 2
24 hr data : 3.458991095
48 hr data : 0.687749776
72 hr data : 0.550549534
12 hr data : -159.2042332
(Similar size data set as sat1)
When the data set to small, the estimated Cr value is negative.
I am bit confused about this results. I appreciate some explanations as to why this is happening.

Having negative values for the reflection coefficient highlights estimation difficulties. The optimizer has difficulties to estimate physical values. In other words, they are observability issues.

Generally speaking, the more measurements you have, the better the observability of your problem is. The obtained values for the different measurement time span highlights this behavior. Also, the accuracy of your measurements (i.e., the sigma value) can have a significant impact.

If you have a lot of uncertainty in the satellite’s surface and mass, I’m not surprised. What values do you set for the mass and surface? These values will greatly influence the estimation of the reflection coefficient.

What you could also try is to set a minimum value for the reflection coefficient. Let force be your SolarRadiationPressure force model with a IsotropicRadiationSingleCoefficient model. Updating the minimum value can be done force.getParametersDrivers().get(0).setMinValue(0.0)

Finally, could you show us how do you initialize the numerical propagator (including force models) ulto see if there is no mistakes?

I am using BatchLSObserver with gaussNewton optimizer.

I believe the accuracy of the measurements are high. But being a GEO communication satellite, the satellite could maneuver multiple times if the measurement period is longer. Therefore increasing the measurement period could be problematic.
My OD code does not handle maneuver as I am yet to figure out whether it can be done / and how to in Orekit.
I am using some dummy values for mass and area. (mass = 1000kg, default value / area = 25.0m2).
I will explorer your suggesting for minimal values. Thank you.
Also I only used Gravity, Third body attraction and solar radiation pressure. The orbit state vector values without solar radiation pressure(SRP) are quite close to state vector with SRP. I would assume the satellite either has a very low reflectivity, low area to mass ratio or both.

final static OrbitDeterminationPropagatorBuilder initializePropagator(inal ODEIntegratorBuilder integrator,
final Orbit initialOrbit, final OneAxisEllipsoid centralBody, final SphericalHarmonicsProvider gravityField) {
// Initialize the numerical builder
final double positionScale = 1.0; // position scale : Scaling factor for orbital parameter normalization, Typically set to expected std of the position
final PositionAngle posAngle = PositionAngle.MEAN; // Enumerate for true, eccentric and mean position angles.
final NumericalPropagatorBuilder numPropagator = new NumericalPropagatorBuilder(initialOrbit, integrator,posAngle,positionScale);
final CelestialBody body = CelestialBodyFactory.getBody("sun");
numPropagator.addForceModel(new ThirdBodyAttraction(body));
final CelestialBody body = CelestialBodyFactory.getBody("moon");
numPropagator.addForceModel(new ThirdBodyAttraction(body));
numPropagator.addForceModel(new HolmesFeatherstoneAttractionModel(centralBody.getBodyFrame(), (NormalizedSphericalHarmonicsProvider) gravityField));
double cr = 1.5;
double solarEffectiveArea = 25.0;
//satellite model
RadiationSensitive spacecraft = new IsotropicRadiationSingleCoefficient(solarEffectiveArea, cr);
final SolarRadiationPressure solarPressureForce = new SolarRadiationPressure(CelestialBodyFactory.getSun(), centralBody.getEquatorialRadius(), spacecraft);
for (final ParameterDriver driver : solarPressureForce.getParametersDrivers()) {
if (driver.getName().equals(RadiationSensitive.REFLECTION_COEFFICIENT)) {
driver.setSelected(true);
}
System.out.println("Solar Radiation pressure added to propagator");
numPropagator.addForceModel(solarPressureForce);
}

Above is the simplified propagator code. ( I am using a parameter file similar to Orekit-Tutorial and have not included the whole code as it is lengthy).

To initialize the Java objects modelling maneuvers, you have different examples in different place. First, you can look at the tests classes. Then, you can look at the different tutorials:

ApogeeManeuver : model an apogee maneuver with a constant thrust.

If there is an unmodeled maneuver in the first 24H, I am not surprised at the negative value of the reflection coefficient. The coefficient absorbs unmodeled dynamic effects and its estimated value is not physical.
I remember an Orekit validation test using the W3B satellite. The particularity of this satellite is that its life ended because of a leak. At the beginning, Orekit had not modeled the leak and the estimated reflection coefficient was therefore about -1000 Now Orekit can model the leak, using an empirical acceleration, and the reflection coefficient is well estimated.