切换页面或锁屏时关闭串口电源
26
.metadata
@ -1,10 +1,30 @@
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
# This file should be version controlled.
|
||||
|
||||
version:
|
||||
revision: b101bfe32f634566e7cb2791a9efe19cf8828b15
|
||||
channel: beta
|
||||
revision: cd41fdd495f6944ecd3506c21e94c6567b073278
|
||||
channel: unknown
|
||||
|
||||
project_type: app
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: cd41fdd495f6944ecd3506c21e94c6567b073278
|
||||
base_revision: cd41fdd495f6944ecd3506c21e94c6567b073278
|
||||
- platform: android
|
||||
create_revision: cd41fdd495f6944ecd3506c21e94c6567b073278
|
||||
base_revision: cd41fdd495f6944ecd3506c21e94c6567b073278
|
||||
|
||||
# User provided section
|
||||
|
||||
# List of Local paths (relative to this file) that should be
|
||||
# ignored by the migrate tool.
|
||||
#
|
||||
# Files that are not part of the templates will be ignored by default.
|
||||
unmanaged_files:
|
||||
- 'lib/main.dart'
|
||||
- 'ios/Runner.xcodeproj/project.pbxproj'
|
||||
|
@ -8,7 +8,7 @@ if (localPropertiesFile.exists()) {
|
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||
if (flutterRoot == null) {
|
||||
throw new Exception("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
@ -28,24 +28,19 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
android {
|
||||
// compileSdkVersion flutter.compileSdkVersion
|
||||
compileSdkVersion 32
|
||||
ndkVersion "23.1.7779620"
|
||||
ndkVersion flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "cn.com.motse.fengshui_compass"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
||||
// minSdkVersion flutter.minSdkVersion
|
||||
minSdkVersion 19
|
||||
targetSdkVersion flutter.targetSdkVersion
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
@ -59,19 +54,8 @@ android {
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
disable "Instantiatable"
|
||||
checkReleaseBuilds false
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="cn.com.motse.fengshui_compass">
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
@ -29,7 +29,6 @@
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:resource="@drawable/launch_image"
|
||||
android:value="2" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
@ -0,0 +1,142 @@
|
||||
package cn.com.motse.fengshui_compass;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* author: Blankj
|
||||
* blog : http://blankj.com
|
||||
* time : 2016/08/07
|
||||
* desc : utils about shell
|
||||
* </pre>
|
||||
*/
|
||||
public final class ComShellUtils {
|
||||
public static final String TAG = "CommandExecution";
|
||||
|
||||
public final static String COMMAND_SU = "su";
|
||||
public final static String COMMAND_SH = "sh";
|
||||
public final static String COMMAND_EXIT = "exit\n";
|
||||
public final static String COMMAND_LINE_END = "\n";
|
||||
|
||||
/**
|
||||
* Command执行结果
|
||||
*
|
||||
* @author Mountain
|
||||
*/
|
||||
public static class CommandResult {
|
||||
public int result = -1;
|
||||
public String errorMsg;
|
||||
public String successMsg;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CommandResult{" +
|
||||
"result=" + result +
|
||||
", errorMsg='" + errorMsg + '\'' +
|
||||
", successMsg='" + successMsg + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行命令—单条
|
||||
*
|
||||
* @param command
|
||||
* @param isRoot
|
||||
* @return
|
||||
*/
|
||||
public static CommandResult execCommand(String command, boolean isRoot) {
|
||||
String[] commands = {command};
|
||||
return execCommand(commands, isRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行命令-多条
|
||||
*
|
||||
* @param commands
|
||||
* @param isRoot
|
||||
* @return
|
||||
*/
|
||||
public static CommandResult execCommand(String[] commands, boolean isRoot) {
|
||||
CommandResult commandResult = new CommandResult();
|
||||
if (commands == null || commands.length == 0) return commandResult;
|
||||
Process process = null;
|
||||
DataOutputStream os = null;
|
||||
BufferedReader successResult = null;
|
||||
BufferedReader errorResult = null;
|
||||
StringBuilder successMsg = null;
|
||||
StringBuilder errorMsg = null;
|
||||
try {
|
||||
process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
|
||||
os = new DataOutputStream(process.getOutputStream());
|
||||
for (String command : commands) {
|
||||
if (command != null) {
|
||||
os.write(command.getBytes());
|
||||
os.writeBytes(COMMAND_LINE_END);
|
||||
os.flush();
|
||||
}
|
||||
}
|
||||
os.writeBytes(COMMAND_EXIT);
|
||||
os.flush();
|
||||
commandResult.result = process.waitFor();
|
||||
//获取错误信息
|
||||
successMsg = new StringBuilder();
|
||||
errorMsg = new StringBuilder();
|
||||
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
||||
String s;
|
||||
while ((s = successResult.readLine()) != null) {
|
||||
successMsg.append(s);
|
||||
}
|
||||
while ((s = errorResult.readLine()) != null) {
|
||||
errorMsg.append(s);
|
||||
}
|
||||
commandResult.successMsg = successMsg.toString();
|
||||
commandResult.errorMsg = errorMsg.toString();
|
||||
Log.i(TAG, commandResult.result + " | " + commandResult.successMsg
|
||||
+ " | " + commandResult.errorMsg);
|
||||
} catch (IOException e) {
|
||||
String errmsg = e.getMessage();
|
||||
if (errmsg != null) {
|
||||
Log.e(TAG, errmsg);
|
||||
} else {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String errmsg = e.getMessage();
|
||||
if (errmsg != null) {
|
||||
Log.e(TAG, errmsg);
|
||||
} else {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
if (successResult != null) {
|
||||
successResult.close();
|
||||
}
|
||||
if (errorResult != null) {
|
||||
errorResult.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
String errmsg = e.getMessage();
|
||||
if (errmsg != null) {
|
||||
Log.e(TAG, errmsg);
|
||||
} else {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
return commandResult;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package cn.com.motse.fengshui_compass;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity;
|
||||
import io.flutter.embedding.engine.FlutterEngine;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
public class MainActivity extends FlutterActivity {
|
||||
private static final String CHANNEL = "toggle_power";
|
||||
|
||||
@Override
|
||||
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine);
|
||||
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
|
||||
.setMethodCallHandler(
|
||||
(call, result) -> {
|
||||
if (call.method.equals("turnOnPower")) {
|
||||
String state = "1";
|
||||
String ioValue = "236";
|
||||
String cmdStr1 = "echo " + ioValue + " > /sys/class/gpio/export";
|
||||
String cmdStr2 = "echo out > /sys/class/gpio/gpio" + ioValue + "/direction";
|
||||
String cmdStr3 = "echo " + state + " > /sys/class/gpio/gpio" + ioValue + "/value";
|
||||
ComShellUtils.execCommand(cmdStr1, false);
|
||||
ComShellUtils.execCommand(cmdStr2, false);
|
||||
ComShellUtils.execCommand(cmdStr3, false);
|
||||
result.success("on");
|
||||
} else if (call.method.equals("turnOffPower")) {
|
||||
String state = "0";
|
||||
String ioValue = "236";
|
||||
String cmdStr1 = "echo " + ioValue + " > /sys/class/gpio/export";
|
||||
String cmdStr2 = "echo out > /sys/class/gpio/gpio" + ioValue + "/direction";
|
||||
String cmdStr3 = "echo " + state + " > /sys/class/gpio/gpio" + ioValue + "/value";
|
||||
ComShellUtils.execCommand(cmdStr1, false);
|
||||
ComShellUtils.execCommand(cmdStr2, false);
|
||||
ComShellUtils.execCommand(cmdStr3, false);
|
||||
result.success("off");
|
||||
} else {
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package cn.com.motse.fengshui_compass
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
|
||||
class MainActivity: FlutterActivity() {
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@color/transparent" />
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<item>
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@drawable/launch_image" />
|
||||
</item>
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
|
Before Width: | Height: | Size: 540 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 544 B |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 442 B |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 721 B |
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 1.4 KiB |
@ -3,7 +3,7 @@
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
|
@ -3,7 +3,7 @@
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
Flutter draws its first frame -->
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
@ -14,7 +14,5 @@
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
|
||||
</style>
|
||||
<color name="transparent">#00000000</color>
|
||||
</resources>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="cn.com.motse.fengshui_compass">
|
||||
<!-- Flutter needs it to communicate with the running application
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
@ -6,7 +6,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
classpath 'com.android.tools.build:gradle:7.1.2'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
|
||||
|
@ -7,6 +7,7 @@ import 'package:fengshui_compass/components/my_icon.dart';
|
||||
import 'package:fengshui_compass/pages/login_page.dart';
|
||||
import 'package:fengshui_compass/states/region.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_serial_port_api/flutter_serial_port_api.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@ -23,7 +24,7 @@ class CompassPage extends StatefulWidget {
|
||||
State<StatefulWidget> createState() => _CompassState();
|
||||
}
|
||||
|
||||
class _CompassState extends State<CompassPage> {
|
||||
class _CompassState extends State<CompassPage> with WidgetsBindingObserver {
|
||||
// 串口相关
|
||||
bool isPortOpened = false;
|
||||
SerialPort _serialPort;
|
||||
@ -54,16 +55,53 @@ class _CompassState extends State<CompassPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
print("init");
|
||||
// 添加观察者以监听生命周期事件
|
||||
WidgetsBinding.instance?.addObserver(this);
|
||||
initPort();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
turnOffPower();
|
||||
// 在小部件被销毁时移除观察者,以防止内存泄漏
|
||||
WidgetsBinding.instance?.removeObserver(this);
|
||||
super.dispose();
|
||||
print("dispose");
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
// 在这里处理应用程序生命周期状态变化事件
|
||||
if (state == AppLifecycleState.paused) {
|
||||
// 应用程序进入后台
|
||||
print('App entered background');
|
||||
turnOffPower();
|
||||
} else if (state == AppLifecycleState.resumed) {
|
||||
// 应用程序回到前台
|
||||
print('App returned to foreground');
|
||||
initPort();
|
||||
} else if (state == AppLifecycleState.inactive) {
|
||||
// 应用程序处于非活动状态(例如:锁屏、电话来电)
|
||||
print('App in inactive state');
|
||||
turnOffPower();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> initPort() async {
|
||||
await turnOnPower();
|
||||
// todo:
|
||||
setState(() {
|
||||
isLock = true;
|
||||
isUpClose = true;
|
||||
isSideClose = true;
|
||||
});
|
||||
// 20ms接收一次串口数据,防抖,定义接收缓存
|
||||
final debounceTransformer = StreamTransformer<Uint8List, dynamic>.fromBind(
|
||||
(s) => s.transform(debounceBuffer(const Duration(milliseconds: 20))));
|
||||
|
||||
if (!isPortOpened) {
|
||||
Device theDevice = Device("/dev/ttyS2", "/dev/ttyS2");
|
||||
Device theDevice = Device("/dev/ttyS3", "/dev/ttyS3");
|
||||
var serialPort = await FlutterSerialPortApi.createSerialPort(
|
||||
theDevice, 115200,
|
||||
parity: 0, dataBits: 8, stopBit: 1);
|
||||
@ -89,6 +127,24 @@ class _CompassState extends State<CompassPage> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> turnOnPower() async {
|
||||
const platform = MethodChannel('toggle_power');
|
||||
await platform.invokeMethod("turnOnPower");
|
||||
}
|
||||
|
||||
Future<void> turnOffPower() async {
|
||||
const platform = MethodChannel('toggle_power');
|
||||
await platform.invokeMethod("turnOffPower");
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
isLock = false;
|
||||
isUpClose = false;
|
||||
isSideClose = false;
|
||||
isPortOpened = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> closePort() async {
|
||||
bool closeResult = await _serialPort.close();
|
||||
setState(() {
|
||||
@ -204,40 +260,50 @@ class _CompassState extends State<CompassPage> {
|
||||
w_y_tmp = 0.5 - 0.07 * roll_tmp / 30.0;
|
||||
w_x_tmp = 0.5 - 0.07 * pitch_tmp / 30.0;
|
||||
} else if (w_total > 30) {
|
||||
//todo
|
||||
w_y_tmp = 0.5 - 0.07 * w_total / 30.0;
|
||||
w_x_tmp = 0.5 - 0.07 * w_total / 30.0;
|
||||
// //todo
|
||||
// w_y_tmp = 0.5 - 0.07 * w_total / 30.0;
|
||||
// w_x_tmp = 0.5 - 0.07 * w_total / 30.0;
|
||||
var radius = sqrt(0.07 * 0.07 * 2);
|
||||
//todo;
|
||||
var _angle = atan2(roll_tmp, -pitch_tmp);
|
||||
if (_angle < 0) {
|
||||
_angle += 2 * pi;
|
||||
}
|
||||
w_y_tmp = 0.5 - radius * sin(_angle);
|
||||
w_x_tmp = 0.5 + radius * cos(_angle);
|
||||
}
|
||||
|
||||
// todo 其他情况
|
||||
|
||||
var meanValue;
|
||||
|
||||
if (lista.length < 20) {
|
||||
lista.add(temp_myaw);
|
||||
meanValue = null;
|
||||
} else {
|
||||
lista.removeAt(0);
|
||||
lista.add(temp_myaw);
|
||||
meanValue = lista.map((e) => e).reduce((a, b) => a + b) / lista.length;
|
||||
// if (lista.length < 20) {
|
||||
// lista.add(temp_myaw);
|
||||
// meanValue = null;
|
||||
// } else {
|
||||
// lista.removeAt(0);
|
||||
// lista.add(temp_myaw);
|
||||
// meanValue = lista.map((e) => e).reduce((a, b) => a + b) / lista.length;
|
||||
// }
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
// print("roll: $roll_tmp pitch: $pitch_tmp");
|
||||
// print("w_x: $w_x_tmp, w_y: $w_y_tmp");
|
||||
// if (meanValue != null) {
|
||||
// myaw = meanValue;
|
||||
// } else {
|
||||
// myaw = 0;
|
||||
// }
|
||||
myaw = temp_myaw;
|
||||
|
||||
w_x = w_x_tmp;
|
||||
w_y = w_y_tmp;
|
||||
|
||||
// 水平仪 0.5+-0.07范围
|
||||
// x旋转y在动 y旋转x在动 roll改变y坐标,pitch改变x坐标
|
||||
});
|
||||
}
|
||||
|
||||
setState(() {
|
||||
// print("roll: $roll_tmp pitch: $pitch_tmp");
|
||||
// print("w_x: $w_x_tmp, w_y: $w_y_tmp");
|
||||
// if (meanValue != null) {
|
||||
// myaw = meanValue;
|
||||
// } else {
|
||||
// myaw = 0;
|
||||
// }
|
||||
myaw = temp_myaw;
|
||||
|
||||
w_x = w_x_tmp;
|
||||
w_y = w_y_tmp;
|
||||
|
||||
// 水平仪 0.5+-0.07范围
|
||||
// x旋转y在动 y旋转x在动 roll改变y坐标,pitch改变x坐标
|
||||
});
|
||||
} else if (str.contains("9E010401") &&
|
||||
(str.length >= ((str.indexOf("9E010401") + 26)))) {
|
||||
var pos = str.indexOf("9E010401");
|
||||
@ -311,7 +377,8 @@ class _CompassState extends State<CompassPage> {
|
||||
} else if (angle > 180) {
|
||||
result = angle - 180;
|
||||
} else {
|
||||
result = 0.0;
|
||||
// result = 0.0;
|
||||
result = angle;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|