指南针和风速计异常行为 - Swift UI

问题描述 投票:0回答:1

最近几天我快疯了,无法解决这个问题。我正在制作一个包含风速计和指南针的应用程序,它们也有同样的问题。 我在这里仅以风速计为例进行分享。 因此,我有一个风传感器,每秒都会更新风向和风速的数据,一切正常,直到......它达到从 1 度到 359 度的过渡,反之亦然。这不是风速计的自然行为。 我尝试了来自互联网和堆栈溢出的许多不同解决方案,但似乎没有任何效果。在这里我发布了两个解决方案 - 第一个解决方案对于 0 度左右的度数之间的过渡是可以的,但是当它达到 180 度限制时它会做同样的事情。 第二种方法我尝试捕获两个角度,并将这些值保存在数组中。然后,我计算角度之间的最短距离,并将差值应用于第一个角度,并尝试沿相关方向旋转,但效果不佳。 有什么好的解决办法吗?

请观看视频: anemometer_going_crazy

这是代码 - 我在 matt 管理器中进行计算,计算完成后,我只需调用具有此值“windAngle”的视图

    func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
        if let str = message.string { // <--- here or something like this
            print(str)
            let strSplit = str.split(separator: ",")
            
            windAngle = Double(strSplit[1])!
            
//            //MARK: Solution 1
//
//            if windAngle <= 180 {
//
//                windAngle = windAngle
//                print(windAngle)
//            } else {
//                windAngle = -(360 - windAngle)
//                print(windAngle)
//            }
            //MARK: - Solution 2
//            windArray.append(windAngle)
//            print(windArray.count)
//            //kind of calibration
//            if windArray.count > 2 {
//
//                let diff1 = windArray[2] - windArray[1]
//                let diff2 = -(360 - windArray[2] - windArray[1])
//                print(windArray[1])
//                print(windArray[2])
//
//                print(diff1)
//                print(diff2)
//
//
//                if (diff1.magnitude <= diff2.magnitude) {
//                    windAngle = windArray[1] + diff1
//                } else {
//                    windAngle = windArray[1] + diff2
//                }
//
//                windArray[1] = windArray[2]
//                windArray.removeLast()
//            }

            windSpeed = Double(strSplit[3])!
        }
        
    }

编辑:1 所以,首先我在代码中犯了一个错误,因为两个模数差不等于360,我纠正了它,但还没有一个好的结果;

                let diff1 = windArray[2] - windArray[1]
                let diff2 = -(windArray[2] - windArray[1] + 360) // <-- correction here
                print("first wind angle: \(windArray[1])")
                print("next wind angle: \(windArray[2])")

                print("first path difference: \(diff1)")
                print("second path diference: \(diff2)")

因此,如果您看到红色圆圈中的值,很明显该算法一直有效,直到它选择具有适当长度的路径,但它只采用相反的符号,而不是减小角度,而是将其减小差值或只会让事情变得愚蠢。我几乎确定我没有以正确的方式计算两条不同的路径,但我只是没有看到它:) 另一双眼睛肯定会有帮助:)

values_from_wind_sensors

swiftui navigation rotation logic
1个回答
0
投票

好吧,经过更多时间的研究,我找到了正确的解决方案,至少对我来说是这样。我会将其发布在这里,以防有人需要。 感谢这个答案:shortest_path_ Between_angles_calculation

由凯尔回答,我认为这是最优雅的,我找到了如何计算两个角度之间的最短路径并返回具有正确符号的正确值的方法。

这个想法是,在工作完成并且角度已在视图中发布后,我将其分配给数组的第一个元素,以供将来计算下一个角度时参考。这样,-180 / 180 范围随角度一起移动,并且视图永远不会变得疯狂或重叠。同样的原理也适用于指南针,我也在那里使用了它。 这是代码:

//MARK: - Calculating the wind angle
            //add next wind angle for calculation
            windArray.append(windAngle)
            
            if windArray.count > 1 {
                //calculating the differnece between the two angles
                let diff = (windArray[1] - windArray[0] + 180).truncatingRemainder(dividingBy: 360) - 180
                //getting the shortest path to the next angle
                let correctedDiff = diff < -180 ? diff + 360 : diff
                //assigning the final value to the windAngle that is going called in the main view
                windAngle = windArray[0] + correctedDiff

                //once the job is done assign the last wind angle to the [0] element of the array
                //for a future reference point
                windArray[0] = windAngle
                //remove the last angle and prepare the array for the next angle
                windArray.remove(at: 1)
            }
© www.soinside.com 2019 - 2024. All rights reserved.