1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/tytokongjian-StepCountingUpperPC

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
MainWindow.xaml.cs 22 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
xiaobeibi Отправлено 17.06.2021 10:58 e421465
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Windows.Media.Animation;
namespace BluetoothPC
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private delegate void showData(string msg); //通信窗口输出相关
//private TcpClient client;
private Socket server;
//private NetworkStream sendStream;
private const int bufferSize = 1024;
private Thread thread;
private Thread Updateth;
private Thread StepCounting;
BitmapImage bitmapImage1 = new BitmapImage(new Uri("/picture/1.png", UriKind.Relative));
BitmapImage bitmapImage2 = new BitmapImage(new Uri("/picture/2.png", UriKind.Relative));
private int valueNum = 5;
//private double[] tempValue;
private List<double> tempValue = new List<double>();
private Boolean isDirectionUp = false;
private int continueUpCount = 0;
private int continueUpFormerCount = 0;
private Boolean lastStatus = false;
private double peakOfWave = 0;
private double valleyOfWave = 0;
private double timeOfThisPeak = 0;
private double timeOfLastPeak = 0;
private double timeOfNow = 0;
private double gravityOld = 0;
private double initialValue = 1.7;
private double ThreadValue = 2.0;
private double minValue = 11;
private double maxValue = 19.6;
private double g = 9.8;
private double thisSteps = 0; //当前步数
private double StepsCopy = 0; //步数复制
private double X_axis = 0;
private double Y_axis = 0;
private double Z_axis = 0;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//时间线程
DispatcherTimer dateTimer = new DispatcherTimer();//显示当前时间线程
dateTimer.Tick += new EventHandler(dateTimer_Tick);
dateTimer.Interval = new TimeSpan(0, 0, 0, 1, 0);
dateTimer.Start();
//UDP监听线程
thread = new Thread(ListenerServer);
thread.IsBackground = true;
//数据更新线程
Updateth = new Thread(UpdateTextBox);
Updateth.Start();
//动态界面显示
var delay = new TimeSpan(0);
foreach (Ellipse item in Container1.Children)
{
var baseAnimation = Container1.Resources["MyAnimation"] as Storyboard;
var storyBoard = baseAnimation.Clone();
storyBoard.BeginTime = delay;
item.BeginStoryboard(storyBoard);
delay = delay.Add(TimeSpan.FromSeconds(0.1));
}
foreach (Ellipse item in Container2.Children)
{
var baseAnimation = Container2.Resources["MyAnimation"] as Storyboard;
var storyBoard = baseAnimation.Clone();
storyBoard.BeginTime = delay;
item.BeginStoryboard(storyBoard);
delay = delay.Add(TimeSpan.FromSeconds(0.1));
}
}
private async void UpdateTextBox()
{
while (true)
{
Dispatcher.Invoke(() =>
{
XaxisTextBox.Text = X_axis.ToString();
YaxisTextBox.Text = Y_axis.ToString();
ZaxisTextBox.Text = Z_axis.ToString();
});
await Task.Delay(100);
}
}
private void dateTimer_Tick(object sender, EventArgs e)//取当前时间的委托
{
string timeDateString = "";
DateTime now = DateTime.Now;
timeDateString = string.Format("{0}年{1}月{2}日 {3}:{4}:{5}",
now.Year,
now.Month.ToString("00"),
now.Day.ToString("00"),
now.Hour.ToString("00"),
now.Minute.ToString("00"),
now.Second.ToString("00"));
timeDateTextBlock.Text = timeDateString;
//statusInfoTextBlock.Text = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds).ToString();
}
private void Window_Closed(object sender, EventArgs e)
{
try
{
server.Close();
server = null;
server.Dispose();
}
catch
{
}
}
private void Switch_Button_Click(object sender, RoutedEventArgs e)
{
Button bt = sender as Button;
if (bt.Content.ToString() == "请求连接")
{
//判断IP是否为空
if (IPAdressTextBox.Text.Trim() == string.Empty)
{
_ = new MessageWindow()
{
Owner = this,
Header = "警告",
Message = "请填入服务器IP地址"
}.ShowDialog();
//ComWinTextBox.Dispatcher.Invoke(new showData(ComWinTextBox.AppendText), "请填入服务器IP地址\n");
return;
}
//判断IP是否正确
if (Regex.Matches(IPAdressTextBox.Text.Trim(), Regex.Escape(new string('.', 1))).Count != 3)
{
_ = new MessageWindow()
{
Owner = this,
Header = "错误",
Message = "服务器IP地址无效"
}.ShowDialog();
//ComWinTextBox.Dispatcher.Invoke(new showData(ComWinTextBox.AppendText), "请填入服务器IP地址\n");
return;
}
//判断端口是否为空
if (PortTextBox.Text.Trim() == string.Empty)
{
_ = new MessageWindow()
{
Owner = this,
Header = "警告",
Message = "请填入服务器端口号"
}.ShowDialog();
//ComWinTextBox.Dispatcher.Invoke(new showData(ComWinTextBox.AppendText), "请填入服务器端口号\n");
return;
}
//判断端口是否能转成数字
if (!Regex.IsMatch(PortTextBox.Text.Trim(), @"^[+-]?\d*[.]?\d*$"))
{
_ = new MessageWindow()
{
Owner = this,
Header = "错误",
Message = "服务器端口号无效"
}.ShowDialog();
//ComWinTextBox.Dispatcher.Invoke(new showData(ComWinTextBox.AppendText), "请填入服务器端口号\n");
return;
}
else if (Convert.ToDouble(PortTextBox.Text.Trim()) > 65535)
{
_ = new MessageWindow()
{
Owner = this,
Header = "错误",
Message = "服务器端口号无效"
}.ShowDialog();
//ComWinTextBox.Dispatcher.Invoke(new showData(ComWinTextBox.AppendText), "请填入服务器端口号\n");
return;
}
try
{
IPAddress ip = IPAddress.Parse(IPAdressTextBox.Text);
//ComWinTextBox.AppendText("开始连接服务端....\n");
//client = new TcpClient();
server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//ComWinTextBox.AppendText("已经创建服务器....\n");
//client.Connect(ip, int.Parse(PortTextBox.Text));
server.Bind(new IPEndPoint(ip, int.Parse(PortTextBox.Text)));
//ComWinTextBox.AppendText("已经绑定客户端....\n");
//ComWinTextBox.AppendText("已经连接服务端\n");
statusInfoTextBlock.Text = "建立接收透传数据成功";
//sendStream = client.GetStream();
if (thread.ThreadState == ThreadState.Aborted)
{
thread = new Thread(ListenerServer);
thread.IsBackground = true;
}
if (thread.ThreadState == (ThreadState.Unstarted | ThreadState.Background))
{
thread.Start();
}
bt.Content = "断开连接";
imageBtn.Source = bitmapImage2;
}
catch
{
_ = new MessageWindow()
{
Owner = this,
Header = "错误",
Message = "连接服务端失败"
}.ShowDialog();
//ComWinTextBox.AppendText("连接服务端失败\n");
statusInfoTextBlock.Text = "服务器未连接";
}
}
else
{
thread.Abort();
//sendStream.Close();
server.Close();
server = null;
bt.Content = "请求连接";
imageBtn.Source = bitmapImage1;
//ComWinTextBox.AppendText("已与服务器断开连接\n");
statusInfoTextBlock.Text = "已与服务器断开连接";
}
}
private void ListenerServer()
{
do
{
try
{
int readSize;
byte[] buffer = new byte[bufferSize];
EndPoint point = new IPEndPoint(IPAddress.Any, 0);
//lock (sendStream)
//{
//readSize = sendStream.Read(buffer, 0, bufferSize);
//}
readSize = server.ReceiveFrom(buffer, ref point);
if (readSize == 0)return;
//16进制处理模式
//string receiveData = byteToHexStr(buffer, readSize);
string receiveDataDefault = Encoding.UTF8.GetString(buffer, 0, readSize);
double[] XYZ_axis = StringToDouble3(receiveDataDefault);
X_axis = XYZ_axis[0];
Y_axis = XYZ_axis[1];
Z_axis = XYZ_axis[2];
//ComWinTextBox.Dispatcher.Invoke(new showData(ComWinTextBox.AppendText), "信息:" + receiveDataDefault + " + " + receiveDataDefault.Length + "\n");
//ComWinTextBox.Dispatcher.Invoke(new showData(ComWinTextBox.AppendText), "信息:" + X_axis + " + " + Y_axis + " + " + Z_axis + "+" + thisSteps + "\n");
}
catch
{
//ComWinTextBox.Dispatcher.Invoke(new showData(ComWinTextBox.AppendText), "接收数据错误\n");
//statusInfoTextBlock.Text = "接收数据发生错误";//用异步改写一下
//break;
}
} while (true);
}
/// <summary>
/// 后期可能要删除
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
//private void ComWinTextBox_TextChanged(object sender, TextChangedEventArgs e)
//{
// ComWinTextBox.ScrollToEnd(); //当通信窗口内容有变化时保持滚动条在最下面
//}
/// <summary>
/// 接收字符转double数组
/// 获取三轴加速度double值
/// </summary>
/// <param name="receive"></param>
/// <returns></returns>
public double[] StringToDouble3(string receive)
{
List<double> XYZacceleration = new List<double>();
Regex rg = new Regex("(?<=(" + ":" + "))[.\\s\\S]*?(?=(" + "mG" + "))", RegexOptions.Multiline | RegexOptions.Singleline);
MatchCollection results = rg.Matches(receive);
foreach (Match result in results)
{
XYZacceleration.Add(Convert.ToDouble(result.Value) / 1000.0);
}
return XYZacceleration.ToArray();
}
/// <summary>
/// 字节转字符串
/// </summary>
/// <param name="bytes"></param>
/// <param name="readSize"></param>
/// <returns></returns>
public static string byteToHexStr(byte[] bytes, int readSize)
{
string returnStr = "";
if (bytes != null)
{
for (int i = 0; i < readSize; i++)
{
returnStr += bytes[i].ToString("X2");
}
}
return returnStr;
}
/// <summary>
/// 计步器x,y,z值由加速计获取
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
public void counterStep(double x, double y, double z)
{
double _sqrt = Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2) + Math.Pow(z, 2));
double _average = _sqrt * g;
detectorNewStep(_average);
}
/// <summary>
/// 监测新的步数 如果检测到了波峰,并且符合时间差以及阈值的条件,则判定为1步
/// 符合时间差条件,波峰波谷差值大于initialValue,则将该差值纳入阈值的计算中
/// </summary>
/// <param name="_values">加速传感器三轴的平均值</param>
public void detectorNewStep(double _values)
{
if (gravityOld == 0)
{
gravityOld = _values;
}
else
{
if (detectorPeak(_values, gravityOld))
{
timeOfLastPeak = timeOfThisPeak;
timeOfNow = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds);
//时间差大于200ms,小于2s
if (((timeOfNow - timeOfLastPeak) >= 200) && ((timeOfNow - timeOfLastPeak) <= 2000) && ((peakOfWave - valleyOfWave) >= ThreadValue))
{
timeOfThisPeak = timeOfNow;
//增加步数
thisSteps++;
//增加步数复制
StepsCopy++;
}
if(((timeOfNow - timeOfLastPeak) >= 200) && ((peakOfWave - valleyOfWave) >= initialValue))
{
timeOfThisPeak = timeOfNow;
double _diffWaveVal = peakOfWave - valleyOfWave;
ThreadValue = peak_Valley_Thread(_diffWaveVal);
}
}
gravityOld = _values;
}
}
/// <summary>
/// 监测波峰
/// 以下四个条件判断为波峰
/// 1.目前点为下降的趋势:isDirectionUp为false
/// 2.之前的点为上升的趋势:lastStatus为true
/// 3.到波峰为止,持续上升大于等于2次
/// 4.波峰值大于minValue,小于maxValue
/// 记录波谷值
/// 1.观察波形图,可以发现在出现步子的地方,波谷的下一个就是波峰,有比较明显的特征以及差值
/// 2.所以要记录每次的波谷值,为了和下次的波峰作对比
/// </summary>
/// <param name="_newValue"></param>
/// <param name="_oldValue"></param>
/// <returns></returns>
public Boolean detectorPeak(double _newValue, double _oldValue)
{
lastStatus = isDirectionUp;
if (_newValue >= _oldValue)
{
isDirectionUp = true;
continueUpCount++;
}
else
{
continueUpFormerCount = continueUpCount;
continueUpCount = 0;
isDirectionUp = false;
}
if (!isDirectionUp && lastStatus && (continueUpFormerCount >= 2 && (_oldValue >= minValue && _oldValue < maxValue)))
{
//满足上面波峰的四个条件,此时为波峰状态
peakOfWave = _oldValue;
return true;
}
else if (!lastStatus && isDirectionUp)
{
//满足波谷条件,此时为波谷状态
valleyOfWave = _oldValue;
return false;
}
else
{
return false;
}
}
/// <summary>
/// 阈值的计算
/// 1.通过波峰波谷的差值计算阈值
/// 2.记录4个值,存入tempValue[] 数组中
/// 3.在将数组传入函数averageValue中计算阈值
/// </summary>
/// <param name="_value"></param>
/// <returns></returns>
public double peak_Valley_Thread(double _value)
{
double _tempThread = ThreadValue;
List<double> _tempValue = new List<double>(tempValue);
if (tempValue.Count < valueNum)
{
tempValue.Add(_value);
}
else
{
//tempValue数组长度=valueNum=5
_tempThread = averageValue(tempValue);
_tempValue.RemoveAt(0);
_tempValue.Add(_value);
tempValue = _tempValue;
}
return _tempThread;
}
/// <summary>
/// 梯度化阈值
/// 1.计算数组的均值
/// 2.通过均值将阈值梯度化在一个范围里
/// 这些数据是通过大量的统计得到的
/// </summary>
/// <param name="_value"></param>
/// <returns></returns>
public double averageValue(List<double> _value)
{
if (_value.Count != 0)
{
double _ave = 0;
foreach (double i in _value)
_ave += i;
_ave = _ave / _value.Count;
if(_ave >= 8)
{
_ave = 4.3;
}
else if (_ave >= 7 && _ave < 8)
{
_ave = 3.3;
}
else if (_ave >= 4 && _ave < 7)
{
_ave = 2.3;
}
else if (_ave >= 3 && _ave < 4)
{
_ave = 2.0;
}
else
{
_ave = 1.7;
}
return _ave;
}
else
{
return 1.7;
}
}
private async void StepCountingMethod()
{
while (true)
{
counterStep(X_axis, Y_axis, Z_axis);
if(StepsCopy >= 50)
{
//清零
StepsCopy = 0;
Dispatcher.Invoke(new Action(() =>
{
//信息窗
new JumpPage()
{
NotifyMessage = "您已完成50步,加油!!!"
}.Show();
}));
}
//步数显示
Dispatcher.Invoke(() =>
{
StepNumberDisplay.Text = thisSteps.ToString();
MyBeautifulBar.Value = StepsCopy * 10;
});
await Task.Delay(100);
}
}
private void ToggleButton_Checked(object sender, RoutedEventArgs e)
{
//ComWinTextBox.AppendText("开始计步\n");
StepCounting = new Thread(StepCountingMethod);
StepCounting.Start();
//信息窗
new JumpPage()
{
NotifyMessage = "开始计步!!!"
}.Show();
}
private void ToggleButton_Unchecked(object sender, RoutedEventArgs e)
{
if(StepCounting.IsAlive == true)
{
StepCounting.Abort();
//ComWinTextBox.AppendText("计步结束\n");
}
//步数清零
thisSteps = 0;
//步数副本清零
StepsCopy = 0;
//信息窗
new JumpPage()
{
NotifyMessage = "计步结束!!!"
}.Show();
}
//扩展按钮
private void PseudoMaterializedButton3_Click(object sender, RoutedEventArgs e)
{
}
private void PseudoMaterializedButton4_Click(object sender, RoutedEventArgs e)
{
}
private void PseudoMaterializedButton2_Click(object sender, RoutedEventArgs e)
{
}
private void PseudoMaterializedButton1_Click(object sender, RoutedEventArgs e)
{
}
}
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/tytokongjian-StepCountingUpperPC.git
git@api.gitlife.ru:oschina-mirror/tytokongjian-StepCountingUpperPC.git
oschina-mirror
tytokongjian-StepCountingUpperPC
tytokongjian-StepCountingUpperPC
master