分类: Matlab |
今天闲来无事想起来以前在MATLAB中进行坐标变换都自己编写了坐标转换函数,MATLAB中应该会有吧,找了下帮助果真有,其实在MATLAB的AerospaceToolBox中封装好了很多坐标转换函数,可以直接调用完成对坐标系相对关系的描述。
Create direction cosine matrix from rotation angles
由旋转角度创建方向余弦矩阵
dcm =
angle2dcm(rotationAng1,
rotationAng2, rotationAng3)
dcm = angle2dcm(rotationAng1,
rotationAng2, rotationAng3,
rotationSequence)
dcm = angle2dcm(rotationAng1, rotationAng2, rotationAng3) calculates the direction cosine matrix given three sets of rotation angles. 由三个旋转角计算方向余弦矩阵
dcm = angle2dcm(rotationAng1, rotationAng2, rotationAng3, rotationSequence) calculates the direction cosine matrix using a rotation sequence.由特定的旋转序列计算方向余弦矩阵
这里的旋转角是指右手系下的旋转方向为正如图
而得出的方向余弦矩阵dcm 是由原坐标系经旋转后到新坐标系的转换矩阵。
例如在导航专业中用到的导航坐标系到载体坐标系的旋转就可以用此函数求的,而求的的方向余弦矩阵为导航坐标系转向载体坐标系的,即Cnb
rotationAng1 |
m-by-1 array of first rotation angles, in radians. 第一个旋转角 |
|||||||||||||
rotationAng2 |
m-by-1 array of second rotation angles, in radians. 第二个旋转角 |
|||||||||||||
rotationAng3 |
m-by-1 array of third rotation angles, in radians.第三个旋转角 |
|||||||||||||
rotationSequence |
String that defines rotation sequence. For example, the default 'ZYX' represents a sequence where rotationAng1 is z-axis rotation, rotationAng2 is y-axis rotation, and rotationAng3 is x-axis rotation. 定义旋转序列的字符串。例如默认的'ZYX'表示了一个这样的旋转顺序:rotationAng1是绕Z轴旋转,rotationAng2 是绕y轴旋转,rotationAng3绕x轴旋转。共有如下几种形式:
|
dcm |
3-by-3-by-m matrix containing m direction cosine matrices. 3X3的方向余弦矩阵
|
Examples
将原坐标系axis1先沿着z轴旋转20度,沿着x轴旋转30度,再沿着y轴旋转45度,得到新的坐标系axis2。
那么在坐标系axis1中的点A(2,3,4)在新的坐标系axis2中的坐标B用以下方法来求得:
A=[2;3;4];
dcm=angle2dcm(20*pi/180,30*pi/180,45*pi/180,'ZXY');
B=dcm*A
>> B
=
0.359820367873134
3.848996778596074
3.749100305569416
即B坐标为(0.359820367873134,3.848996778596074,3.749100305569416)
在这里,方向余弦矩阵有个性质,即:方向余弦矩阵是正交的,就是其逆等于其转置 dcm'=inv(dcm);
所以如果需要坐标反向转换,只需要这样用:
dcm_inv=dcm';
C=dcm_inv*B;
>> C =
2.000000000000000
3.000000000000000
4.000000000000000
标签:
杂谈 |
分类: c# |
请勿转载,我会不断的更新和修改。
修改日志:
1 20091112创建文档
2 20091113发送函数介绍,数据的接收,上位机基本功能的完成
一、创建Windows窗体项目
二、添加SerialPort组件
三、默认产生serialPort1对象
四、设置串口属性
三种方法(本实例用第三种)
1.设置下面的属性
2.代码实现
3.用我封装的一个类来实现
C# 封装了用于对 Serialport类属性的配置类及其保存窗
五、串口操作(打开关闭)
按上述步骤初始化串口之后进行串口的打开和关闭操作
打开关闭串口的函数包含在SerialPort类中,利用SerialPort对象来引用
serialPort1.Open();
serialPort1.Close();
例如:在程序中添加一个打开串口按钮btn_open,btn_open.Text初始化为"打开串口"
在btn_open响应函数中加入以下代码
此时形成的界面截图如下:
此时程序的代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AHRSmanager;
namespace testOfserialPort
{
public
partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void serialPort1_DataReceived(object sender,
System.IO.Ports.SerialDataReceivedEventArgs e)
{
}
private void btn_SerialportSet_Click(object sender, EventArgs
e)
{
using (串口设置窗口 frmConfig = new 串口设置窗口())
{
frmConfig.ShowDialog();
}
}
private void btn_open_Click(object sender, EventArgs e)
{
if (btn_open.Text == "打开串口")
{
串口设置窗口.ReadSerialPortSet(serialPort1);
//串口初始化
btn_open.Text = "关闭串口";
serialPort1.Open();
}
else
{
btn_open.Text = "打开串口";
serialPort1.Close();
}
}
private void Form1_Load(object sender, EventArgs e)
{
btn_open.Text = "打开串口";
}
}
}
这时该程序已经具有开关串口的作用,可以用 单PC机虚拟串口互连方法 介绍的方法进行串口测试(串口互联模式)
运行程序,点击串口配置按钮,进行参数配置,点击打开串口,VSPM就将显示串口的打开和关闭.
六、数据的发送
(一) 十六进制数据发送
使用方法见 C#中用SerialPort类中的Write()方法发送十六进制数
1.为程序添加发送按钮,命名为btn_send,为程序添加文本输入框tb_send
2.在btn_send的回调函数中添加以下代码
3.测试
将串口配置为COM3,打开VSPM和串口调试助手,调试助手为COM4
打开串口COM3,将要发送的数写入输入文本框(0-255),点击发送在串口调试助手中就会出现相应的十六进制数据显示
命名空间: System.IO.Ports
程序集: System(在 System.dll 中)
除了前面用到的串口常规属性设置(BuadRate,PortName),这里用到了一个新的串口属性:
ms-help://MS.MSDNQTR.v90.chs/fxref_system/icons/pubproperty.gif ms-help://MS.MSDNQTR.v90.chs/fxref_system/icons/CFW.gif | ReceivedBytesThreshold | 获取或设置 DataReceived 事件发生前内部输入缓冲区中的字节数。 |
这个ReceiveBytesThreshold属性即是设置串口输入缓冲区中的数据字节大于ReceiveBytesThreshold时触发DataReceived事件。
用法:
<1>在设计器双击串口serialport1的DataReceived事件,在代码中就会自动加入serialPort1_DataReceived函数作为DateReceived的事件触发函数。
<2>作为测试,先将serialport1.ReceiveBytesThreshold设为1,即串口输入缓冲区有数就触发DataReceived事件。
<3>加入RichTextBox rTB_receive作为串口接收数据的显示组件
<4>在DataReceived事件响应函数中读取串口输入缓冲区中的数据
string serialReadString;
private void serialPort1_DataReceived(object sender,
System.IO.Ports.SerialDataReceivedEventArgs e)
{
serialReadString += serialPort1.ReadExisting();
}
这里serialReadString即为读取到串口输入缓冲区的数据。
要想将其显示到RichTextBox rTB_receive中,这里出现了一个跨线程的问题,因为DataReceived事件是在辅助线程中被激发的,所以要将数据显示到rTB_receive的主线程中就要进行一定的处理,处理方法如下:
C#中SerialPort类中DataReceived事件GUI实时处理方法
string serialReadString;
private void serialPort1_DataReceived(object sender,
System.IO.Ports.SerialDataReceivedEventArgs e)
{
serialReadString = serialPort1.ReadExisting();
this.rTB_receive.Invoke
(
new MethodInvoker
(
delegate
{
this.rTB_receive.AppendText(serialReadString);
}
)
);
}
标签:
c绘图zedgraph |
分类: c# |
该控件来自于CodeProject
http://www.codeproject.com/KB/graphics/zedgraph.aspx
我大多的.NET程序的绘图程序都用的是这个控件。下面是这个控件的文档翻译及其基本使用方法。
A flexible charting library for .NET By JChampionIntroduction
ZedGraph是一个类库,为Windows Forms 设计的用户控件,该控件可以通过专业的数据资料创建2D线、Bar和Pie图像。该类库提供高度的灵活性——几乎每一个图像的部分都能由用户修改。于此同时,通过为所有图像的属性提供缺省值使类库的用法保持简单。类库中包括选择合适的刻度因数范围和基于被显示值的的数据范围的步长值的代码。此外,ZedGraph 兼容于.NET 2.0和VS.NET 2005.
ZeGraph 是作为开源开发工程在SourceForge被维护的。该网站包括该项目的wiki、文档、更新历史和所有的发行版本。
Wiki上含有一套简单的图像实例由公开的代码完成(许多的例子包括C#和VB代码)。
Background
我们可以寻找到很多的绘图类库,但是似乎没有一个能够满足我的需要。我发现MSCHART太诡异了,许多其他的选项都不具有可配置性但我需要达到一种精致的外观。当然,许多商业开发包能够做这种花招,但是我需要某种免费的东东。由此,ZedGraph产生了!
这个类库将可以产生各种线型、条形、图形分割统计图表在Form上,考虑到位置矩形和一些数据点(翻译的有点诡异,没太看明白)。ZedGraph处理二维线形或散点图形,所彩的百分数条形图形,误差条形图像,日本烛台图形和图形分割统计图表——他现在还不能处理2.5D或3D表面图形。可以通过坐标轴标签、标题、图例标签、文字标签、箭头、镜像等对象修饰图像。
ZedGraphWiki 和online class documentation 提供了大量的有用的信息,针对其提供更多的信息,ZedGraph 有大量的选项没有在这个入门文档中提供。
Using ZedGraph as a UserControl
将ZedGraph作为一个控件可由Visual Studio.NET的控件工具箱中获取。 要创建ZedGraph,首先要打开Visual Studio.NET,创建一个新的Forms项目。打开form设计器使其出现在当前窗口,如下图
右击工具箱->选择项
点击浏览定位到 zedgraph.dll文件,并添加。
一旦添加了此文件,你会看到ZedGraphControl选项在工具箱中。如下图
SetSize()
方法。(这里假定你的控件名称为zedGraphControl1)// form 'Resize' 的事件相应方法
private void Form1_Resize( object sender,
EventArgs e )
{
SetSize();
}
//SetSize() 是独立于Resize()的,所以我们能够独立的调用他通过Form1_Load() 方法。
//这将保留10像素环绕控件的外部边缘,定制这些使之适合你的需要。
private void SetSize()
{
zedGraphControl1.Location = new Point( 10, 10
);
//保留一个小的页面空白在控件的周围
zedGraphControl1.Size = new Size( ClientRectangle.Width -
20,
ClientRectangle.Height - 20 );
}
// Load事件的相应函数
private void Form1_Load( object sender, EventArgs e )
{
// 装载图像
CreateGraph( zedGraphControl1 );
//设定控件的大小填充form
SetSize();
}
// 创建图像
private void CreateGraph( ZedGraphControl zgc )
{
//得到GraphPane的引用
GraphPane myPane = zgc.GraphPane;
// 设置标题
myPane.Title.Text = "My Test Graph\n(For CodeProject
Sample)";
myPane.XAxis.Title.Text = "My X Axis";
myPane.YAxis.Title.Text = "My Y Axis";
//生成正弦函数的数据集合
double x, y1, y2;
PointPairList list1 = new PointPairList();
PointPairList list2 = new PointPairList();
for ( int i = 0; i < 36; i++
)
{
x
= (double)i + 5;
y1
= 1.5 + Math.Sin( (double)i * 0.2 );
y2
= 3.0 * ( 1.5 + Math.Sin( (double)i * 0.2 )
);
list1.Add(
x, y1 );
list2.Add(
x, y2 );
}
//用钻石符合形状生成红色的曲线和图例
LineItem myCurve = myPane.AddCurve(
"Porsche",
list1, Color.Red, SymbolType.Diamond );
//利用圆型的符号生成蓝色的曲线和图例
LineItem myCurve2 = myPane.AddCurve(
"Piper",
list2, Color.Blue, SymbolType.Circle );
//告诉ZedGraph 去重新描绘坐标轴当数据变化时
zgc.AxisChange();
}
8. 执行效果
Enhancing the graph
ZedGraph 允许你通过多种途径更改图形的属性,图像的每个部分都被打包成一个类结构体,这个结构体有可更改的属性去控制图形的输出。下面就是一些在ZedGraph中提供的类(注意这些类是XML文档,详细的细节中每个类请看ZedGraph documentation )
Class |
Description |
MasterPane |
这是一个管理多个GraphPane对象的类,继承于PaneBase。MasterPane类的应用是可选的,因为GraphPane类能够直接用于单个面板。提供布局、排列和单个GraphPane对象的管理的方法 |
GraphPane | 图像的主要类,继承自PaneBase。包含所有其他的类作为属性。多用于控制图像面板的标题、窗框架和坐标轴框架、背景等属性。 |
XAxis, |
Axis类的子类。这些类包括了很多坐标轴显示的形式,包括:刻度、网格、颜色、画笔、字体、标签和类型。 |
Scale |
通过Axis类声明的一个类实例。包括刻度范围、步长、格式和刻度的显示选项。由Linear,
Log , Text , Date ,
Ordinal , Exponent ,
LinearAsOrdinal , and DateAsOrdinal
scales的不同而不同。 |
Legend |
此类为描述位置、字体、颜色等性质的类,用于绘制图例 |
CurveItem |
一个对应单条曲线并包含数据的抽象基类。LineItem,
BarItem , HiLowBarItem ,
ErrorBarItem , PieItem ,
StickItem , OHLCBarItem , and
JapaneseCandleStickItem 都继承于此类。 |
CurveList |
一个集合类维护了一个CurveItem的对象链表。在链表中的曲线的顺序控制着 Z-顺序为了绘图。在链表中最后的曲线将会出现在其她的曲线之后。 |
GraphObj |
这是一个抽象的基类,他包含了多种的追加图像对象在一个分块中的位置信息。TextObj,
ImageObj , LineObj , ArrowObj ,
EllipseObj , BoxObj , and
PolyObj 都继承自GraphObj . |
GraphObjList |
一个维护GraphObj链表的集合类。 |
FontSpec |
包括字体信息的功能类,主要是关于图像上字体的颜色、角度、大小、样式、框架和字体的背景填充。每一个包含字体信息的类将会包含一个或几个FontSpec的对象去相应的描述相关联的字体。 |
Fill |
包括背景颜色特性的功能类。每一个含有色彩填充能力的对象都包含一个或多个Fill对象去相应的描述相关联的颜色填充。 |
Border |
包括边框特性的功能类。每一个含有边框描述能力的对象都包含一个或多个Border对象去相应的描述相关联的边框线形和颜色。 |
Location |
一个通用的类,此类处理图像对象在图形中的位置。 |
PointPair |
一个封装了一对double型数据的数据结构,其表征了一个(x,y)的数据点,这是在每个CurveItem中值数组的内部的存储格式。 |
PointPairList |
一个集合类维护了一个PointPair对象的数据链表。 |
XDate |
此类封装了单独的数据时间值(Double) |
通过访问上面的每一个类的属性来修改图像。例如,如果你包括下面的代码在你的CreateGraph()方法中, 放在前述的代码示例之后,输出图像将会相应的改变。
// 改变标题的颜色
myPane.Title.FontSpec.FontColor = Color.Green;
//对图像添加灰色网格
myPane.XAxis.MajorGrid.IsVisible = true;
myPane.YAxis.MajorGrid.IsVisible = true;
myPane.XAxis.MajorGrid.Color = Color.LightGray;
myPane.YAxis.MajorGrid.Color = Color.LightGray;
//改变图例的位置
myPane.Legend.Position = ZedGraph.LegendPos.Bottom;
//使两个曲线线性变细
myCurve.Line.Width = 2.0F;
myCurve2.Line.Width = 2.0F;
//在曲线下填充区域
myCurve.Line.Fill = new Fill(Color.White, Color.Red, 45F);
myCurve2.Line.Fill = new Fill(Color.White, Color.Blue, 45F);
//增加符号的大小然后填充其为白色
myCurve.Symbol.Size = 8.0F;
myCurve2.Symbol.Size = 8.0F;
myCurve.Symbol.Fill = new Fill(Color.White);
myCurve2.Symbol.Fill = new Fill(Color.White);
//对坐标轴框架添加背景倾斜填充(其实就是坐标轴的背景图)
// Add a background gradient fill to the axis frame
myPane.Chart.Fill = new Fill(Color.White,
Color.FromArgb(255, 255, 210), -45F);
// 添加说明文字和箭头
TextObj myText = new TextObj("Interesting\nPoint", 230F,
70F);
myText.FontSpec.FontColor = Color.Red;
myText.Location.AlignH = AlignH.Center;
myText.Location.AlignV = AlignV.Top;
myPane.GraphObjList.Add(myText);
ArrowObj myArrow = new ArrowObj(Color.Red, 12F, 230F, 70F, 280F,
55F);
myPane.GraphObjList.Add(myArrow);
最终的效果如下所示:
标签:
杂谈 |
分类: c# |
即是所谓的IEEE754标准,这也是大多数硬件存储浮点数的标准。单精度浮点数占4个字节,表示范围为:在负数的时候是从 -3.402823E38 到 -1.401298E-45,而在正数的时候是从 1.401298E-45 到 3.402823E38 。
在C#中的转换函数为:
1,由四个字节的十六机制数组转浮点数:
byte[] bytes = new byte[4];
BitConverter.ToSingle(bytes, 0);
2,由浮点数转数组:
byte[] bytes = BitConverter.GetBytes(floatValue);
这种转换方法经常用于串口通讯中,表示范围足够各种传感器数值传输及工控场合,将要发送的浮点数据转换为4个字节的十六机制数,然后由串口发出,在接收端再将其转换为浮点数。
单片机或非.net环境下使用转换程序则不能调用BitConverter类!
提供以下代码以供转换:
未修改过的如下:可以在C#中直接调用而不用库函数
public static float ToFloat(byte[] data)
{
float a = 0;
byte i;
byte[] x = data;
unsafe
{
void* pf;
fixed (byte* px = x)
{
pf = &a;
for (i = 0; i < data.Length; i++)
{
*((byte*)pf + i) = *(px + i);
}
}
}
return a;
}
public static byte[] ToByte(float data)
{
unsafe
{
byte* pdata = (byte*)&data;
byte[] byteArray = new byte[sizeof(float)];
for (int i = 0; i < sizeof(float); ++i)
byteArray[i] = *pdata++;
return byteArray;
}
}
如果对工程进行直接编译会报出一下错误:这是因为C#默认不提供指针支持,只有在不安全代码的形式下才可以用指针。
错误 1 不安全代码只会在使用 /unsafe 编译的情况下出现 E:\Visual Studio 2008\Projects\TEST\testOfFloatConsolt\testOfFloatConsolt\Program.cs 26 13 testOfFloatConsolt |
单片机串口通讯浮点转换函数
我在AVR串口通信协议中用到了这部分,直接将单片机的运算结果(浮点类型)转换为(字节类型)嵌入串口通信协议中,上传至上位机。
下面为符合IEEE754标准将浮点数转换为四个字节的数组的函数源代码:已经用于mega16单片机的串口通信中。
WinAVR-20090313测试通过:
下面为符合IEEE754标准的由四个字节型数组转化为相应的浮点数
WinAVR-20090313测试通过:
调用测试方法:其中USART_Transmit();为向串口发送的函数。
在上位机用串口进行读取时调用
BitConverter.ToSingle(bytes, 0);
就会转换成12.15,测试方法可以随着需求改变。
分类: Matlab |
一,matlab中生成随机数主要有三个函数:rand, randn,randi
1,rand 生成均匀分布的伪随机数。分布在(0~1)之间
主要语法:rand(m,n)生成m行n列的均匀分布的伪随机数
rand(m,n,'double')生成指定精度的均匀分布的伪随机数,参数还可以是'single'
rand(RandStream,m,n)利用指定的RandStream(我理解为随机种子)生成伪随机数
2,randn 生成标准正态分布的伪随机数(均值为0,方差为1)
主要语法:和上面一样
3, randi 生成均匀分布的伪随机整数
主要语法:randi(iMax)在开区间(0,iMax)生成均匀分布的伪随机整数
randi(iMax,m,n)在开区间(0,iMax)生成mXn型随机矩阵
r = randi([iMin,iMax],m,n)在开区间(iMin,iMax)生成mXn型随机矩阵
示例验证:
均值分布
概率分布图:
y=rand(1,3000000);
hist(y,2000);
散点图:
y=rand(1,3000000);
plot(y)
正态分布
概率分布图:
y=randn(1,3000000);
hist(y,2000);
散点图:
y=randn(1,3000000);
plot(y);
二,关于随机种子,伪随机数的重复生成
正常情况下每次调用相同指令例如rand生成的伪随机数是不同的,
例如:
rand(1,3)
rand(1,3)
matlab的输出为:
ans =
0.139043482536049
0.734007633362635
0.194791464843949
ans =
0.602204766324215
0.937923745019422
0.149285414707192
如何使两个语句生成的随机数相等呢?
Matlab帮助中的下面章节有所叙述:
管理默认(缺省)流
rand, randn, and randi draw random numbers from an underlying random number stream, called the default stream. The @RandStream class allows you to get a handle to the default stream and control random number generation.
rand,randn,和randi 从一个基础的随机数流中得到随机数,叫做默认流。你可以通过 @RandStream 类得到默认流的句柄从而控制随机数的生成。
Get a handle to the default stream as follows:
以下为得到默认流句柄的代码:
defaultStream=RandStream.getDefaultStream defaultStream = mt19937ar random stream (current default) Seed: 0 RandnAlg: Ziggurat
Return the properties of the stream object with the get method:
用get方法返回流对象属性:
get(defaultStream) Type: 'mt19937ar' NumStreams: 1 StreamIndex: 1 Substream: 1 Seed: 0 State: [625x1 uint32] RandnAlg: 'Ziggurat' Antithetic: 0 FullPrecision: 1
The State property is the internal state of the generator. You can save the State of defaultStream.
state属性是发生器的内部状态,你可以保存默认流的状态:
myState=defaultStream.State;
Using myState, you can restore the state of defaultStream and reproduce previous results.
利用myState你可以恢复默认流状态重新生成前面的结果:
myState=defaultStream.State; A=rand(1,100); defaultStream.State=myState; B=rand(1,100); isequal(A,B) ans = 1
你也可以直接使用@RandStream 类的reset静态方法重置种子状态来获取相同的随机生成序列,下面是示例代码:
stream =
RandStream.getDefaultStream;%获取默认的随机种子(暂时这么叫,帮助有详细解释)
reset(stream);%重置
rand(stream,1,3)
reset(stream);%重置
rand(stream,1,3)
matlab的输出为:
ans =
0.814723686393179
0.905791937075619
0.126986816293506
ans =
0.814723686393179
0.905791937075619
0.126986816293506
可以看出生成的随机码是相等的,这样可以用于重复实验上来
标签:
杂谈 |
分类: c# |
C# 中List类的Find,Exists,FindAll,FindIndex ,FindLast ,FindLastIndex等方法的应用举例
以Exists为例,MSDN中是这样叙述的
ms-help://MS.MSDNQTR.v90.chs/fxref_mscorlib/icons/pubmethod.gif ms-help://MS.MSDNQTR.v90.chs/fxref_mscorlib/icons/xna.gif | Exists |
确定 List<(Of <(T>)>) 是否包含与指定谓词所定义的条件相匹配的元素。 |
我一直都认为编写MSDN文档的人语文是好的令人发指啊!
相信很多人都深有体会,这里每个字都认识,放一起完全不知所云,看了好多例子才知道是怎么回事,不知道是我肤浅,还是技术总是要深奥。
总结一下,写了一个通俗点的例子,希望能对看到的人有用。
20090928更新
关于List(T).Sort方法,MSDN是这样叙述的。
List.Sort应用例程:实现比较泛型委托