public void Test_TerrainSwather_SwathExtentTooLarge() { var siteModel = new SiteModel(StorageMutability.Immutable); var machine = new Machine(); var grid = new ServerSubGridTree(siteModel.ID, StorageMutability.Mutable); var SiteModelGridAggregator = new ServerSubGridTree(siteModel.ID, StorageMutability.Mutable); var MachineTargetValueChangesAggregator = new ProductionEventLists(siteModel, MachineConsts.kNullInternalSiteModelMachineIndex); var processor = new TAGProcessor(siteModel, machine, SiteModelGridAggregator, MachineTargetValueChangesAggregator); var fence = new Fence(new BoundingWorldExtent3D(0, 0, 10000, 2)); var swather = new TerrainSwather(processor, MachineTargetValueChangesAggregator, siteModel, grid, fence); CreateSwathContext(0, 0, 0, 10000, 0, 0, 0, 2, 0, 10000, 2, 0, out SimpleTriangle HeightInterpolator1, out SimpleTriangle HeightInterpolator2, out SimpleTriangle TimeInterpolator1, out SimpleTriangle TimeInterpolator2); bool swathResult = swather.PerformSwathing(HeightInterpolator1, HeightInterpolator2, TimeInterpolator1, TimeInterpolator2, false, PassType.Front, MachineSide.None); swathResult.Should().BeTrue(); processor.ProcessedEpochCount.Should().Be(0); processor.ProcessedCellPassesCount.Should().Be(0); }
public void Test_TAGProcessor_DoPostProcessFileAction() { var SiteModel = new SiteModel(StorageMutability.Immutable); var Machine = new Machine(); var SiteModelGridAggregator = new ServerSubGridTree(SiteModel.ID, StorageMutability.Mutable); var MachineTargetValueChangesAggregator = new ProductionEventLists(SiteModel, MachineConsts.kNullInternalSiteModelMachineIndex); TAGProcessor processor = new TAGProcessor(SiteModel, Machine, SiteModelGridAggregator, MachineTargetValueChangesAggregator); // Set the state of the processor to emulate the end of processing this TAG file at which point the processor should emit // a "Stop recording event". In this instance, the NoGPSModeSet flag will also be true which should trigger emission of // a 'NoGPS' GPS mode state event and a 'UTS' positioning technology state event DateTime eventDate = DateTime.SpecifyKind(new DateTime(2000, 1, 1, 1, 1, 1), DateTimeKind.Utc); // Setting the first data time will create the start event processor.DataTime = eventDate; DateTime eventDate2 = eventDate.AddMinutes(1); processor.DataTime = eventDate2; processor.DoPostProcessFileAction(true); Assert.True(MachineTargetValueChangesAggregator.GPSModeStateEvents.LastStateValue() == GPSMode.NoGPS && MachineTargetValueChangesAggregator.GPSModeStateEvents.LastStateDate() == eventDate, "DoPostProcessFileAction did not set GPSMode event"); Assert.True(MachineTargetValueChangesAggregator.PositioningTechStateEvents.LastStateValue() == PositioningTech.UTS && MachineTargetValueChangesAggregator.PositioningTechStateEvents.LastStateDate() == eventDate, "DoPostProcessFileAction did not set positioning tech event"); Assert.True(MachineTargetValueChangesAggregator.StartEndRecordedDataEvents.LastStateValue() == ProductionEventType.EndEvent /*EndRecordedData*/ && MachineTargetValueChangesAggregator.StartEndRecordedDataEvents.LastStateDate() == eventDate2, "DoPostProcessFileAction did not set end recorded data event"); }
public void Test_TAGProcessor_DoEpochStateEvent() { var processor = new TAGProcessor(); Action act = () => processor.DoEpochStateEvent(EpochStateEvent.Unknown); act.Should().Throw <TRexTAGFileProcessingException>().WithMessage("*Unknown epoch state event type*"); }
public void Test_TAGProcessor_Creation() { var SiteModel = new SiteModel(StorageMutability.Immutable); var Machine = new Machine(); var SiteModelGridAggregator = new ServerSubGridTree(SiteModel.ID, StorageMutability.Mutable); var MachineTargetValueChangesAggregator = new ProductionEventLists(SiteModel, MachineConsts.kNullInternalSiteModelMachineIndex); TAGProcessor processor = new TAGProcessor(SiteModel, Machine, SiteModelGridAggregator, MachineTargetValueChangesAggregator); Assert.NotNull(processor); }
public void Test_TAGProcessor_DoEpochPreProcessAction() { var SiteModel = new SiteModel(StorageMutability.Immutable); var Machine = new Machine(); var SiteModelGridAggregator = new ServerSubGridTree(SiteModel.ID, StorageMutability.Mutable); var MachineTargetValueChangesAggregator = new ProductionEventLists(SiteModel, MachineConsts.kNullInternalSiteModelMachineIndex); TAGProcessor processor = new TAGProcessor(SiteModel, Machine, SiteModelGridAggregator, MachineTargetValueChangesAggregator); Assert.True(processor.DoEpochPreProcessAction(), "EpochPreProcessAction returned false in default TAGProcessor state"); // Current PreProcessAction activity is limited to handling proofing runs. This will be handled by proofing run tests elsewhere }
public void Test_TerrainSwather_Creation() { var siteModel = new SiteModel(StorageMutability.Immutable); var machine = new Machine(); var grid = new ServerSubGridTree(siteModel.ID, StorageMutability.Mutable); var fence = new Fence(); var SiteModelGridAggregator = new ServerSubGridTree(siteModel.ID, StorageMutability.Mutable); var MachineTargetValueChangesAggregator = new ProductionEventLists(siteModel, MachineConsts.kNullInternalSiteModelMachineIndex); var processor = new TAGProcessor(siteModel, machine, SiteModelGridAggregator, MachineTargetValueChangesAggregator); var swather = new TerrainSwather(processor, MachineTargetValueChangesAggregator, siteModel, grid, fence); Assert.True(swather != null, "TerrainSwather not created as expected"); }
/// <summary> /// Fill out the local class properties with the information wanted from the TAG file /// </summary> /// <param name="processor"></param> private void SetPublishedState(TAGProcessor processor) { ProcessedEpochCount = processor.ProcessedEpochCount; ProcessedCellPassCount = processor.ProcessedCellPassesCount; // Set the site model's last modified date... SiteModel.LastModifiedDate = DateTime.UtcNow; //Update latest status for the machine Machine.LastKnownX = processor.DataLeft.X; Machine.LastKnownY = processor.DataLeft.Y; Machine.LastKnownPositionTimeStamp = processor.DataTime; Machine.MachineHardwareID = processor.HardwareID; Machine.MachineType = processor.MachineType; Machine.Name = processor.MachineID; }
public void LoadFile() { using var stream = new FileStream(FILENAME, FileMode.Open, FileAccess.Read); var file = new VolvoEarthworksCSVReader(stream); var siteModel = new SiteModel(StorageMutability.Immutable); var machine = new Machine(); var siteModelGridAggregator = new ServerSubGridTree(siteModel.ID, StorageMutability.Mutable); var machineTargetValueChangesAggregator = new ProductionEventLists(siteModel, MachineConsts.kNullInternalSiteModelMachineIndex); var processor = new TAGProcessor(siteModel, machine, siteModelGridAggregator, machineTargetValueChangesAggregator); file.Read(null, processor); processor.ProcessedEpochCount.Should().Be(19325); siteModelGridAggregator.CountLeafSubGridsInMemory().Should().Be(11); }
public void Test_TAGProcessor_TestZeroValuesInvalid() { var SiteModel = new SiteModel(StorageMutability.Immutable); var Machine = new Machine(); var SiteModelGridAggregator = new ServerSubGridTree(SiteModel.ID, StorageMutability.Mutable); var MachineTargetValueChangesAggregator = new ProductionEventLists(SiteModel, MachineConsts.kNullInternalSiteModelMachineIndex); TAGProcessor processor = new TAGProcessor(SiteModel, Machine, SiteModelGridAggregator, MachineTargetValueChangesAggregator); Assert.True(processor.ICMDPValues.GetLatest() == CellPassConsts.NullMDP, "MDP Initial value incorrect"); Assert.True(processor.ICCCVValues.GetLatest() == CellPassConsts.NullCCV, "CCV Initial value incorrect"); Assert.True(processor.ICCCAValues.GetLatest() == CellPassConsts.NullCCA, "CCA Initial value incorrect"); processor.SetICMDPValue(0); processor.SetICCCVValue(0); processor.SetICCCAValue(0); Assert.True(processor.ICMDPValues.GetLatest() == CellPassConsts.NullMDP, "Zero should not be a valid for MDP"); Assert.True(processor.ICCCVValues.GetLatest() == CellPassConsts.NullCCV, "Zero should not be a valid for CCV"); Assert.True(processor.ICCCAValues.GetLatest() == CellPassConsts.NullCCA, "Zero should not be a valid for CCA"); }
public void Test_TAGProcessor_ProcessEpochContext_WithValidPosition() { var SiteModel = new SiteModel(StorageMutability.Immutable); SiteModel.IgnoreInvalidPositions = false; var Machine = new Machine(); var SiteModelGridAggregator = new ServerSubGridTree(SiteModel.ID, StorageMutability.Mutable); var MachineTargetValueChangesAggregator = new ProductionEventLists(SiteModel, MachineConsts.kNullInternalSiteModelMachineIndex); TAGProcessor processor = new TAGProcessor(SiteModel, Machine, SiteModelGridAggregator, MachineTargetValueChangesAggregator); // Set the blade left and right tip locations to a trivial epoch, the epoch and do it again to trigger a swathing scan, then // check to see if it generated anything! Fence interpolationFence = new Fence(); interpolationFence.SetRectangleFence(0, 0, 1, 1); DateTime StartTime = DateTime.SpecifyKind(new DateTime(2000, 1, 1, 1, 1, 1), DateTimeKind.Utc); processor.DataLeft = new XYZ(0, 0, 5); processor.DataRight = new XYZ(1, 0, 5); processor.DataTime = StartTime; Assert.True(processor.ProcessEpochContext(), "ProcessEpochContext returned false in default TAGProcessor state (1)"); DateTime EndTime = DateTime.SpecifyKind(new DateTime(2000, 1, 1, 1, 1, 3), DateTimeKind.Utc); processor.DataLeft = new XYZ(0, 1, 5); processor.DataRight = new XYZ(1, 1, 5); processor.DataTime = EndTime; Assert.True(processor.ProcessEpochContext(), "ProcessEpochContext returned false in default TAGProcessor state (2)"); Assert.Equal(9, processor.ProcessedCellPassesCount); Assert.Equal(2, processor.ProcessedEpochCount); }
public void Test_TAGProcessor_ProcessEpochContext_WithoutValidTimestamp() { var SiteModel = new SiteModel(StorageMutability.Immutable); SiteModel.IgnoreInvalidPositions = false; var Machine = new Machine(); var SiteModelGridAggregator = new ServerSubGridTree(SiteModel.ID, StorageMutability.Mutable); var MachineTargetValueChangesAggregator = new ProductionEventLists(SiteModel, MachineConsts.kNullInternalSiteModelMachineIndex); TAGProcessor processor = new TAGProcessor(SiteModel, Machine, SiteModelGridAggregator, MachineTargetValueChangesAggregator); // Set the blade left and right tip locations to a trivial epoch, the epoch and do it again to trigger a swathing scan, then // check to see if it generated anything! Fence interpolationFence = new Fence(); interpolationFence.SetRectangleFence(0, 0, 1, 1); processor.DataLeft = new XYZ(0, 0, 5); processor.DataRight = new XYZ(1, 0, 5); Assert.False(processor.ProcessEpochContext(), "ProcessEpochContext returned true without a valid epoch timestamp"); }
public void Test_TerrainSwather_PerformSwathing() { var siteModel = new SiteModel(StorageMutability.Immutable); var machine = new VSS.TRex.Machines.Machine(); var grid = new ServerSubGridTree(siteModel.ID, StorageMutability.Mutable); var SiteModelGridAggregator = new ServerSubGridTree(siteModel.ID, StorageMutability.Mutable); var MachineTargetValueChangesAggregator = new ProductionEventLists(siteModel, MachineConsts.kNullInternalSiteModelMachineIndex); var processor = new TAGProcessor(siteModel, machine, SiteModelGridAggregator, MachineTargetValueChangesAggregator); var fence = new Fence(); fence.SetRectangleFence(0, 0, 10, 2); TerrainSwather swather = new TerrainSwather(processor, MachineTargetValueChangesAggregator, siteModel, grid, fence); CreateSwathContext(0, 0, 0, 10, 0, 0, 0, 2, 0, 10, 2, 0, out SimpleTriangle HeightInterpolator1, out SimpleTriangle HeightInterpolator2, out SimpleTriangle TimeInterpolator1, out SimpleTriangle TimeInterpolator2); // Compute swath with full cell pass on the front (blade) measurement location bool swathResult = swather.PerformSwathing(HeightInterpolator1, HeightInterpolator2, TimeInterpolator1, TimeInterpolator2, false, PassType.Front, MachineSide.None); // Did the swathing operation succeed? Assert.True(swathResult, "Perform swathing failed"); // Did it produce the expected set of swathed cells? Assert.Equal(1, grid.Root.CountChildren()); // Computation of the latest pass information which aids locating cells with non-null values try { IStorageProxy storageProxy = StorageProxy.Instance(StorageMutability.Mutable); grid.Root.ScanSubGrids(grid.FullCellExtent(), x => { ((IServerLeafSubGrid)x).ComputeLatestPassInformation(true, storageProxy); return(true); }); } catch (Exception E) { Assert.False(true, $"Exception {E} occured computing latest cell information"); } grid.CalculateIndexOfCellContainingPosition(grid.CellSize / 2, grid.CellSize / 2, out int _, out int _); int nonNullCellCount = 0; try { grid.Root.ScanSubGrids(grid.FullCellExtent(), x => { nonNullCellCount += ((IServerLeafSubGrid)x).CountNonNullCells(); return(true); }); } catch (Exception e) { Assert.False(true, $"Exception {e} occured counting non-null cells"); } Assert.Equal(174, nonNullCellCount); // Todo: Iterate over the cells and confirm their content is as expected }
/// <summary> /// Execute the conversion operation on the TAG file, returning a boolean success result. /// Sets up local state detailing the pre-scan fields retrieved from the TAG file /// </summary> public bool ExecuteLegacyTAGFile(string filename, Stream tagData, Guid assetUid, bool isJohnDoe) { Log.LogInformation($"In {nameof(ExecuteLegacyTAGFile)}: reading file {filename} for asset {assetUid}, JohnDoe: {isJohnDoe}"); ReadResult = TAGReadResult.NoError; List <UTMCoordPointPair> aCSBladePositions = null; List <UTMCoordPointPair> ACSRearAxlePositions = null; List <UTMCoordPointPair> ACSTrackPositions = null; List <UTMCoordPointPair> ACSWheelPositions = null; try { Processor?.Dispose(); // Locate the machine in the local set of machines, adding one if necessary Machine = Machines.Locate(assetUid, isJohnDoe); var machineType = MachineType.Unknown; var machineHardwareId = string.Empty; var machineId = string.Empty; //Prescan to get all relevant information necessary for processing the tag file. e.g. Machinetype for swather, Type of coordinate system (ACS) var tagFilePreScan = new TAGFilePreScan(); tagFilePreScan.Execute(tagData); tagData.Position = 0; // reset if (tagFilePreScan.ReadResult == TAGReadResult.NoError) { machineType = tagFilePreScan.MachineType; // used in creation of swather machineHardwareId = tagFilePreScan.HardwareID; machineId = tagFilePreScan.MachineID; IsUTMCoordinateSystem = !tagFilePreScan.IsCSIBCoordSystemTypeOnly; // do we need to convert UTM coordinates to project coordinates if (IsUTMCoordinateSystem && tagFilePreScan.ProcessedEpochCount > 0) { Log.LogInformation($"{nameof(ExecuteLegacyTAGFile)}: ACS coordinate system detected. {filename}"); aCSBladePositions = new List <UTMCoordPointPair>(); ACSRearAxlePositions = new List <UTMCoordPointPair>(); ACSTrackPositions = new List <UTMCoordPointPair>(); ACSWheelPositions = new List <UTMCoordPointPair>(); if (!CollectAndConvertBladePostions(_targetSiteModel, ref tagData, ref aCSBladePositions, ref ACSRearAxlePositions, ref ACSTrackPositions, ref ACSWheelPositions)) { Log.LogError($"{nameof(ExecuteLegacyTAGFile)}: Failed to collect and convert blade positions for tagfile processing with ACS. TAG FILE:{filename}"); ReadResult = TAGReadResult.CoordinateConversionFailure; return(false); } } } else { Log.LogError($"Unsuccessful prescan of tagfile. {tagFilePreScan.ReadResult}"); return(false); } if (Machine == null) { // Now we know more about the machine have another go finding it Machine = Machines.Locate(assetUid, machineId, isJohnDoe); } if (Machine == null) { Log.LogDebug($"Creating new machine in common converter for AssetUid = {assetUid}, JohnDoe = {isJohnDoe}, machineId = {machineId}, machineHardwareId = {machineHardwareId}"); Machine = Machines.CreateNew(machineId, machineHardwareId, machineType, DeviceTypeEnum.MANUALDEVICE, isJohnDoe, assetUid); } if (Machine.MachineType == MachineType.Unknown && machineType != MachineType.Unknown) { Machine.MachineType = machineType; } var holdMachineType = Machine.MachineType; // Locate the aggregator, adding one if necessary var machineTargetValueChangesAggregator = MachinesTargetValueChangesAggregator[Machine.InternalSiteModelMachineIndex] as ProductionEventLists; if (machineTargetValueChangesAggregator == null) { machineTargetValueChangesAggregator = new ProductionEventLists(SiteModel, Machine.InternalSiteModelMachineIndex); MachinesTargetValueChangesAggregator.Add(machineTargetValueChangesAggregator); } Processor = new TAGProcessor(SiteModel, Machine, SiteModelGridAggregator, machineTargetValueChangesAggregator); // If ACS coordinate system populate converted UTM coordinates if (IsUTMCoordinateSystem && tagFilePreScan.ProcessedEpochCount > 0) { if (aCSBladePositions != null && aCSBladePositions.Count > 0) { Processor.ConvertedBladePositions.AddRange(aCSBladePositions); } if (ACSRearAxlePositions != null && ACSRearAxlePositions.Count > 0) { Processor.ConvertedRearAxlePositions.AddRange(ACSRearAxlePositions); } if (ACSTrackPositions != null && ACSTrackPositions.Count > 0) { Processor.ConvertedTrackPositions.AddRange(ACSTrackPositions); } if (ACSWheelPositions != null && ACSWheelPositions.Count > 0) { Processor.ConvertedWheelPositions.AddRange(ACSWheelPositions); } } var sink = new TAGValueSink(Processor); using (var reader = new TAGReader(tagData)) { var tagFile = new TAGFile(); ReadResult = tagFile.Read(reader, sink); // Notify the processor that all reading operations have completed for the file Processor.DoPostProcessFileAction(ReadResult == TAGReadResult.NoError); SetPublishedState(Processor); Machine.MachineType = holdMachineType; if (ReadResult != TAGReadResult.NoError) { return(false); } } } catch (Exception e) // make sure any exception is trapped to return correct response to caller { Log.LogError(e, "Exception occurred while converting a TAG file"); return(false); } return(true); }
/// <summary> /// Execute the conversion operation on the Volvo earthworks CSV file /// NOTE: This is a POC implementation and does not support some behaviours in the legacy TAG file ingest pathway /// </summary> public bool ExecuteVolvoEarthworksCSVFile(string filename, Stream tagData, Guid assetUid, bool isJohnDoe) { ReadResult = TAGReadResult.NoError; Log.LogInformation($"In {nameof(ExecuteVolvoEarthworksCSVFile)}: reading file {filename} for asset {assetUid}, JohnDoe: {isJohnDoe}"); try { var fileDescriptor = new VolvoEarthworksFileNameDescriptor(filename); Processor?.Dispose(); // Locate the machine in the local set of machines, adding one if necessary Machine = Machines.Locate(assetUid, true /*isJohnDoe - hard code Volvo machines to be John Does for POC*/); var machineType = MachineType.Unknown; var machineHardwareId = fileDescriptor.MachineID; var machineId = fileDescriptor.MachineID; if (Machine == null) { Log.LogDebug($"Creating new machine in common converter for AssetUid = {assetUid}, JohnDoe = {isJohnDoe}, machineId = {machineId}, machineHardwareId = {machineHardwareId}"); Machine = Machines.CreateNew(machineId, machineHardwareId, machineType, DeviceTypeEnum.MANUALDEVICE, isJohnDoe, assetUid); } var holdMachineType = Machine.MachineType; // Locate the aggregator, adding one if necessary var machineTargetValueChangesAggregator = MachinesTargetValueChangesAggregator[Machine.InternalSiteModelMachineIndex] as ProductionEventLists; if (machineTargetValueChangesAggregator == null) { machineTargetValueChangesAggregator = new ProductionEventLists(SiteModel, Machine.InternalSiteModelMachineIndex); MachinesTargetValueChangesAggregator.Add(machineTargetValueChangesAggregator); } Processor = new TAGProcessor(SiteModel, Machine, SiteModelGridAggregator, machineTargetValueChangesAggregator); var sink = new TAGValueSink(Processor); var reader = new VolvoEarthworksCSVReader(tagData); ReadResult = reader.Read(sink, Processor); // Notify the processor that all reading operations have completed for the file Processor.DoPostProcessFileAction(ReadResult == TAGReadResult.NoError); SetPublishedState(Processor); Machine.MachineType = holdMachineType; if (ReadResult != TAGReadResult.NoError) { return(false); } } catch (Exception e) // make sure any exception is trapped to return correct response to caller { Log.LogError(e, "Exception occurred while converting a Volvo CSV file"); return(false); } return(true); }
/// <summary> /// Reads the context of a Volvo earthworks CSV file using the provided sink to send data to /// Note: LastEDV value is not handled as it has no corresponding value in TRex /// </summary> public TAGReadResult Read(TAGValueSinkBase sink, TAGProcessor processor) { using var streamReader = new StreamReader(_stream, Encoding.ASCII); var headerLine = streamReader.ReadLine(); var headerIndex = 0; _headerLocations = headerLine.Split(',').Select(x => new KeyValuePair <string, int>(x, headerIndex++)).ToDictionary(k => k.Key, v => v.Value); // Read all remaining lines into an array for easy access var lines = ReadLines(streamReader).ToList(); var swather = new VolvoEarthworksCSVGridSwather(processor, processor.MachineTargetValueChangesAggregator, processor.SiteModel, processor.SiteModelGridAggregator, null) { ProcessedEpochNumber = processor.ProcessedEpochCount }; var currentTime = DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc); //var firstDataTime = // For each line, locate the TRex cell that fall within the cell and add a cell pass for it lines.ForEach(line => { var cellPass = ParseLine(line); if (!cellPass.lineParsedOK) { // Each cell is parsed independently, so we can short circuit processing if a line did not parse return; } processor.DataTime = DateTime.SpecifyKind(cellPass.Time, DateTimeKind.Utc); // There is no RMV in the CSV file - set on ground to be true all the time. processor.SetOnGround(OnGroundState.YesLegacy); // Default Volvo machine to MC024 sensor returning CMV values // TODO: understand if this is a special sensor for Volvo // TODO: understand meaning of the ICMVType field processor.ICSensorType = CompactionSensorType.MC024; // TODO: Understand the relationship of Volvo CMV value to internal CMV value processor.SetICCCVValue((short)Math.Round(cellPass.LastCMV)); processor.MachineType = VolvoEarthworksCSVRecord.MachineTypeFromString(cellPass.Machine); if (processor.MachineType == MachineType.Unknown) { _log.LogDebug($"Machine type name {cellPass.Machine} generated an unknown machine type"); } // Add the events for this line if (currentTime < processor.DataTime) { // Fill in the machine events for this epoch processor.Design = cellPass.DesignName; } // Convert mph to cs/s. 44.704 is the magic mph to cm/s conversion factor var speedInCentimetersPerSecond = (int)Math.Round(cellPass.Speed_mph * 44.704); processor.SetICMachineSpeedValue(speedInCentimetersPerSecond); processor.ICPassTargetValue = (ushort)cellPass.TargetPassCount; processor.ValidPosition = cellPass.ValidPos ? (byte)1 : (byte)0; processor.ICLayerIDValue = (ushort)cellPass.Lift; processor.SetICFrequency((ushort)cellPass.LastFreq_Hz); processor.SetICAmplitude(cellPass.LastAmp_mm == -1000 ? CellPassConsts.NullAmplitude : (ushort)Math.Round(cellPass.LastAmp_mm * 100)); processor.ICTargetLiftThickness = (float)(cellPass.TargThickness_FT / 3.048); processor.ICGear = VolvoEarthworksCSVRecord.MachineGearFromString(cellPass.MachineGear); if (processor.ICGear == MachineGear.Null) { _log.LogDebug($"Machine gear name {cellPass.MachineGear} generated a null machine gear"); } processor.SetICTemperatureValue((ushort)cellPass.LastTemp_f); processor.ICMode = (byte)((cellPass.VibeState == "On" ? 1 : 0) << ICModeFlags.IC_TEMPERATURE_VIBRATION_STATE_SHIFT); // Add the cell pass for this line. // Note: Half pass is hardwired to false, and pass type is hardwired to front drum/blade swather.SwathSingleCell(false, PassType.Front, cellPass.CellE_m, cellPass.CellN_m, VOLVO_EARTHWORKS_GRID_CELL_SIZE, cellPass); processor.ProcessedEpochCount = swather.ProcessedEpochNumber; }); return(TAGReadResult.NoError); }