예제 #1
0
        private void ProcessMarker(MarkerPair marker)
        {
            var   positions  = new List <Vector3>();
            var   rotations  = new List <Quaternion>();
            int   id         = -1;
            float confidence = 0;

            if (marker.Left != null)
            {
                var matrixRaw       = MatrixFromFloatArray(marker.Left.transformation_matrix);
                var transformMatrix = LHMatrixFromRHMatrix(matrixRaw);
                positions.Add(transformMatrix.GetPosition() + new Vector3(OffsetLeft, 0, 0));
                rotations.Add(transformMatrix.GetRotation());
                id         = marker.Left.id;
                confidence = Mathf.Max(confidence, marker.Left.confidence);
            }

            if (marker.Right != null)
            {
                var matrixRaw       = MatrixFromFloatArray(marker.Right.transformation_matrix);
                var transformMatrix = LHMatrixFromRHMatrix(matrixRaw);
                positions.Add(transformMatrix.GetPosition() + new Vector3(OffsetRight, 0, 0));
                rotations.Add(transformMatrix.GetRotation());
                id         = marker.Right.id;
                confidence = Mathf.Max(confidence, marker.Right.confidence);
            }

            OnNewPoseDetected(new MarkerPose
            {
                Id         = id,
                Confidence = confidence,
                Position   = MathUtility.Average(positions),
                Rotation   = MathUtility.Average(rotations)
            });
        }
예제 #2
0
        private void CalculateEnthalpyFromVaporFraction(double pValue, double vfValue, double moistureContentValue)
        {
            double massConcentrationValue  = 1.0 - moistureContentValue;
            double tBoilingPointOfSolution = GetBoilingPoint(pValue, massConcentrationValue);

            massConcentrationValue = massConcentrationValue / (1.0 - vfValue);
            double tBoilingPointOfSolutionFinal = GetBoilingPoint(pValue, massConcentrationValue);
            double evapHeat         = GetEvaporationHeat(MathUtility.Average(tBoilingPointOfSolution, tBoilingPointOfSolutionFinal));
            double moistureLiquidCp = MoistureProperties.GetSpecificHeatOfLiquid(MathUtility.Average(tBoilingPointOfSolution, tBoilingPointOfSolutionFinal));
            double cs                = GetCpOfAbsoluteDryMaterial();
            double hBubble           = GetBubblePointEnthalpy(pValue, moistureContentValue);
            double hBoilingPointRise = (moistureContentValue * moistureLiquidCp + (1.0 - moistureContentValue) * cs) * (tBoilingPointOfSolutionFinal - tBoilingPointOfSolution);
            double h = hBubble + hBoilingPointRise + vfValue * evapHeat;

            Calculate(specificEnthalpy, h);
            Calculate(temperature, tBoilingPointOfSolution);

            if (!specificHeat.HasValue)
            {
                double cp;
                if (Math.Abs(vfValue - 1.0) < 1.0e-5)
                {
                    cp = GetGasCp(tBoilingPointOfSolution);
                }
                else
                {
                    cp = CalculateCp(tBoilingPointOfSolution);
                }

                Calculate(specificHeat, cp);
            }
        }
 private void OnDrawGizmos()
 {
     if (Samples.Count > 0)
     {
         var positionAvg = MathUtility.Average(Samples.Select(t => t.Item1));
         var rotationAvg = MathUtility.Average(Samples.Select(t => t.Item2));
         Gizmos.DrawCube(positionAvg, Vector3.one * 0.01f);
         GizmosExtension.DrawRotation(positionAvg, rotationAvg, 0.1f);
     }
 }
예제 #4
0
        //Calculate hot side heat transfer coefficient
        public override double GetColdSideLiquidPhaseHeatTransferCoeff(double tBulk, double tWall, double massFlowRate)
        {
            double bulkVisc     = MathUtility.Average(owner.ColdSideInlet.GetLiquidViscosity(tBulk), owner.ColdSideOutlet.GetLiquidViscosity(tBulk));
            double wallVisc     = MathUtility.Average(owner.ColdSideInlet.GetLiquidViscosity(tWall), owner.ColdSideOutlet.GetLiquidViscosity(tWall));
            double thermalCond  = MathUtility.Average(owner.ColdSideInlet.GetLiquidThermalConductivity(tBulk), owner.ColdSideOutlet.GetLiquidThermalConductivity(tBulk));
            double specificHeat = MathUtility.Average(owner.ColdSideInlet.GetLiquidCp(tBulk), owner.ColdSideOutlet.GetLiquidCp(tBulk));
            double Re           = GetReynoldsNumber(massFlowRate, bulkVisc, coldSidePasses.Value);
            double De           = GetChannelEquivalentDiameter();

            return(CalculateSinglePhaseHTC(Re, De, bulkVisc, wallVisc, thermalCond, specificHeat));
        }
예제 #5
0
        protected void CalculateHTUAndExchEffectiveness()
        {
            //number of heat tranfer units
            //Chemical Equipment Chapter 8, page 179
            double cpCold = MathUtility.Average(owner.ColdSideInlet.SpecificHeat.Value, owner.ColdSideOutlet.SpecificHeat.Value);
            double cpHot  = MathUtility.Average(owner.HotSideInlet.SpecificHeat.Value, owner.HotSideOutlet.SpecificHeat.Value);
            double mcCold = owner.ColdSideInlet.MassFlowRate.Value * cpCold;
            double mcHot  = owner.HotSideInlet.MassFlowRate.Value * cpHot;
            //double massFlowCold = coldSideInlet.MassFlowRate.Value;
            //double massFlowHot = hotSideInlet.MassFlowRate.Value;
            double mcMin = mcCold < mcHot ? mcCold : mcHot;
            //double htArea = totalHeatTransferArea.Value;
            double totalHtc  = totalHeatTransferCoefficient.Value;
            double totalHeat = owner.TotalHeatTransfer.Value;

            double tColdIn  = owner.ColdSideInlet.Temperature.Value;
            double tColdOut = owner.ColdSideOutlet.Temperature.Value;
            double tHotIn   = owner.HotSideInlet.Temperature.Value;
            double tHotOut  = owner.HotSideOutlet.Temperature.Value;
            //hCold = coldSideHeatTransferCoefficient.Value;
            //hHot = hotSideHeatTransferCoefficient.Value;

            double lmtd = CalculateLmtd(tHotIn, tHotOut, tColdIn, tColdOut);

            double ft = GetFtFactor(tHotIn, tHotOut, tColdIn, tColdOut);

            if (this is HXRatingModelShellAndTube)
            {
                HXRatingModelShellAndTube model = this as HXRatingModelShellAndTube;
                owner.Calculate(model.FtFactor, ft);
            }

            if (Math.Abs(lmtd) > 1.0e-8)
            {
                double ua = totalHeat / (ft * lmtd);
                //owner.Calculate(totalHeatTransferArea, totalArea);
                double ntu = ua / mcMin;
                double c   = mcCold < mcHot ? mcCold / mcHot : mcHot / mcCold;
                double p;
                if (IsParallelFlow())
                {
                    p = (1.0 - Math.Exp(-ntu * (1.0 + c))) / (1.0 + c);
                }
                else
                {
                    p = (1.0 - Math.Exp(-ntu * (1.0 - c))) / (1.0 - c * Math.Exp(-ntu * (1.0 - c)));
                }

                owner.Calculate(numberOfHeatTransferUnits, ntu);
                owner.Calculate(exchangerEffectiveness, p);
            }
        }
예제 #6
0
        //Calculate hot side heat transfer coefficient
        public override double GetHotSideLiquidPhasePressureDrop(double tBulk, double tWall, double massFlowRate)
        {
            double density        = MathUtility.Average(owner.HotSideInlet.GetLiquidDensity(tBulk), owner.HotSideOutlet.GetLiquidDensity(tBulk));
            double bulkVisc       = MathUtility.Average(owner.HotSideInlet.GetLiquidViscosity(tBulk), owner.HotSideOutlet.GetLiquidViscosity(tBulk));
            double wallVisc       = MathUtility.Average(owner.HotSideInlet.GetLiquidViscosity(tWall), owner.HotSideOutlet.GetLiquidViscosity(tWall));
            int    numberOfPasses = hotSidePasses.Value;
            double massVelocity   = GetMassVelocity(massFlowRate, numberOfPasses);
            double Re             = GetReynoldsNumber(massFlowRate, bulkVisc, numberOfPasses);

            double dpChannel = CalculateSinglePhaseChannelDP(Re, massVelocity, bulkVisc, wallVisc, density, numberOfPasses);
            double dpPort    = CalculatePortDP(massFlowRate, density, numberOfPasses);

            return(dpChannel + dpPort);
        }
예제 #7
0
        private IEnumerator SetMarker()
        {
            var positionSamples = Vector3.zero;
            var rotationSamples = new List <Quaternion>();
            int sampleCount     = 0;

            CanSetMarker = false;

            while (SetMarkerProgress < 1f)
            {
                sampleCount++;
                positionSamples += _markerPreview.transform.position;
                rotationSamples.Add(_markerPreview.transform.rotation);

                SetMarkerProgress += 0.05f;
                yield return(new WaitForSeconds(0.1f));
            }

            var avgRotation = Quaternion.identity;

            if (sampleCount > 0)
            {
                positionSamples = positionSamples / sampleCount;
                avgRotation     = MathUtility.Average(rotationSamples);
            }

            var createdMarker = Instantiate(MarkerPrefab);

            createdMarker.name = String.Format("Marker_{0}", _currentCalibratingMarkerId);
            createdMarker.GetComponent <MultiMarker_Debug_CameraIndicator>().MarkerId = _currentCalibratingMarkerId;
            createdMarker.transform.position = positionSamples;
            createdMarker.transform.rotation = avgRotation;

            CanSetMarker      = true;
            SetMarkerProgress = 0f;

            CalibratedMarkers.Add(new CalibratedMarkerObject
            {
                Id     = _currentCalibratingMarkerId,
                Marker = createdMarker
            });
        }
예제 #8
0
        private void PerformCalibration()
        {
            var validMarkers = ArMarkers.GetAll().Where(m => IsArMarkerValid(m));

            if (validMarkers.Count() > 0)
            {
                var camPositions   = validMarkers.Select(m => m.DetectedCameraPosition);
                var avgCamPosition = MathUtility.Average(camPositions);
                //var optitrackPose = OptitrackListener.GetPose(Globals.OptitrackHmdName);
                //Debug.Assert(optitrackPose != null, "OptitrackPose shall not be null, since we checked for that in ShouldCalibrate??");
                var hmdRotation = VRListener.CurrentRotation;
                var hmdPosition = VRListener.CurrentPosition;
                CalibrationParams.PositionOffset = Quaternion.Inverse(hmdRotation) * (avgCamPosition - hmdPosition);

                var camRotations   = validMarkers.Select(m => m.DetectedCameraRotation);
                var avgCamRotation = MathUtility.Average(camRotations);

                CalibrationParams.RotationOffset = Quaternion.Inverse(hmdRotation) * avgCamRotation;
            }
        }
예제 #9
0
        private void StartCalibration()
        {
            var actualPosition = MathUtility.Average(_positionSamples);
            var actualRotation = MathUtility.Average(_rotationSamples);
            var actualTRS      = Matrix4x4.TRS(actualPosition, actualRotation, Vector3.one);

            var targetPosition = _origin.Point1.transform.position;
            var targetRotation = _origin.Point1.transform.rotation;
            var targetTRS      = Matrix4x4.TRS(targetPosition, targetRotation, Vector3.one);

            var transformationMatrix = targetTRS * actualTRS.inverse;

            Debug.Log($"Calibration complete with TRS:{Environment.NewLine}{transformationMatrix}");

            _client.OffsetMatrix  = transformationMatrix;
            _client.IsCalibrating = false;

            _positionSamples.Clear();
            _rotationSamples.Clear();
            CurrentSamples = 0;
        }
예제 #10
0
        private void CalculateReynoldsNumbers()
        {
            double massFlowRate = owner.HotSideInlet.MassFlowRate.Value;
            double t            = MathUtility.Average(owner.HotSideInlet.Temperature.Value, owner.ColdSideInlet.Temperature.Value);;
            double viscosity    = owner.HotSideInlet.GetLiquidViscosity(t);
            double ReHot        = GetReynoldsNumber(massFlowRate, viscosity, hotSidePasses.Value);
            double density      = owner.HotSideInlet.GetLiquidDensity(t);
            double velocityHot  = GetMassVelocity(massFlowRate, hotSidePasses.Value) / density;

            massFlowRate = owner.ColdSideInlet.MassFlowRate.Value;
            t            = MathUtility.Average(owner.ColdSideInlet.Temperature.Value, owner.ColdSideOutlet.Temperature.Value);
            viscosity    = owner.HotSideInlet.GetLiquidViscosity(t);
            double ReCold = GetReynoldsNumber(massFlowRate, viscosity, coldSidePasses.Value);

            density = owner.ColdSideInlet.GetLiquidDensity(t);
            double velocityCold = GetMassVelocity(massFlowRate, coldSidePasses.Value) / density;

            owner.Calculate(hotSideVelocity, velocityHot);
            owner.Calculate(hotSideRe, ReHot);
            owner.Calculate(coldSideVelocity, velocityCold);
            owner.Calculate(coldSideRe, ReCold);
        }
        private void StartCalibration()
        {
            List <Matrix4x4> offsetMatrices = new List <Matrix4x4>();

            var markerPosition = MathUtility.Average(_markerSamples.Select(t => t.Item1));
            var markerRotation = MathUtility.Average(_markerSamples.Select(t => t.Item2));
            var markerTRS      = Matrix4x4.TRS(markerPosition, markerRotation, Vector3.one);

            foreach (var id in _calibratedClient.Trackers)
            {
                var trackerPosition = MathUtility.Average(_trackerSamples[id].Select(t => t.Item1));
                var trackerRotation = MathUtility.Average(_trackerSamples[id].Select(t => t.Item2));
                var trackerTRS      = Matrix4x4.TRS(trackerPosition, trackerRotation, Vector3.one);

                var transformationMatrix = trackerTRS.inverse * markerTRS;
                offsetMatrices.Add(transformationMatrix);
                Debug.Log($"Calibration complete for tracker {id} with TRS:{Environment.NewLine}{transformationMatrix}" +
                          $"{Environment.NewLine}{MathUtility.PositionFromMatrix(transformationMatrix)}");
            }

            _calibratedClient.OffsetMatrices = offsetMatrices.ToArray();
            _calibratedClient.IsCalibrating  = false;
            _calibratedClient = null;
        }
예제 #12
0
파일: ChangeMonitor.cs 프로젝트: SebiH/ART
        public void UpdateStability(Vector3 nextPosition, Quaternion nextRotation)
        {
            _positions.Add(nextPosition);
            while (_positions.Count > MaxSamples)
            {
                _positions.RemoveAt(0);
            }

            var avgPos           = MathUtility.Average(_positions);
            var maxPosDifference = 0f;

            foreach (var pos in _positions)
            {
                maxPosDifference = Mathf.Max((pos - avgPos).magnitude, maxPosDifference);
            }
            PositionStability = Mathf.Clamp(1 - maxPosDifference * Sensitivity, 0f, 1f);


            _rotations.Add(nextRotation);
            while (_rotations.Count > MaxSamples)
            {
                _rotations.RemoveAt(0);
            }

            var avgRot           = MathUtility.Average(_rotations);
            var maxRotDifference = 0f;

            foreach (var rot in _rotations)
            {
                maxRotDifference = Mathf.Max(Quaternion.Angle(rot, avgRot), maxRotDifference);
            }
            RotationStability = Mathf.Clamp(1 - maxRotDifference * (Sensitivity / 1000f), 0f, 1f);


            Stability = RotationStability * PositionStability;
        }
예제 #13
0
        private double CalculateLiquidEnthalpy(double pValue, double tValue, double moistureContentValue)
        {
            double tBoilingPointOfSolvent  = MoistureProperties.GetSaturationTemperature(pValue);
            double tBoilingPointOfSolution = GetBoilingPoint(pValue, (1 - moistureContentValue));
            double cs        = GetCpOfAbsoluteDryMaterial();
            double hValue    = Constants.NO_VALUE;
            double hMoisture = Constants.NO_VALUE;

            //SteamTable steamTable = SteamTable.GetInstance();
            //SubstanceStatesAndProperties props;
            //double mc = moistureContentWetBase.Value;
            if (tValue < tBoilingPointOfSolvent)
            {
                //props = steamTable.GetPropertiesFromPressureAndTemperature(pValue, tValue);
                hMoisture = MoistureProperties.GetEnthalpyFromPressureAndTemperature(pValue, tValue);
                hValue    = moistureContentValue * hMoisture + (1.0 - moistureContentValue) * cs * (tValue - 273.15);
            }
            else if (tValue <= tBoilingPointOfSolution)
            {
                //props = steamTable.GetPropertiesFromPressureAndVaporFraction(pValue, 0); //P-V flash is more appropriate for buble point enthalpy of pure moisture
                hMoisture = MoistureProperties.GetEnthalpyFromPressureAndTemperature(pValue, tBoilingPointOfSolvent - TOLERANCE);
                double hBoilingPointOfSolvent = moistureContentValue * hMoisture + (1.0 - moistureContentValue) * cs * (tValue - 273.15);
                double moistureLiquidCp       = MoistureProperties.GetSpecificHeatOfLiquid(MathUtility.Average(tBoilingPointOfSolvent, tBoilingPointOfSolution));
                hValue = hBoilingPointOfSolvent + (moistureContentValue * moistureLiquidCp + (1.0 - moistureContentValue) * cs) * (tValue - tBoilingPointOfSolvent);
            }

            return(hValue);
        }
예제 #14
0
        private void CalculateTemperatureFromEnthalpy(double pValue, double hValue, double moistureContentValue)
        {
            double tValue    = Constants.NO_VALUE;
            double tValueOld = Constants.NO_VALUE;
            double vfValue   = Constants.NO_VALUE;

            double tBoilingPointOfSolvent  = MoistureProperties.GetSaturationTemperature(pValue);
            double tBoilingPointOfSolution = GetBoilingPoint(pValue);
            double cpLiquid = specificHeat.Value;

            if (cpLiquid == Constants.NO_VALUE)
            {
                cpLiquid = GetLiquidCp(MathUtility.Average(273.15, tBoilingPointOfSolution));
            }

            if (cpLiquid == Constants.NO_VALUE)
            {
                return;
            }

            //SteamTable steamTable = SteamTable.GetInstance();
            //SubstanceStatesAndProperties props;

            double hBoilingPointOfSolvent = CalculateLiquidEnthalpy(pValue, tBoilingPointOfSolvent, moistureContentValue);
            double hBubble = GetBubblePointEnthalpy(pValue, moistureContentValue);
            double hDew    = GetDewPointEnthalpy(pValue, moistureContentValue);

            double cs      = GetCpOfAbsoluteDryMaterial();
            int    counter = 0;

            if (hValue <= hBoilingPointOfSolvent)
            {
                double tempH;
                //tValue = hValue / cpLiquid + 273.15;
                tValue = tBoilingPointOfSolvent - (hBoilingPointOfSolvent - hValue) / cpLiquid;
                do
                {
                    counter++;
                    tValueOld = tValue;
                    tempH     = (hValue - (1.0 - moistureContentValue) * cs * (tValue - 273.15)) / moistureContentValue;
                    //props = steamTable.GetPropertiesFromPressureAndEnthalpy(pValue, tempH);
                    //tValue = props.temperature;
                    tValue = MoistureProperties.GetTemperatureFromPressureAndEnthalpy(pValue, tempH);
                } while (Math.Abs(tValue - tValueOld) > TOLERANCE && counter < 200);

                if (counter == 200)
                {
                    string msg = BuildProperErrorMessage(this.name + ": Calculation of temperature from enthalpy failed.\nPlease make sure each specified value in this stream");
                    throw new CalculationFailedException(msg);
                }
                vfValue = 0.0;
            }
            else if (hValue <= hBubble)
            {
                double moistureLiquidCp;
                //double hBoilingPointOfSolvent = CalculateLiquidEnthalpy(pValue, tBoilingPointOfSolvent - TOLERANCE);
                //tValue = hValue / cpLiquid + 273.15;
                tValue = (hValue - hBoilingPointOfSolvent) / cpLiquid + tBoilingPointOfSolvent;
                do
                {
                    counter++;
                    tValueOld        = tValue;
                    moistureLiquidCp = MoistureProperties.GetSpecificHeatOfLiquid(MathUtility.Average(tBoilingPointOfSolvent, tValue));
                    tValue           = (hValue - hBoilingPointOfSolvent) / (moistureContentValue * moistureLiquidCp + (1.0 - moistureContentValue) * cs) + tBoilingPointOfSolvent;
                } while (Math.Abs(tValue - tValueOld) > TOLERANCE && counter < 200);

                if (counter == 200)
                {
                    string msg = BuildProperErrorMessage(this.name + ": Calculation of temperature from enthalpy failed.\nPlease make sure each specified value in this stream");
                    throw new CalculationFailedException(msg);
                }
                vfValue = 0.0;
            }
            else if (hValue <= hDew)
            {
                double tBoilingPointOfSolutionFinal = tBoilingPointOfSolution;
                double evapHeat  = GetEvaporationHeat(tBoilingPointOfSolution);
                double extraHeat = (hValue - hBubble);
                if (moistureContentValue > 0.9999)
                {
                    vfValue = extraHeat / evapHeat;
                }
                else
                {
                    vfValue = 0;
                    double vfValueOld;
                    double moistureLiquidCp;
                    double massConcentrationValue = 1.0 - moistureContentValue;
                    do
                    {
                        counter++;
                        vfValueOld                   = vfValue;
                        vfValue                      = extraHeat / evapHeat;
                        massConcentrationValue       = (1.0 - moistureContentValue) / (1.0 - vfValue);
                        tBoilingPointOfSolutionFinal = GetBoilingPoint(pValue, massConcentrationValue);
                        evapHeat                     = GetEvaporationHeat(MathUtility.Average(tBoilingPointOfSolution, tBoilingPointOfSolutionFinal));
                        moistureLiquidCp             = MoistureProperties.GetSpecificHeatOfLiquid(MathUtility.Average(tBoilingPointOfSolution, tBoilingPointOfSolutionFinal));
                        extraHeat                    = hValue - hBubble - (moistureContentValue * moistureLiquidCp + (1.0 - moistureContentValue) * cs) * (tBoilingPointOfSolutionFinal - tBoilingPointOfSolution);
                    } while (Math.Abs(vfValue - vfValueOld) > TOLERANCE && counter < 200);

                    if (counter == 200)
                    {
                        string msg = BuildProperErrorMessage(this.name + ": Calculation of temperature from enthalpy failed.\nPlease make sure each specified value in this stream");
                        throw new CalculationFailedException(msg);
                    }
                }

                if (vfValue < 0.0)
                {
                    vfValue = 0.0;
                }

                tValue = tBoilingPointOfSolutionFinal;
            }
            else if (hValue > hDew)
            {
                double apparentHeat;
                double hVapor;
                double cpGas = GetGasCp(tBoilingPointOfSolution);
                tValue = (hValue - hDew) / cpGas + tBoilingPointOfSolution;

                do
                {
                    apparentHeat = (hValue - hDew - (1.0 - moistureContentValue) * cs * (tValue - tBoilingPointOfSolution)) / moistureContentValue;
                    //props = steamTable.GetPropertiesFromPressureAndTemperature(pValue, tBoilingPointOfSolution + TOLERANCE);
                    //hVapor = props.enthalpy + apparentHeat;
                    hVapor = apparentHeat + MoistureProperties.GetEnthalpyFromPressureAndTemperature(pValue, tBoilingPointOfSolution + TOLERANCE);
                    //props = steamTable.GetPropertiesFromPressureAndEnthalpy(pressure.Value, hVapor);
                    tValueOld = tValue;
                    //tValue = props.temperature;
                    tValue = MoistureProperties.GetTemperatureFromPressureAndEnthalpy(pressure.Value, hVapor);
                } while (Math.Abs(tValue - tValueOld) > TOLERANCE && counter < 200);

                if (counter == 200)
                {
                    string msg = BuildProperErrorMessage(this.name + ": Calculation of temperature from enthalpy failed.\nPlease make sure each specified value in this stream");
                    throw new CalculationFailedException(msg);
                }

                vfValue = moistureContentValue;
            }

            Calculate(temperature, tValue);
            Calculate(vaporFraction, vfValue);

            if (!specificHeat.HasValue)
            {
                double cp;
                if (hValue <= hBubble)
                {
                    cp = GetLiquidCp(tValue);
                }
                else
                {
                    cp = GetGasCp(tValue);
                }
                Calculate(specificHeat, cp);
            }
        }
예제 #15
0
        private IEnumerator UpdateCalibration()
        {
            var avgPos = new List <Vector3>();
            var avgRot = new List <Quaternion>();

            IsCalibrating = true;

            const int maxSamples = 100;

            for (int sampleCount = 0; sampleCount < maxSamples; sampleCount++)
            {
                CalibrationProgress = sampleCount / (float)maxSamples;
                yield return(new WaitForSecondsRealtime(0.002f));

                if (SurfaceManager.Instance.Has(DisplayName))
                {
                    var display       = SurfaceManager.Instance.Get(DisplayName);
                    var tableRotation = display.Rotation;

                    var calibPoses = new List <CalibPose>();

                    for (int i = 0; i < CalibrationOffsets.Length; i++)
                    {
                        if (CalibrationOffsets[i] == null)
                        {
                            continue;
                        }

                        var marker         = CalibrationOffsets[i];
                        var markerPosWorld = GetMarkerWorldPosition(i, tableRotation);
                        if (marker.HasArPose && (Time.unscaledTime - marker.ArPoseDetectionTime) < ArCutoffTime)
                        {
                            var localPos = marker.ArCameraPosition;
                            var worldPos = markerPosWorld + tableRotation * localPos;

                            var localRot     = marker.ArCameraRotation;
                            var localForward = localRot * Vector3.forward;
                            var localUp      = localRot * Vector3.up;

                            var worldForward = tableRotation * localForward;
                            var worldUp      = tableRotation * localUp;
                            var worldRot     = Quaternion.LookRotation(worldForward, worldUp);

                            calibPoses.Add(new CalibPose
                            {
                                WorldCameraPosition = worldPos,
                                WorldMarkerPosition = markerPosWorld,
                                WorldRotation       = worldRot
                            });
                        }
                    }

                    if (calibPoses.Count == 0)
                    {
                        continue;
                    }

                    // camera *must* be near optitrack camera position
                    var poses_noOutlier = calibPoses.Where((p) => (p.WorldCameraPosition - _optitrackCameraPose.Position).sqrMagnitude <= 0.025f);
                    Debug.Log("Found " + (calibPoses.Count - poses_noOutlier.Count()) + " Outliers during calibration");

                    var avgPosition = Vector3.zero;
                    var rots        = new List <Quaternion>();

                    foreach (var pose in poses_noOutlier)
                    {
                        avgPosition += pose.WorldCameraPosition;
                        rots.Add(pose.WorldRotation);
                    }

                    // need a few points to minimize errors
                    //if (rots.Count > 4)
                    {
                        if (CalibMethod == CalibrationMethod.Standard)
                        {
                            avgPosition = avgPosition / rots.Count;
                            avgPos.Add(Quaternion.Inverse(_optitrackCameraPose.Rotation) * (avgPosition - _optitrackCameraPose.Position));
                            _debugAvgPosition = avgPosition;
                        }
                        else if (CalibMethod == CalibrationMethod.LineExtension)
                        {
                            var closestPoints = new List <Vector3>();
                            var poses         = poses_noOutlier.ToArray();

                            _debugClosestPoints.Clear();
                            _debugRays.Clear();

                            for (int poseIndex = 0; poseIndex < poses.Length; poseIndex++)
                            {
                                var pose = poses[poseIndex];

                                var poseRay = new Ray(pose.WorldMarkerPosition, pose.WorldCameraPosition - pose.WorldMarkerPosition);
                                _debugRays.Add(poseRay);

                                for (int intersectIndex = poseIndex + 1; intersectIndex < poses.Length; intersectIndex++)
                                {
                                    var intersect    = poses[intersectIndex];
                                    var intersectRay = new Ray(intersect.WorldMarkerPosition, intersect.WorldCameraPosition - intersect.WorldMarkerPosition);

                                    Vector3 closestPoint1, closestPoint2;
                                    var     success = MathUtility.ClosestPointsOnTwoLines(out closestPoint1, out closestPoint2, poseRay.origin, poseRay.direction, intersectRay.origin, intersectRay.direction);

                                    if (success)
                                    {
                                        closestPoints.Add(closestPoint1);
                                        closestPoints.Add(closestPoint2);

                                        _debugClosestPoints.Add(closestPoint1);
                                        _debugClosestPoints.Add(closestPoint2);
                                    }
                                }
                            }

                            if (closestPoints.Count > 0)
                            {
                                avgPosition = Vector3.zero;
                                foreach (var p in closestPoints)
                                {
                                    avgPosition += p;
                                }

                                avgPosition = avgPosition / closestPoints.Count;
                                avgPos.Add(Quaternion.Inverse(_optitrackCameraPose.Rotation) * (avgPosition - _optitrackCameraPose.Position));
                                _debugAvgPosition = avgPosition;
                            }
                        }
                        else
                        {
                            Debug.LogWarning("Unknown calibration method " + CalibMethod.ToString());
                        }

                        var avgRotation = MathUtility.Average(rots);
                        avgRot.Add(avgRotation * Quaternion.Inverse(_ovrRot));
                        _debugAvgRotation = avgRotation;
                    }
                }
            }

            var avgPosOffset = Vector3.zero;

            foreach (var pos in avgPos)
            {
                avgPosOffset += pos;
            }

            _avgCalibrationPosOffsets.Add(avgPosOffset / avgPos.Count);
            _avgCalibrationRotOffsets.Add(MathUtility.Average(avgRot));

            var totalAvgPosOffset = Vector3.zero;

            foreach (var offset in _avgCalibrationPosOffsets)
            {
                totalAvgPosOffset += offset;
            }

            CalibrationParams.PositionOffset = totalAvgPosOffset / _avgCalibrationPosOffsets.Count;
            CalibrationParams.RotationOffset = MathUtility.Average(_avgCalibrationRotOffsets);

            IsCalibrating = false;
        }
        private void StartCalibration()
        {
            var actualPosition1 = MathUtility.Average(Calibrator1.Samples.Select(s => s.Item1));
            var targetPosition1 = CalibrationOriginPoint.Instance.Point1.transform.position;

            var actualPosition2 = MathUtility.Average(Calibrator2.Samples.Select(s => s.Item1));
            var targetPosition2 = CalibrationOriginPoint.Instance.Point2.transform.position;

            var targetScale = Mathf.Abs(Vector3.Distance(targetPosition1, targetPosition2));
            var actualScale = Mathf.Abs(Vector3.Distance(actualPosition1, actualPosition2));

            //var scaleDifference = actualScale / targetScale;

            Debug.Log($"TargetScale: {targetScale}");
            Debug.Log($"ActualScale: {actualScale}");
            //Debug.Log($"Scale Difference: {scaleDifference}");


            //actualPosition1.Scale(Vector3.one * scaleDifference);
            var actualRotation1 = MathUtility.Average(Calibrator1.Samples.Select(s => s.Item2));
            var actualTRS1      = Matrix4x4.TRS(actualPosition1, actualRotation1, Vector3.one);

            //targetPosition1.Scale(Vector3.one * (1 / scaleDifference));
            var targetRotation1 = CalibrationOriginPoint.Instance.Point1.transform.rotation;
            var targetTRS1      = Matrix4x4.TRS(targetPosition1, targetRotation1, Vector3.one);

            var transformationMatrix1 = targetTRS1 * actualTRS1.inverse;


            //actualPosition2.Scale(Vector3.one * scaleDifference);
            var actualRotation2 = MathUtility.Average(Calibrator2.Samples.Select(s => s.Item2));
            var actualTRS2      = Matrix4x4.TRS(actualPosition2, actualRotation2, Vector3.one);

            //targetPosition2.Scale(Vector3.one * (1 / scaleDifference));
            var targetRotation2 = CalibrationOriginPoint.Instance.Point2.transform.rotation;
            var targetTRS2      = Matrix4x4.TRS(targetPosition2, targetRotation2, Vector3.one);

            var transformationMatrix2 = targetTRS2 * actualTRS2.inverse;


            var finalMatrix = Matrix4x4.TRS(
                MathUtility.Average(new[] { MathUtility.PositionFromMatrix(transformationMatrix1), MathUtility.PositionFromMatrix(transformationMatrix2) }),
                MathUtility.Average(new[] { MathUtility.QuaternionFromMatrix(transformationMatrix1), MathUtility.QuaternionFromMatrix(transformationMatrix2) }),
                //Vector3.one * (1 / scaleDifference));
                Vector3.one);
            //Debug.Log($"Final scale: {1 / scaleDifference}");

            var posDiff = MathUtility.PositionFromMatrix(transformationMatrix1) - MathUtility.PositionFromMatrix(transformationMatrix2);
            var rotDiff = Quaternion.Angle(MathUtility.QuaternionFromMatrix(transformationMatrix1), MathUtility.QuaternionFromMatrix(transformationMatrix2));

            Debug.Log($"actual Pos Diff: {posDiff.x}, {posDiff.y}, {posDiff.z}");
            Debug.Log($"Rot Diff: {rotDiff}");



            _client.OffsetMatrix  = finalMatrix;
            _client.IsCalibrating = false;

            Calibrator1.Reset();
            Calibrator2.Reset();
        }
예제 #17
0
        void OnEnable()
        {
            CalibrationOffsets = new MarkerOffset[MarkersPerRow * MarkersPerColumn];
            for (int i = 0; i < CalibrationOffsets.Length; i++)
            {
                CalibrationOffsets[i] = new MarkerOffset {
                    ArMarkerId = i
                }
            }
            ;

            ArMarkerTracker.Instance.NewPoseDetected += OnArucoPose;
            OptitrackListener.PosesReceived          += OnOptitrackPose;
            SteamVR_Events.NewPoses.Listen(OnSteamVrPose);
        }

        void OnDisable()
        {
            ArMarkerTracker.Instance.NewPoseDetected -= OnArucoPose;
            OptitrackListener.PosesReceived          -= OnOptitrackPose;
            SteamVR_Events.NewPoses.Remove(OnSteamVrPose);
        }

        void Update()
        {
            if (SurfaceManager.Instance.Has(DisplayName) && (Time.unscaledTime - _optitrackCameraDetectionTime) < OptitrackCutoffTime)
            {
                var display       = SurfaceManager.Instance.Get(DisplayName);
                var tableRotation = display.Rotation;

                var lineRenderer = GetComponent <LineRenderer>();

                if (lineRenderer != null)
                {
                    lineRenderer.numPositions = 5;
                    lineRenderer.SetPosition(0, display.GetCornerPosition(Corner.TopLeft));
                    lineRenderer.SetPosition(1, display.GetCornerPosition(Corner.BottomLeft));
                    lineRenderer.SetPosition(2, display.GetCornerPosition(Corner.BottomRight));
                    lineRenderer.SetPosition(3, display.GetCornerPosition(Corner.TopRight));
                    lineRenderer.SetPosition(4, display.GetCornerPosition(Corner.TopLeft));
                }


                var markers = CalibrationOffsets.Where((m) => m.HasArPose && (Time.unscaledTime - m.ArPoseDetectionTime) < ArCutoffTime);

                if (markers == null)
                {
                    return;
                }

                if (!UseAverage)
                {
                    markers = new[] { markers.First() };
                }

                var rotations = new List <Quaternion>();
                var positions = new List <Vector3>();

                foreach (var marker in markers)
                {
                    var markerPosWorld = GetMarkerWorldPosition(marker.ArMarkerId, tableRotation);

                    var localPos = marker.ArCameraPosition;
                    var worldPos = markerPosWorld + tableRotation * localPos;

                    var localRot     = marker.ArCameraRotation;
                    var localForward = localRot * Vector3.forward;
                    var localUp      = localRot * Vector3.up;

                    var worldForward = tableRotation * localForward;
                    var worldUp      = tableRotation * localUp;
                    var worldRot     = Quaternion.LookRotation(worldForward, worldUp);

                    rotations.Add(worldRot);
                    positions.Add(worldPos);
                }

                CalibrationParams.PositionOffset = Quaternion.Inverse(_optitrackCameraPose.Rotation) * (MathUtility.Average(positions) - _optitrackCameraPose.Position);
                // c = b * inv(a)
                // => b = c * a?
                // from ovrRot to worldRot
                CalibrationParams.RotationOffset = MathUtility.Average(rotations) * Quaternion.Inverse(_ovrRot);
            }
        }
예제 #18
0
 public Quaternion GetAverageRotation()
 {
     return(MathUtility.Average(_rotations));
 }
예제 #19
0
        void OnDrawGizmos()
        {
            if (IsReadyForCalibration)
            {
                var avgMarkerPos    = Vector3.zero;
                var arucoPosesCount = 0;
                var arucoRotations  = new List <Quaternion>();

                foreach (var pose in _calibratedArucoPoses)
                {
                    avgMarkerPos += pose.Value.Position;
                    arucoRotations.Add(pose.Value.Rotation);
                    arucoPosesCount++;
                }

                var avgRotation = MathUtility.Average(arucoRotations);
                avgMarkerPos = avgMarkerPos / arucoPosesCount;
                var avgPosOffset = (avgMarkerPos - _optitrackCameraPose.Position);

                Gizmos.color = Color.blue;
                Gizmos.DrawSphere(_optitrackCameraPose.Position + avgPosOffset, 0.01f);
                var start = _optitrackCameraPose.Position + avgPosOffset;
                var end   = start + (avgRotation * Vector3.forward);
                var up    = start + (avgRotation * Vector3.up * 0.1f);
                var right = start + (avgRotation * Vector3.right * 0.1f);
                Gizmos.DrawLine(start, end);
                Gizmos.DrawLine(start, up);
                Gizmos.DrawLine(start, right);

                Gizmos.color = Color.green;
                end          = start + (_ovrRot * Vector3.forward);
                up           = start + (_ovrRot * Vector3.up * 0.1f);
                right        = start + (_ovrRot * Vector3.right * 0.1f);
                Gizmos.DrawLine(start, end);
                Gizmos.DrawLine(start, up);
                Gizmos.DrawLine(start, right);

                foreach (var pose in _calibratedArucoPoses)
                {
                    Gizmos.color = Color.red;
                    var rot = pose.Value.Rotation;
                    start = pose.Value.Position;
                    end   = start + (rot * Vector3.forward);
                    up    = start + (rot * Vector3.up * 0.1f);
                    right = start + (rot * Vector3.right * 0.1f);
                    Gizmos.DrawLine(start, end);
                    Gizmos.DrawLine(start, up);
                    Gizmos.DrawLine(start, right);

                    // draw ray from marker through possible camera location
                    var marker = _markerSetupScript.CalibratedMarkers.First((m) => m.Id == pose.Key);
                    start = marker.Marker.transform.position;
                    var direction = pose.Value.Position - start;
                    end          = start + 2 * direction;
                    Gizmos.color = Color.yellow;
                    Gizmos.DrawLine(start, end);
                }

                var poses = _calibratedArucoPoses.Values.ToArray();
                Gizmos.color = Color.black;
                var closestPoints = new List <Vector3>();

                for (int poseIndex = 0; poseIndex < poses.Length; poseIndex++)
                {
                    var pose       = poses[poseIndex];
                    var poseMarker = _markerSetupScript.CalibratedMarkers.First((m) => m.Id == pose.Id).Marker;
                    var poseRay    = new Ray(poseMarker.transform.position, pose.Position - poseMarker.transform.position);

                    for (int intersectIndex = poseIndex + 1; intersectIndex < poses.Length; intersectIndex++)
                    {
                        var intersect       = poses[intersectIndex];
                        var intersectMarker = _markerSetupScript.CalibratedMarkers.First((m) => m.Id == intersect.Id).Marker;
                        var intersectRay    = new Ray(intersectMarker.transform.position, intersect.Position - intersectMarker.transform.position);

                        Vector3 closestPoint1, closestPoint2;
                        var     success = MathUtility.ClosestPointsOnTwoLines(out closestPoint1, out closestPoint2, poseRay.origin, poseRay.direction, intersectRay.origin, intersectRay.direction);

                        if (success)
                        {
                            Gizmos.DrawSphere(closestPoint1, 0.005f);
                            Gizmos.DrawSphere(closestPoint2, 0.005f);
                            closestPoints.Add(closestPoint1);
                            closestPoints.Add(closestPoint2);
                        }
                    }
                }

                if (closestPoints.Count > 0)
                {
                    var avgIntersect = Vector3.zero;
                    foreach (var p in closestPoints)
                    {
                        avgIntersect += p;
                    }

                    avgIntersect = avgIntersect / closestPoints.Count;
                    Gizmos.color = Color.white;
                    Gizmos.DrawSphere(avgIntersect, 0.01f);
                }
            }
        }
예제 #20
0
        private void DoSingleMarkerCalibration(Surface surface)
        {
            // get nearest marker (from center) with up-to-date ar marker pose
            MarkerPose nearestMarker   = null;
            var        nearestDistance = 0f;

            // get intersection between camera ray and display plane
            Vector3 intersection    = new Vector3();
            var     hasIntersection = MathUtility.LinePlaneIntersection(out intersection, TrackedCamera.position, TrackedCamera.forward, surface.Normal, surface.GetCornerPosition(Corner.TopLeft));

            var angle = MathUtility.AngleVectorPlane(TrackedCamera.forward, surface.Normal);

            // use <, as we want the camera to be perpendicular to the table ( | camera, _ table)
            __camTableAngle = Mathf.Abs(angle);
            if (Mathf.Abs(angle) < MinMarkerAngle)
            {
                __hasWrongAngle = true;
                return;
            }
            __hasWrongAngle = false;

            if (hasIntersection)
            {
                __intersection = intersection;
                var poses = UseMaps ? ArucoMapListener.Instance.DetectedPoses.Values : ArMarkerTracker.Instance.DetectedPoses.Values;

                foreach (var marker in poses)
                {
                    bool isCurrent = (Time.unscaledTime - marker.DetectionTime) < ArCutoffTime;
                    if (!isCurrent)
                    {
                        continue;
                    }                             // shave off a few calculations

                    // calculate distance between intersection and marker
                    var  markerWorldPosition = GetMarkerWorldPosition(marker.Id);
                    var  distance            = (intersection - markerWorldPosition).sqrMagnitude;
                    bool isNearest           = (nearestMarker == null) || ((distance < nearestDistance));

                    if (isCurrent && isNearest)
                    {
                        nearestMarker   = marker;
                        nearestDistance = distance;
                    }
                }
            }

            if (nearestMarker != null && nearestDistance < NearestDistanceThreshold)
            {
                var markerWorldPos     = GetMarkerWorldPosition(nearestMarker.Id);
                var distMarkerToCamera = (markerWorldPos - TrackedCamera.position).sqrMagnitude;

                __camMarkerDistance = distMarkerToCamera;

                if (distMarkerToCamera > MaxMarkerCameraDistance)
                {
                    __isTooFarAway = true;
                    return;
                }
                __isTooFarAway = false;

                if (__nearestMarkerId != nearestMarker.Id)
                {
                    _perMarkerPosCalib.Clear();
                    _perMarkerRotCalib.Clear();
                }


                // debugging
                __nearestMarkerId = nearestMarker.Id;

                // apply calibration
                var markerMatrix = Matrix4x4.TRS(nearestMarker.Position, nearestMarker.Rotation, Vector3.one);
                var cameraMatrix = markerMatrix.inverse;

                var localPos = cameraMatrix.GetPosition();
                var worldPos = markerWorldPos + surface.Rotation * localPos;

                var localRot     = cameraMatrix.GetRotation();
                var localForward = localRot * Vector3.forward;
                var localUp      = localRot * Vector3.up;

                var worldForward = surface.Rotation * localForward;
                var worldUp      = surface.Rotation * localUp;
                var worldRot     = Quaternion.LookRotation(worldForward, worldUp);

                _perMarkerPosCalib.Add(Quaternion.Inverse(_optitrackPose.Rotation) * (worldPos - _optitrackPose.Position));
                _perMarkerRotCalib.Add(worldRot * Quaternion.Inverse(_ovrRotation));

                if (_perMarkerPosCalib.Count > 5 && _perMarkerPosCalib.Count < 50)
                {
                    CalibrationParams.PositionOffset = MathUtility.Average(_perMarkerPosCalib);
                    // c = b * inv(a)
                    // => b = c * a?
                    // from ovrRot to worldRot
                    CalibrationParams.RotationOffset = MathUtility.Average(_perMarkerRotCalib);
                }
            }
        }
예제 #21
0
        private void Solve()
        {
            //Mass Transfer--gas moisture and material particles transfer from gas stream to liquid stream
            DryingMaterialStream dmsOutlet = liquidOutlet as DryingMaterialStream;

            DryingGasStream dgsInlet  = gasInlet as DryingGasStream;
            DryingGasStream dgsOutlet = gasOutlet as DryingGasStream;

            //if (dgsInlet.DewPoint.HasValue && dgsOutlet.Temperature.HasValue && dgsOutlet.Temperature.Value > dgsInlet.DewPoint.Value) {
            //   throw new InappropriateSpecifiedValueException("Gas outlet temperature is not low enough to reach satuation");
            //}

            Calculate(dgsOutlet.RelativeHumidity, 0.9999999);

            //have to recalculate the streams so that the following balance calcualtion
            //can have all the latest balance calculated values taken into account
            if (dgsOutlet.Temperature.HasValue || dgsOutlet.WetBulbTemperature.HasValue)
            {
                UpdateStreamsIfNecessary();
            }

            balanceModel.DoBalanceCalculation();

            double inletDustMassFlowRate      = Constants.NO_VALUE;
            double outletDustMassFlowRate     = Constants.NO_VALUE;
            double inletDustMoistureFraction  = 0.0;
            double outletDustMoistureFraction = 0.0;

            DryingGasComponents dgc;

            if (InletParticleLoading.HasValue && gasInlet.VolumeFlowRate.HasValue)
            {
                inletDustMassFlowRate = InletParticleLoading.Value * gasInlet.VolumeFlowRate.Value;
                dgc = dgsInlet.GasComponents;
                if (dgc.SolidPhase != null)
                {
                    SolidPhase        sp = dgc.SolidPhase;
                    MaterialComponent mc = sp[1];
                    inletDustMoistureFraction = mc.GetMassFractionValue();
                }
            }

            if (OutletParticleLoading.HasValue && gasOutlet.VolumeFlowRate.HasValue)
            {
                outletDustMassFlowRate = OutletParticleLoading.Value * gasOutlet.VolumeFlowRate.Value;
                dgc = dgsOutlet.GasComponents;
                if (dgc.SolidPhase != null)
                {
                    SolidPhase        sp = dgc.SolidPhase;
                    MaterialComponent mc = sp[1];
                    inletDustMoistureFraction = mc.GetMassFractionValue();
                }
            }

            double materialFromGas = ParticleCollectionRate.Value;

            if (inletDustMassFlowRate != Constants.NO_VALUE && materialFromGas != Constants.NO_VALUE && outletDustMassFlowRate == Constants.NO_VALUE)
            {
                outletDustMassFlowRate = inletDustMassFlowRate - materialFromGas;
            }

            MoistureProperties moistureProperties = (this.unitOpSystem as EvaporationAndDryingSystem).GetMoistureProperties(((DryingGasStream)gasInlet).GasComponents.Moisture.Substance);
            double             materialEnthalpyLoss;
            double             gasEnthalpyLoss;
            double             gatTempValue;
            double             matTempValue;
            double             liquidCp;
            double             specificHeatOfSolidPhase;
            double             totalEnthapyLoss;

            if (waterInlet != null && waterOutlet != null)
            {
                if (waterInlet.MassFlowRate.HasValue)
                {
                    Calculate(waterOutlet.MassFlowRate, waterInlet.MassFlowRate.Value);
                }
                else if (waterOutlet.MassFlowRate.HasValue)
                {
                    Calculate(waterInlet.MassFlowRate, waterOutlet.MassFlowRate.Value);
                }

                if (waterInlet.SpecificEnthalpy.HasValue && waterInlet.MassFlowRate.HasValue &&
                    waterOutlet.SpecificEnthalpy.HasValue)
                {
                    double waterEnthalpyGain = waterInlet.MassFlowRate.Value * (waterOutlet.SpecificEnthalpy.Value - waterInlet.SpecificEnthalpy.Value);
                    Calculate(coolingDuty, waterEnthalpyGain);
                }
            }

            if (dmsOutlet.Temperature.HasValue && dgsInlet.SpecificEnthalpyDryBase.HasValue && coolingDuty.HasValue &&
                dgsInlet.MassFlowRateDryBase.HasValue && inletDustMoistureFraction != Constants.NO_VALUE &&
                materialFromGas != Constants.NO_VALUE)
            {
                gatTempValue = gasInlet.Temperature.Value;
                matTempValue = dmsOutlet.Temperature.Value;

                liquidCp = moistureProperties.GetSpecificHeatOfLiquid(MathUtility.Average(gatTempValue, matTempValue));
                specificHeatOfSolidPhase = (1.0 - inletDustMoistureFraction) * dmsOutlet.GetCpOfAbsoluteDryMaterial() + inletDustMoistureFraction * liquidCp;
                materialEnthalpyLoss     = materialFromGas * specificHeatOfSolidPhase * (matTempValue - gatTempValue);
                gasEnthalpyLoss          = coolingDuty.Value - materialEnthalpyLoss;
                //double outletEnthalpy = gasInlet.SpecificEnthalpy.Value - gasEnthalpyLoss;
                //Calculate(gasOutlet.SpecificEnthalpy, outletEnthalpy);
                double outletEnthalpy = dgsInlet.SpecificEnthalpyDryBase.Value - gasEnthalpyLoss / dgsInlet.MassFlowRateDryBase.Value;
                Calculate(dgsOutlet.SpecificEnthalpyDryBase, outletEnthalpy);
                UpdateStreamsIfNecessary();
                if (dgsOutlet.VolumeFlowRate.HasValue)
                {
                    double outletLoading = outletDustMassFlowRate / dgsOutlet.VolumeFlowRate.Value;
                    Calculate(OutletParticleLoading, outletLoading);
                }
            }
            else if (dmsOutlet.Temperature.HasValue && dgsInlet.SpecificEnthalpyDryBase.HasValue && dgsOutlet.Temperature.HasValue &&
                     dgsInlet.MassFlowRateDryBase.HasValue && dgsOutlet.SpecificEnthalpyDryBase.HasValue && inletDustMoistureFraction != Constants.NO_VALUE)
            {
                gatTempValue = dgsInlet.Temperature.Value;
                matTempValue = dmsOutlet.Temperature.Value;

                liquidCp = moistureProperties.GetSpecificHeatOfLiquid(MathUtility.Average(gatTempValue, matTempValue));
                specificHeatOfSolidPhase = (1.0 - inletDustMoistureFraction) * dmsOutlet.GetCpOfAbsoluteDryMaterial() + inletDustMoistureFraction * liquidCp;
                materialEnthalpyLoss     = materialFromGas * specificHeatOfSolidPhase * (matTempValue - gatTempValue);
                gasEnthalpyLoss          = dgsInlet.MassFlowRateDryBase.Value * (dgsInlet.SpecificEnthalpyDryBase.Value - dgsOutlet.SpecificEnthalpyDryBase.Value);
                totalEnthapyLoss         = materialEnthalpyLoss + gasEnthalpyLoss;
                Calculate(coolingDuty, totalEnthapyLoss);
                if (waterInlet != null && waterOutlet != null)
                {
                    if (waterInlet.SpecificEnthalpy.HasValue && waterInlet.MassFlowRate.HasValue)
                    {
                        double waterOutletSpecificEnthanlpy = totalEnthapyLoss / waterInlet.MassFlowRate.Value + waterInlet.SpecificEnthalpy.Value;
                        Calculate(waterOutlet.SpecificEnthalpy, waterOutletSpecificEnthanlpy);
                    }
                    else if (waterOutlet.SpecificEnthalpy.HasValue && waterInlet.MassFlowRate.HasValue)
                    {
                        double waterInletSpecificEnthanlpy = waterOutlet.SpecificEnthalpy.Value - totalEnthapyLoss / waterInlet.MassFlowRate.Value;
                        Calculate(waterOutlet.SpecificEnthalpy, waterInletSpecificEnthanlpy);
                    }
                }
            }
            //else if (gasInlet.SpecificEnthalpy.HasValue && gasOutlet.SpecificEnthalpy.HasValue && coolingDuty.HasValue
            //   && gasInlet.MassFlowRate.HasValue && inletDustMoistureFraction != Constants.NO_VALUE) {

            //   gasEnthalpyLoss = gasInlet.SpecificEnthalpy.Value * gasInlet.MassFlowRate.Value - gasOutlet.SpecificEnthalpy.Value * gasOutlet.MassFlowRate.Value;
            //   materialEnthalpyLoss = coolingDuty.Value - gasEnthalpyLoss;
            //   gatTempValue = gasInlet.Temperature.Value;
            //   //double matTempValue = dmsOutlet.Temperature.Value;

            //   liquidCp = moistureProperties.GetSpecificHeatOfLiquid(gatTempValue);
            //   specificHeatOfSolidPhase = (1.0 - inletDustMoistureFraction) * dmsOutlet.GetCpOfAbsoluteDryMaterial() + inletDustMoistureFraction * liquidCp;
            //   matTempValue = gatTempValue + materialEnthalpyLoss / (materialFromGas * specificHeatOfSolidPhase);

            //   Calculate(liquidOutlet.Temperature, matTempValue);
            //}

            double inletMoistureFlowRate  = Constants.NO_VALUE;
            double outletMoistureFlowRate = Constants.NO_VALUE;

            if (dgsInlet.MassFlowRateDryBase.HasValue && dgsInlet.MoistureContentDryBase.HasValue)
            {
                inletMoistureFlowRate = dgsInlet.MassFlowRateDryBase.Value * dgsInlet.MoistureContentDryBase.Value;
            }

            if (dgsOutlet.MassFlowRateDryBase.HasValue && dgsOutlet.MoistureContentDryBase.HasValue)
            {
                outletMoistureFlowRate = dgsOutlet.MassFlowRateDryBase.Value * dgsOutlet.MoistureContentDryBase.Value;
            }

            if (materialFromGas != Constants.NO_VALUE &&
                inletMoistureFlowRate != Constants.NO_VALUE && outletMoistureFlowRate != Constants.NO_VALUE)
            {
                double moistureFromGas = inletMoistureFlowRate - outletMoistureFlowRate;
                // materialFromGas = inletDustMassFlowRate - outletDustMassFlowRate;
                double moistureOfMaterialFromGas = inletDustMassFlowRate * inletDustMoistureFraction - outletDustMassFlowRate * outletDustMoistureFraction;

                double outletMassFlowRate = materialFromGas + moistureFromGas;
                Calculate(dmsOutlet.MassFlowRate, outletMassFlowRate);

                double outletMaterialMoistureFlowRate = moistureFromGas + moistureOfMaterialFromGas;
                double outletMoistureContentWetBase   = outletMaterialMoistureFlowRate / outletMassFlowRate;
                Calculate(dmsOutlet.MoistureContentWetBase, outletMoistureContentWetBase);
                //solveState = SolveState.Solved;
            }

            if (liquidToGasVolumeRatio.HasValue && gasInlet.VolumeFlowRate.HasValue)
            {
                double recirculationVolumeFlow = liquidToGasVolumeRatio.Value * gasInlet.VolumeFlowRate.Value;
                Calculate(liquidRecirculationVolumeFlowRate, recirculationVolumeFlow);
                if (liquidOutlet.Density.HasValue)
                {
                    double recirculationMassFlow = recirculationVolumeFlow / liquidOutlet.Density.Value;
                    Calculate(liquidRecirculationMassFlowRate, recirculationMassFlow);
                }
            }

            if (dgsInlet.DewPoint.HasValue && dgsOutlet.Temperature.HasValue && dgsOutlet.Temperature.Value > dgsInlet.DewPoint.Value)
            {
                solveState = SolveState.SolvedWithWarning;
            }
            //else if (gasInlet.Pressure.HasValue && gasOutlet.Pressure.HasValue
            //   && gasInlet.Temperature.HasValue && gasOutlet.Temperature.HasValue
            //   && gasInlet.SpecificEnthalpy.HasValue && gasOutlet.SpecificEnthalpy.HasValue
            //   && waterInlet.Pressure.HasValue && waterOutlet.Pressure.HasValue
            //   && waterInlet.Temperature.HasValue && waterOutlet.Temperature.HasValue
            //   && waterInlet.SpecificEnthalpy.HasValue && waterOutlet.SpecificEnthalpy.HasValue
            //   && liquidOutlet.Pressure.HasValue && liquidOutlet.Temperature.HasValue
            //   && dmsOutlet.MoistureContentWetBase.HasValue) {
            else if (gasInlet.SolveState == SolveState.Solved && gasOutlet.SolveState == SolveState.Solved &&
                     coolingDuty.HasValue &&
                     ((waterInlet == null || waterOutlet == null) ||
                      (waterInlet != null && waterOutlet != null) &&
                      (waterInlet.SolveState == SolveState.Solved && waterOutlet.SpecificEnthalpy.HasValue ||
                       waterOutlet.SolveState == SolveState.Solved && waterInlet.SpecificEnthalpy.HasValue)))
            {
                solveState = SolveState.Solved;
            }
        }
예제 #22
0
        private IEnumerator DoCalibration()
        {
            var avgPosOffset   = Vector3.zero;
            var arucoRotations = new List <Quaternion>();

            var samples = 0;

            IsCalibrating = true;

            while (samples < MaxCalibrationSamples)
            {
                foreach (var pose in _calibratedArucoPoses)
                {
                    arucoRotations.Add(pose.Value.Rotation);
                }

                if (CalibMethod == CalibrationMethod.Standard)
                {
                    var arucoPosesCount = 0;
                    var avgMarkerPos    = Vector3.zero;

                    foreach (var pose in _calibratedArucoPoses)
                    {
                        avgMarkerPos += pose.Value.Position;
                        arucoPosesCount++;
                    }

                    avgMarkerPos  = avgMarkerPos / arucoPosesCount;
                    avgPosOffset += (avgMarkerPos - _optitrackCameraPose.Position);
                }
                else if (CalibMethod == CalibrationMethod.LineExtension)
                {
                    var poses         = _calibratedArucoPoses.Values.ToArray();
                    var closestPoints = new List <Vector3>();

                    for (int poseIndex = 0; poseIndex < poses.Length; poseIndex++)
                    {
                        var pose       = poses[poseIndex];
                        var poseMarker = _markerSetupScript.CalibratedMarkers.First((m) => m.Id == pose.Id).Marker;
                        var poseRay    = new Ray(poseMarker.transform.position, pose.Position - poseMarker.transform.position);

                        for (int intersectIndex = poseIndex + 1; intersectIndex < poses.Length; intersectIndex++)
                        {
                            var intersect       = poses[intersectIndex];
                            var intersectMarker = _markerSetupScript.CalibratedMarkers.First((m) => m.Id == intersect.Id).Marker;
                            var intersectRay    = new Ray(intersectMarker.transform.position, intersect.Position - intersectMarker.transform.position);

                            Vector3 closestPoint1, closestPoint2;
                            var     success = MathUtility.ClosestPointsOnTwoLines(out closestPoint1, out closestPoint2, poseRay.origin, poseRay.direction, intersectRay.origin, intersectRay.direction);

                            if (success)
                            {
                                closestPoints.Add(closestPoint1);
                                closestPoints.Add(closestPoint2);
                            }
                        }
                    }

                    if (closestPoints.Count > 0)
                    {
                        var avgIntersect = Vector3.zero;
                        foreach (var p in closestPoints)
                        {
                            avgIntersect += p;
                        }

                        avgIntersect = avgIntersect / closestPoints.Count;

                        avgPosOffset += (avgIntersect - _optitrackCameraPose.Position);
                    }
                }

                samples++;
                CalibrationProgress = samples / MaxCalibrationSamples;
                yield return(new WaitForSeconds(0.1f));
            }

            avgPosOffset = avgPosOffset / samples;
            var avgRotation  = MathUtility.Average(arucoRotations);
            var avgRotOffset = avgRotation * Quaternion.Inverse(_ovrRot);

            CalibrationParams.PositionOffset = avgPosOffset;
            CalibrationParams.RotationOffset = avgRotOffset;

            IsCalibrating       = false;
            CalibrationProgress = 0;

            Debug.Log("Calibration complete");
        }