Commit d250dfe7 authored by 17임경현's avatar 17임경현

asdf

parent 44e7ca58
...@@ -17,6 +17,12 @@ void setup() ...@@ -17,6 +17,12 @@ void setup()
} }
} }
void writeulong(unsigned long x)
{
Serial.print(x, HEX);
Serial.print(" ");
}
void writefloat(float x) void writefloat(float x)
{ {
byte* ptr = (byte*)&x; byte* ptr = (byte*)&x;
...@@ -31,6 +37,7 @@ void loop() ...@@ -31,6 +37,7 @@ void loop()
{ {
IMU.readSensor(); IMU.readSensor();
Serial.print("="); Serial.print("=");
writeulong(micros());
writefloat(IMU.getAccelX_mss()); writefloat(IMU.getAccelX_mss());
writefloat(IMU.getAccelY_mss()); writefloat(IMU.getAccelY_mss());
writefloat(IMU.getAccelZ_mss()); writefloat(IMU.getAccelZ_mss());
......
<UserControl x:Class="wuhyuo.GraphRenderer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:wuhyuo"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" Loaded="UserControl_Loaded">
<Border BorderBrush="Black" BorderThickness="2">
<Grid ClipToBounds="True">
<Label x:Name="label" Content="{Binding Path=Text}"/>
<Canvas x:Name="canvas" HorizontalAlignment="Right" VerticalAlignment="Center">
<Canvas.RenderTransform>
<TranslateTransform x:Name="translate"/>
</Canvas.RenderTransform>
<Polyline x:Name="polyline" Points="0,0" Stroke="{Binding Path=Stroke}" />
</Canvas>
<Rectangle VerticalAlignment="Center" Height="4" Fill="#7F7F7F7F"/>
<Rectangle Width="4" HorizontalAlignment="Center" Fill="#7F7F7F7F"/>
</Grid>
</Border>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
namespace wuhyuo
{
/// <summary>
/// GraphRenderer.xaml에 대한 상호 작용 논리
/// </summary>
public partial class GraphRenderer : UserControl
{
public static readonly DependencyProperty TextProperty
= DependencyProperty.Register("Text", typeof(string), typeof(GraphRenderer), new UIPropertyMetadata(""));
public static readonly DependencyProperty StrokeProperty
= DependencyProperty.Register("Stroke", typeof(Brush), typeof(GraphRenderer), new UIPropertyMetadata(Brushes.Black));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public Brush Stroke
{
get { return (Brush)GetValue(StrokeProperty); }
set { SetValue(StrokeProperty, value); }
}
public GraphRenderer()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, EventArgs e)
{
label.Content = Text;
polyline.Stroke = Stroke;
polyline.StrokeThickness = 2;
}
public void AddValue(double time, double value)
{
double x = 50 * time;
double y = 10 * value;
polyline.Points.Add(new Point(x, y));
translate.X = -x;
}
}
}
<Window x:Class="WpfApp1.MainWindow" <Window x:Class="wuhyuo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1" xmlns:local="clr-namespace:wuhyuo"
mc:Ignorable="d" mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Initialized="Window_Initialized" Closed="Window_Closed"> Title="MainWindow" Width="1280" Height="906" Loaded="Window_Loaded" Closed="Window_Closed">
<Grid Margin="20"> <Grid Margin="20">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition /> <RowDefinition Height="2*"/>
<RowDefinition /> <RowDefinition Height="2*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition /> <ColumnDefinition/>
<ColumnDefinition /> <ColumnDefinition/>
<ColumnDefinition /> <ColumnDefinition/>
<ColumnDefinition /> <ColumnDefinition/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Border BorderBrush="Black" BorderThickness="2" Grid.Row="0" Grid.Column="0"> <local:GraphRenderer x:Name="accelX" Text="AccelX" Stroke="Red" Grid.Row="0" Grid.Column="0"/>
<Grid ClipToBounds="True"> <local:GraphRenderer x:Name="accelY" Text="AccelY" Stroke="Orange" Grid.Row="0" Grid.Column="1"/>
<Label>AccelX</Label> <local:GraphRenderer x:Name="accelZ" Text="AccelZ" Stroke="DarkKhaki" Grid.Row="0" Grid.Column="2"/>
<Canvas x:Name="canvas1" HorizontalAlignment="Right" VerticalAlignment="Center"/> <local:GraphRenderer x:Name="accelTotal" Text="Accel Total" Stroke="CornflowerBlue" Grid.Row="0" Grid.Column="3"/>
</Grid> <local:GraphRenderer x:Name="gyroX" Text="GyroX" Stroke="Green" Grid.Row="1" Grid.Column="0"/>
</Border> <local:GraphRenderer x:Name="gyroY" Text="GyroZ" Stroke="Blue" Grid.Row="1" Grid.Column="1"/>
<Border BorderBrush="Black" BorderThickness="2" Grid.Row="0" Grid.Column="1"> <local:GraphRenderer x:Name="gyroZ" Text="GyroY" Stroke="Purple" Grid.Row="1" Grid.Column="2"/>
<Grid ClipToBounds="True"> <local:GraphRenderer x:Name="gyroTotal" Text="GyroTotal" Stroke="Chocolate" Grid.Row="1" Grid.Column="3"/>
<Label>AccelY</Label> <Grid Grid.Row="2" Grid.ColumnSpan="4">
<Canvas x:Name="canvas2" HorizontalAlignment="Right" VerticalAlignment="Center"/> <WrapPanel>
</Grid> <Button Click="Button_Click" FontSize="48">Reset</Button>
</Border> </WrapPanel>
<Border BorderBrush="Black" BorderThickness="2" Grid.Row="0" Grid.Column="2"> <Viewport3D>
<Grid ClipToBounds="True"> <Viewport3D.Camera>
<Label>AccelZ</Label> <PerspectiveCamera
<Canvas x:Name="canvas3" HorizontalAlignment="Right" VerticalAlignment="Center"/> FarPlaneDistance="100" NearPlaneDistance="1" LookDirection="0, 0, -1" UpDirection="0, 1, 0"
</Grid> Position="0, 0, 10" FieldOfView="70"/>
</Border> </Viewport3D.Camera>
<Border BorderBrush="Black" BorderThickness="2" Grid.Row="0" Grid.Column="3"> <ModelVisual3D>
<Grid ClipToBounds="True"> <ModelVisual3D.Transform>
<Label>Accel Total</Label> <RotateTransform3D>
<Canvas x:Name="canvas4" HorizontalAlignment="Right" VerticalAlignment="Center"/> <RotateTransform3D.Rotation>
</Grid> <QuaternionRotation3D x:Name="viewRotate"/>
</Border> </RotateTransform3D.Rotation>
<Border BorderBrush="Black" BorderThickness="2" Grid.Row="1" Grid.Column="0"> </RotateTransform3D>
<Grid ClipToBounds="True"> </ModelVisual3D.Transform>
<Label>GryoX</Label> <ModelVisual3D.Content>
<Canvas x:Name="canvas5" HorizontalAlignment="Right" VerticalAlignment="Center"/> <Model3DGroup>
</Grid> <DirectionalLight Color="White" Direction="-2, -3, -1"/>
</Border> <GeometryModel3D>
<Border BorderBrush="Black" BorderThickness="2" Grid.Row="1" Grid.Column="1"> <GeometryModel3D.Geometry>
<Grid ClipToBounds="True"> <MeshGeometry3D
<Label>GyroY</Label> Positions="0.293893 -0.5 0.404509 0.475528 -0.5 0.154509 0 0.5 0 0.475528 -0.5 0.154509 0 0.5 0 0 0.5 0 0.475528 -0.5 0.154509 0.475528 -0.5 -0.154509 0 0.5 0 0.475528 -0.5 -0.154509 0 0.5 0 0 0.5 0 0.475528 -0.5 -0.154509 0.293893 -0.5 -0.404509 0 0.5 0 0.293893 -0.5 -0.404509 0 0.5 0 0 0.5 0 0.293893 -0.5 -0.404509 0 -0.5 -0.5 0 0.5 0 0 -0.5 -0.5 0 0.5 0 0 0.5 0 0 -0.5 -0.5 -0.293893 -0.5 -0.404509 0 0.5 0 -0.293893 -0.5 -0.404509 0 0.5 0 0 0.5 0 -0.293893 -0.5 -0.404509 -0.475528 -0.5 -0.154509 0 0.5 0 -0.475528 -0.5 -0.154509 0 0.5 0 0 0.5 0 -0.475528 -0.5 -0.154509 -0.475528 -0.5 0.154509 0 0.5 0 -0.475528 -0.5 0.154509 0 0.5 0 0 0.5 0 -0.475528 -0.5 0.154509 -0.293892 -0.5 0.404509 0 0.5 0 -0.293892 -0.5 0.404509 0 0.5 0 0 0.5 0 -0.293892 -0.5 0.404509 0 -0.5 0.5 0 0.5 0 0 -0.5 0.5 0 0.5 0 0 0.5 0 0 -0.5 0.5 0.293893 -0.5 0.404509 0 0.5 0 0.293893 -0.5 0.404509 0 0.5 0 0 0.5 0 "
<Canvas x:Name="canvas6" HorizontalAlignment="Right" VerticalAlignment="Center"/> Normals="0.7236065,0.4472139,0.5257313 0.2763934,0.4472138,0.8506507 0.5308242,0.4294462,0.7306172 0.2763934,0.4472138,0.8506507 0,0.4294458,0.9030925 0.5308242,0.4294462,0.7306172 0.2763934,0.4472138,0.8506507 -0.2763934,0.4472138,0.8506507 0,0.4294458,0.9030925 -0.2763934,0.4472138,0.8506507 -0.5308242,0.4294462,0.7306172 0,0.4294458,0.9030925 -0.2763934,0.4472138,0.8506507 -0.7236065,0.4472139,0.5257313 -0.5308242,0.4294462,0.7306172 -0.7236065,0.4472139,0.5257313 -0.858892,0.429446,0.279071 -0.5308242,0.4294462,0.7306172 -0.7236065,0.4472139,0.5257313 -0.8944269,0.4472139,0 -0.858892,0.429446,0.279071 -0.8944269,0.4472139,0 -0.858892,0.429446,-0.279071 -0.858892,0.429446,0.279071 -0.8944269,0.4472139,0 -0.7236065,0.4472139,-0.5257313 -0.858892,0.429446,-0.279071 -0.7236065,0.4472139,-0.5257313 -0.5308242,0.4294462,-0.7306172 -0.858892,0.429446,-0.279071 -0.7236065,0.4472139,-0.5257313 -0.2763934,0.4472138,-0.8506507 -0.5308242,0.4294462,-0.7306172 -0.2763934,0.4472138,-0.8506507 0,0.4294458,-0.9030925 -0.5308242,0.4294462,-0.7306172 -0.2763934,0.4472138,-0.8506507 0.2763934,0.4472138,-0.8506507 0,0.4294458,-0.9030925 0.2763934,0.4472138,-0.8506507 0.5308249,0.4294459,-0.7306169 0,0.4294458,-0.9030925 0.2763934,0.4472138,-0.8506507 0.7236068,0.4472141,-0.5257306 0.5308249,0.4294459,-0.7306169 0.7236068,0.4472141,-0.5257306 0.8588922,0.4294461,-0.27907 0.5308249,0.4294459,-0.7306169 0.7236068,0.4472141,-0.5257306 0.8944269,0.4472139,0 0.8588922,0.4294461,-0.27907 0.8944269,0.4472139,0 0.858892,0.429446,0.279071 0.8588922,0.4294461,-0.27907 0.8944269,0.4472139,0 0.7236065,0.4472139,0.5257313 0.858892,0.429446,0.279071 0.7236065,0.4472139,0.5257313 0.5308242,0.4294462,0.7306172 0.858892,0.429446,0.279071 "
</Grid> TriangleIndices="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 " />
</Border> </GeometryModel3D.Geometry>
<Border BorderBrush="Black" BorderThickness="2" Grid.Row="1" Grid.Column="2"> <GeometryModel3D.Material>
<Grid ClipToBounds="True"> <DiffuseMaterial>
<Label>GyroZ</Label> <DiffuseMaterial.Brush>
<Canvas x:Name="canvas7" HorizontalAlignment="Right" VerticalAlignment="Center"/> <SolidColorBrush Color="Red"/>
</Grid> </DiffuseMaterial.Brush>
</Border> </DiffuseMaterial>
<Border BorderBrush="Black" BorderThickness="2" Grid.Row="1" Grid.Column="3"> </GeometryModel3D.Material>
<Grid ClipToBounds="True"> </GeometryModel3D>
<Label>Gyro Total</Label> </Model3DGroup>
<Canvas x:Name="canvas8" HorizontalAlignment="Right" VerticalAlignment="Center"/> </ModelVisual3D.Content>
</Grid> </ModelVisual3D>
</Border> </Viewport3D>
</Grid>
</Grid> </Grid>
</Window> </Window>
...@@ -14,8 +14,10 @@ using System.Windows.Navigation; ...@@ -14,8 +14,10 @@ using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
using System.Threading; using System.Threading;
using System.IO.Ports; using System.IO.Ports;
using System.IO;
using System.Windows.Media.Media3D;
namespace WpfApp1 namespace wuhyuo
{ {
/// <summary> /// <summary>
/// MainWindow.xaml에 대한 상호 작용 논리 /// MainWindow.xaml에 대한 상호 작용 논리
...@@ -27,81 +29,107 @@ namespace WpfApp1 ...@@ -27,81 +29,107 @@ namespace WpfApp1
InitializeComponent(); InitializeComponent();
} }
private void Window_Initialized(object sender, EventArgs e) private void Window_Loaded(object sender, EventArgs e)
{ {
renderer = new GraphRenderer[] {
new GraphRenderer(canvas1, Colors.Red),
new GraphRenderer(canvas2, Colors.Orange),
new GraphRenderer(canvas3, Colors.DarkKhaki),
new GraphRenderer(canvas4, Colors.CornflowerBlue),
new GraphRenderer(canvas5, Colors.Green),
new GraphRenderer(canvas6, Colors.Blue),
new GraphRenderer(canvas7, Colors.Purple),
new GraphRenderer(canvas8, Colors.Chocolate),
};
_thrd = new Thread(InputThread); _thrd = new Thread(InputThread);
_thrd.Start(); _thrd.Start();
} }
private void Window_Closed(object sender, EventArgs e) private void Window_Closed(object sender, EventArgs e)
{ {
_thrd.Abort(); _thrdStop = true;
_thrd.Join(); _thrd?.Join();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
viewRotate.Quaternion = Quaternion.Identity;
} }
private void InputThread() private void InputThread()
{ {
SerialPort port = new SerialPort("COM8", 115200); bool started = false;
uint? prevTime = null;
try try
{ {
SerialPort port = new SerialPort("COM8", 115200);
port.Open(); port.Open();
while (true) while (!_thrdStop)
{ {
string input;
try try
{ {
string input = port.ReadLine(); input = port.ReadLine();
if (input.FirstOrDefault() != '=') }
catch (TimeoutException)
{
continue;
}
foreach (string line in input.Split('\r', '\n').Where(x => x.Length > 0))
{
if (line.FirstOrDefault() != '=')
continue; continue;
double[] values = input.Substring(1).Split(" \t\r\n".ToArray()).Where(x => x.Length > 0) if (!started)
{
started = true;
continue;
}
string[] tokens = input.Substring(1)
.Split(' ', '\t', '\r', '\n').Where(x => x.Length > 0).ToArray();
if (tokens.Length != 7)
continue;
uint micros = Convert.ToUInt32(tokens[0], 16);
double[] values = tokens.Skip(1)
.Select(x => (double)uint2float(Convert.ToUInt32(x, 16))).ToArray(); .Select(x => (double)uint2float(Convert.ToUInt32(x, 16))).ToArray();
if (values.Length != 6)
if (prevTime is null || prevTime.Value >= micros)
{
prevTime = micros;
continue; continue;
}
double dt = (micros - prevTime.Value) / 1000000.0;
System.Diagnostics.Debug.Assert(dt < 1000);
Dispatcher.InvokeAsync(() => Dispatcher.InvokeAsync(() =>
{ {
renderer[0].AddValue(values[0]); double wx = values[3];
renderer[1].AddValue(values[1]); double wy = values[4];
renderer[2].AddValue(values[2]); double wz = values[5];
renderer[4].AddValue(values[3]); var w = new Vector3D(wx, wy, wz);
renderer[5].AddValue(values[4]); var p = new Quaternion(w, w.Length);
renderer[6].AddValue(values[5]); viewRotate.Quaternion = p * viewRotate.Quaternion;
accelX.AddValue(dt, values[0]);
accelY.AddValue(dt, values[1]);
accelZ.AddValue(dt, values[2]);
gyroX.AddValue(dt, values[3]);
gyroY.AddValue(dt, values[4]);
gyroZ.AddValue(dt, values[5]);
double acc = Math.Sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]); double acc = Math.Sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);
double gyro = Math.Sqrt(values[3] * values[3] + values[4] * values[4] + values[5] * values[5]); double gyro = Math.Sqrt(values[3] * values[3] + values[4] * values[4] + values[5] * values[5]);
renderer[3].AddValue(acc); accelTotal.AddValue(dt, acc);
renderer[7].AddValue(gyro); gyroTotal.AddValue(dt, gyro);
}); });
} }
catch (FormatException) { }
catch (TimeoutException) { }
catch (OverflowException) { }
} }
} }
catch (InvalidOperationException) catch (InvalidOperationException ex)
{ {
Dispatcher.Invoke(() => Dispatcher.Invoke(() =>
{ {
MessageBox.Show("arduino connection closed"); MessageBox.Show("serial communication error: " + ex.Message);
_thrd = null;
Close(); Close();
}); });
} }
finally
{
port.Close();
}
} }
private static unsafe float uint2float(uint value) private static unsafe float uint2float(uint value)
...@@ -110,60 +138,6 @@ namespace WpfApp1 ...@@ -110,60 +138,6 @@ namespace WpfApp1
} }
private Thread _thrd; private Thread _thrd;
private volatile bool _thrdStop = false;
private GraphRenderer[] renderer;
}
class GraphRenderer
{
public Canvas Canvas { get; }
public Color Color { get; set; }
public double Time { get; set; }
public double DeltaTime { get; set; }
public double Value { get; set; }
private TranslateTransform translate = new TranslateTransform();
private ScaleTransform scale = new ScaleTransform();
private List<Line> lines = new List<Line>();
public GraphRenderer(Canvas canvas, Color color)
{
Canvas = canvas;
Color = color;
Time = 0;
Value = 0;
DeltaTime = 1;
var transform = new TransformGroup();
transform.Children.Add(translate);
transform.Children.Add(scale);
Canvas.RenderTransform = transform;
}
public void AddValue(double newValue)
{
Line line = new Line();
line.X1 = Time;
line.Y1 = 10 * Value;
line.X2 = Time + DeltaTime;
line.Y2 = 10 * newValue;
line.StrokeThickness = 1;
line.Stroke = new SolidColorBrush(Color);
Canvas.Children.Add(line);
translate.X = -Time;
lines.Add(line);
if (lines.Count > 1000)
{
Canvas.Children.Remove(lines[0]);
lines.RemoveAt(0);
}
Value = newValue;
Time += DeltaTime;
}
} }
} }
...@@ -57,6 +57,10 @@ ...@@ -57,6 +57,10 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Page Include="GraphRenderer.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MainWindow.xaml"> <Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
...@@ -65,6 +69,9 @@ ...@@ -65,6 +69,9 @@
<DependentUpon>App.xaml</DependentUpon> <DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="GraphRenderer.xaml.cs">
<DependentUpon>GraphRenderer.xaml</DependentUpon>
</Compile>
<Compile Include="MainWindow.xaml.cs"> <Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon> <DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment