Leap Motion体感控制器手势判别

using Leap;
   Controller controller = new Controller();
   MyListen mylisten = new MyListen();
    Thread Updatedata;
      private void but_connect_leap_Click(object sender, EventArgs e)
        {
            mylisten.OnServiceConnect(controller);
            if(controller.IsConnected)
            {
                MessageBox.Show("Leap连接成功,刷新手参数线程开启");
                Updatedata = new Thread(update);
                Updatedata.IsBackground = true;
                Update_Robot_T.Enabled = true;
                Updatedata.Start();
            }
            else
            {
                MessageBox.Show("Leap连接失败");
            }
      }
        private void update()
        {
            while (controller.IsConnected)
            {
                Thread.Sleep(1);
                mylisten.OnFrame(controller);
                if (mylisten.HandList != null)
                {
                    if (mylisten.HandList.Count == 0) 
                    {
                        lastx = 0;
                        lasty = 0;
                        lastz = 0;
                        continue;
                    } 
                    Hand handRight = new Hand();
                    Hand handLeft = new Hand();
                    handRight =     mylisten.HandList.Rightmost;
                    handLeft = mylisten.HandList.Leftmost;
                    Thread MoveThread = new Thread(() =>
                      {
                          if (handRight != null && handRight.IsRight && !handRight.IsLeft)
                          {
                            //if (robot.angle2 < 0)
                            //{
                            //    robot.change_attitude(200);
                            //}
                          
                              if (count == 0)
                              {
                                  lastx = handRight.PalmPosition.x;
                                  lasty = handRight.PalmPosition.y;
                                  lastz = handRight.PalmPosition.z;
                                // if (lastx < 50 && lastx>-50 && lastz>-50 && lastz < 50 && lasty>-50 && lasty<50 &&handRight.PalmVelocity.y<10 && handRight.PalmVelocity.x<10 && handRight.PalmVelocity.z<10)
                                if (handRight.GrabStrength < 0.8f)
                                  {
                                      count = 1;
                                  }
                                  else
                                      count = 0;

                              }
                              else if (count == 1)
                              {
                                  float nowx = handRight.PalmPosition.x;
                                  float nowy = handRight.PalmPosition.y;
                                  float nowz = handRight.PalmPosition.z;
                                  Leap_x = nowx - lastx;
                                  Leap_y = nowy - lasty;
                                  Leap_z = nowz - lastz;
                                  lastx = nowx;
                                  lasty = nowy;
                                  lastz = nowz;
                              }
                              speed1 = handRight.PalmVelocity.x;
                              speed2 = handRight.PalmVelocity.y;
                              speed3 = handRight.PalmVelocity.z;
                              speed = (speed1 + speed2 + speed3) / 3;
                            //  if (speed > 800 && speed < 1) continue;
                            Thread robotThread = new Thread();
                                        //robotThread.Start();
                             
                                
                          else
                          if (handLeft != null && !handRight.IsRight && handRight.IsLeft)
                          {
                          }
                            public bool isGrabHand(Hand hand)
        {
            return hand.GrabStrength > 0.8f&&isStationary(hand); 
        }
        public bool isMoveRight(Hand hand)
        {
            return hand.PalmVelocity.z > 50 && !isStationary(hand);
        }
        public bool isMoveLeft(Hand hand)
        {
            return hand.PalmVelocity.z <- 50 && !isStationary(hand);
        }
        public bool isMoveUp(Hand hand)
        {
            return hand.PalmVelocity.y > 50 && !isStationary(hand);
        }
        public bool isMoveDown(Hand hand)
        {
            return hand.PalmVelocity.y <- 50 && !isStationary(hand);
        }
        public bool isMoveForward(Hand hand)
        {
            return hand.PalmVelocity.x > 50 && !isStationary(hand);
        }
        public bool isMoveBack(Hand hand)
        {
            return hand.PalmVelocity.x <- 50 && !isStationary(hand);
        }
        //固定不动的
        public bool isStationary(Hand hand)
        {
            return hand.PalmVelocity.Magnitude < 10;      //Vector3.Magnitude返回向量的长度
        }

==
//leapx–x;
//leapy–z;
//leapz–y;
==

## 基础语法

结构体和类的区别 :类是按引用传递 结构体是按值传递.
Sequential,顺序布局,比如
struct S1
{
int a;
int b;
}
那么默认情况下在内存里是先排a,再排b
也就是如果能取到a的地址,和b的地址,则相差一个int类型的长度,4字节
[StructLayout(LayoutKind.Sequential)]
struct S1
{
int a;
int b;
}
这样和上一个是一样的.因为默认的内存排列就是Sequential,也就是按成员的先后顺序排列.
2.Explicit,精确布局
需要用FieldOffset()设置每个成员的位置
这样就可以实现类似c的公用体的功能
[StructLayout(LayoutKind.Explicit)]
struct S1
{
[FieldOffset(0)]
int a;
[FieldOffset(0)]
int b;
}
这样a和b在内存中地址相同

2.[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
//这是C#引用非托管的C/C++的DLL的一种定义定义结构体的方式
structlayout支持三种附加字段:charset,pack,size,
1)charset是结构中的字符串成员在结构被传给DLL时的排列方式,可以是Unicode,ansi或Auto,默认为Auto.
2)pack定义了结构的封装大小:1,2,4,8,16,32,64,128或特殊值0(表示当前操作平台默认的压缩大小).

默认(LayoutKind.Sequential)情况下,CLR对struct的Layout的处理方法与C/C++中默认的处理方式相同,即按照结构中占用空间最大的成员进行对齐(Align);
使用LayoutKind.Explicit的情况下,CLR不对结构体进行任何内存对齐(Align),而且我们要小心就是FieldOffset;
使用LayoutKind.Auto的情况下,CLR会对结构体中的字段顺序进行调整,使实例占有尽可能少的内存,并进行4byte的内存对齐(Align)。

3.Inptr(指针)
用于:
1)Csharp调用win32API时;
2)Csharp调用C/C++写的DLL时;
用法:
[DllImport(“LeapC”, EntryPoint = “LeapCreateClockRebaser”)]
public static extern eLeapRS CreateClockRebaser(out IntPtr phClockRebaser);
3)字符串转Intptr:
Marshal.StringTocoTaskMemAuto(txt);
4. [MarshalAs(UnmanagedType.FunctionPtr)]
public Allocate allocate;
1)UnmanagedType;指定如何将参数或字段封送到非托管代码.
2)托管代码指必须依靠.net框架解释运行的代码.

托管的代码就是把有关内存管理(内存申请,内存释放,垃圾回收之类的)全部都是.net的CLR来管理,就是说使用托管的代码把底层的一些操作都封装起来了,不能直接进行内存的读取之类的和硬件相关的操作,优点就是比较安全,不会出现诸如内存泄露之类的问题,缺点也很明显,不能直接读取内存,性能上会有损失,使用起来有时也不够灵活。
非托管的刚好相反,可以直接进行硬件操作,性能比较高,但是对开发人员的要求也比较高。
最直观的就是c#不推荐使用指针,而c++就可以使用指针来直接读取内存;
c#使用垃圾回收,c++要手动的释放对象……
托管代码:
”托管“的含义就是,这些语言的后台(隐性的)操作都由这个管理系统(.Net)完成了,你把你的编程委托给了开发平台(库)来完成。当你使用这些语言时,一些系统资源的调用、回收、编译……各种工作都由它来完成,你只需要专注于程序功能的实现即可。
非托管代码:
就是指不在你这个集成开发环境里,而是使用其它的开发平台写出的程序(代码)。比如说java语言(不是jscript),basic语言(不是VB),C语言(不是VC/C++/C#)等等……它们也有自己的开发平台和程序,用这些语言写出的程序就属于”非托管“。
当非托管的代码在你的托管平台上运行时,你的托管平台就不能很好地处理一些后台(隐性的)操作,就需要编写额外的代码来使它们变得和谐并且安全。

5.lock关键字可以用来确保代码块完成运行,而不会被其他线程中断。
方法:
lock(expression)statement_block
expression:希望跟踪的对象,通常是对象引用;
statement_block:互斥段的代码;

如果你想保护一个类的实例,一般地,你可以使用this;如果你想保护一个静态变量(如互斥代码段在一个静态方法内部),一般使用类名就可以了。
而statement_block就是互斥段的代码,这段代码在一个时刻内只可能被一个线程执行。

lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值