Summary for my 4 months

本文详细介绍了使用DTW和SPRING分类算法实现的手势识别智能灯控项目。内容包括串口通讯数据收集、磁力数据矫正、Hue灯桥接控制、PWM信号生成以及3D打印外壳设计等多个方面。

1. 完成了一个小的project

    利用DTW和SPRING分类算法,识别用户手势,控制智能灯。

    我的职责: 

    1.1 负责数据收集(serial port communication)及磁力数据矫正

      a. 用C语言和Java写的读写串口,参见 

http://blog.youkuaiyun.com/u011680118/article/details/49208771

      http://blog.youkuaiyun.com/u011680118/article/details/49750099

      b. 利用矩阵计算库来做磁力矫正

Java使用的库尝试过la4j, colt 最后决定改成C语言,于是使用了GSL。 

        http://blog.youkuaiyun.com/u011680118/article/details/49208839


    1.2 负责灯的控制(hue lamp api, win socket, http)

        a. 需要发现hue lamp bridge,这个通过发送SSDP协议中的特定HTTP请求到多播地址,收到回复后可以找到bridge的IP地址。

http://blog.youkuaiyun.com/u011680118/article/details/49121005

http://blog.youkuaiyun.com/u011680118/article/details/49434639

        b. 通过Socket给birdge发送username获得UID,利用这个UID去进行hue lamps的控制。

        参考: 

http://blog.youkuaiyun.com/u011680118/article/details/49133743

http://blog.youkuaiyun.com/u011680118/article/details/49434855

        c. 控制灯就是按照API文档,构建包含Json字符串的HTTP请求。


    1.3 负责vibrator子系统(read datasheets online, modify programs in Contiki, flash and see PWM output by Digital Logic, use SolidWorks to design 3D box and print them)

a. 生成PWM信号

        

//TODO: Added by Amy, 11/12/2015
#define	GPT_CONF_BASE 		GPT_0_BASE
#define IOC_CONF_SEL 		IOC_PXX_SEL_GPT0_ICP1  // act as GPTimer0 ICP1
#define PWM_GPIO_CONF_PORT 	GPIO_A_NUM
#define PWM_GPIO_CONF_PIN 	1

void enable_gptimer(){
	/* Enable */
	REG(GPT_CONF_BASE + GPTIMER_CTL) |= GPTIMER_CTL_TAEN;
}

void disable_gptimer(){
	/* Stop the timer */
	REG(GPT_CONF_BASE + GPTIMER_CTL) = 0;
}

#define GPTIMER_ON 1
#define GPTIMER_OFF 0
int get_gptimer_state(){
	if(REG(GPT_CONF_BASE + GPTIMER_CTL) == 0)
		return GPTIMER_OFF;
	else
		return GPTIMER_ON;
}


//Config PA1 as an PWM output pin
/*
periodCount: 16000 ---> 1kHz   
dutyCycle: 0.25   0.5  0.75
*/
void initPWM(int periodCount, double dutyCycle) {
	//16Mhz 
	//printf("init PWM start\n");
	/* Enable module clock for the GPTx in Active mode, GPT0 clock enable, CPU running */
	REG(SYS_CTRL_RCGCGPT) |= SYS_CTRL_RCGCGPT_GPT0;

	disable_gptimer();

	/* Use 16-bit timer */
	REG(GPT_CONF_BASE + GPTIMER_CFG) = 0x04;

	/* Configure PWM mode, 0x00000008 Timer A alternate mode. */
	REG(GPT_CONF_BASE + GPTIMER_TAMR) = 0;
	REG(GPT_CONF_BASE + GPTIMER_TAMR) |= GPTIMER_TAMR_TAAMS;

	/* To enable PWM mode, the TACM bit must be cleared and the lowest 2 bits 
	   (TAMR) field must be configured to 0x2.
	   GPTIMER_TnMR bit values, GPTIMER_TAMR_TAMR_PERIODIC is 0x00000002 */
	REG(GPT_CONF_BASE + GPTIMER_TAMR) |= GPTIMER_TAMR_TAMR_PERIODIC;

	//how often the counter is incremented:  every  pre-scaler / clock 16000000 seconds
	REG(GPT_CONF_BASE + GPTIMER_TAPR) = 0; 	//PRESCALER_VALUE  

	/* Set the start value (period), count down */
	REG(GPT_CONF_BASE+ GPTIMER_TAILR) = periodCount;//0xF42400; 	//16000: 3E80, so period is 1s.  16000000:F42400

	/* Set the deassert period */
	REG(GPT_CONF_BASE + GPTIMER_TAMATCHR) = periodCount * (1 - dutyCycle);//0x7A1200; //800: 0x1F40, so the duty rate is 50%, 8000000: 7A1200

	// Defined in contiki/cpu/cc2538/dev/ioc.h
	/* Function select for Port:Pin.
	   The third param sel can be any of the IOC_PXX_SEL_xyz defines. 
	   For example, IOC_PXX_SEL_UART0_TXD will set the port to act as UART0 TX.

     	   Selects one of the 32 pins on the four 8-pin I/O-ports (port A, port B, port C, and port D) to be the GPT0OCP1.
           Configure pin : PA:1 selected as GPT0OCP1*/
	ioc_set_sel(PWM_GPIO_CONF_PORT, PWM_GPIO_CONF_PIN, IOC_CONF_SEL);

	/* Set Port:Pin override function, IOC_OVERRIDE_OE: Output */
	ioc_set_over(PWM_GPIO_CONF_PORT, PWM_GPIO_CONF_PIN, IOC_OVERRIDE_OE);

	/* Configure the pin to be under peripheral control with PIN_MASK of port with PORT_BASE.*/
	GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(PWM_GPIO_CONF_PORT), GPIO_PIN_MASK(PWM_GPIO_CONF_PIN));
	
	enable_gptimer();

	//printf("init PWM end\n");
}

       b. 使用3D printer

       用SolidWorks直接看它的教程即可,然后先制作parts,做好每个部分之后可以用assembly来仿真看看效果。再将parts保存为stl文件,把stl文件交给工作人员即可打印。


    1.4 中间穿插着改了数据传输频率(bluetooth, baudRate)


修改baudRate

/*
 * Baud rate defines used in uart_init() to set the values of UART_IBRD and
 * UART_FBRD in order to achieve the configured baud rates.
 */
#define UART_CLOCK_RATE       16000000 /* 16 MHz */
#define UART_CTL_HSE_VALUE    0
#define UART_CTL_VALUE        (UART_CTL_RXE | UART_CTL_TXE | (UART_CTL_HSE_VALUE << 5))

/* DIV_ROUND() divides integers while avoiding a rounding error: */
#define DIV_ROUND(num, denom) (((num) + (denom) / 2) / (denom))

#define BAUD2BRD(baud)        DIV_ROUND(UART_CLOCK_RATE << (UART_CTL_HSE_VALUE + 2), (baud))
#define BAUD2IBRD(baud)       (BAUD2BRD(baud) >> 6)
#define BAUD2FBRD(baud)       (BAUD2BRD(baud) & 0x3f)
//*********************************************************************************************************************//
// Change UART baud rate from 9600 to 115200 after we set bluetooth frequency to 115200
void set_uart_baud_rate(unsigned int uart_base) {
	/* Make sure the UART is disabled before trying to configure it */
	REG(uart_base + UART_CTL) = UART_CTL_VALUE;

	/* Baud Rate Generation */
	REG(uart_base + UART_IBRD) = BAUD2IBRD(115200);
	REG(uart_base + UART_FBRD) = BAUD2FBRD(115200);

	/* UART Control: 8N1 with FIFOs */
	REG(uart_base + UART_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN;

	/* UART Enable */
	REG(uart_base + UART_CTL) |= UART_CTL_UARTEN;
}

2. 吃过的美食

      去Amy & Jason 家里吃pizza, 还有鱼香肉丝,海带汤,大酱汤,蔬菜沙拉,煎荷包蛋。

      去Larry & Helen 家里吃的Bible study晚餐,那个起司意面好棒!还有大葱汤,暖暖的好贴心。还有三明治,培根,蔬菜沙拉,pizza。都非常棒!

      去恩谷教会吃的各种中餐,非常棒!花椰菜,水煮鱼,红烧肉,凉拌豆腐,麻辣烫,狮子头等等。。

      去姚弟兄家里吃的红烧肉和台湾卤肉面,还有海鲜汤,冬瓜汤,荠菜饺子,简直好吃爆!!

      和Wendy, Amanda一起去的Cafe Exel,三个人才点了一盘appetizer,然后吃了好多面包,还有一分甜点。

      和Wendy, Chelsea一起去的RoadHouse,吃正宗的牛排,就是有点咸,其他面包和烤土豆都非常好吃!

      和Wendy 一起去的 Chick fil-A 等快餐,味道也很棒,跟中国的差不多。

      和金鸽姐,Amy一起去的China King Buffet,撑死了。。味道也还行。

      和Jui一起去的IHOP,最爱那里的鸡蛋饼还有pancakes


在日常的生活中我们最经常使用的距离毫无疑问应该是欧式距离,但是对于一些特殊情况,欧氏距离存在着其很明显的缺陷,比如说时间序列,举个比较简单的例子,序列A:1,1,1,10,2,3,序列B:1,1,1,2,10,3,如果用欧氏距离,也就是distance[i][j]=(b[j]-a[i])*(b[j]-a[i])来计算的话,总的距离和应该是128,应该说这个距离是非常大的,而实际上这个序列的图像是十分相似的,这种情况下就有人开始考虑寻找新的时间序列距离的计算方法,然后提出了DTW算法,这种方法在语音识别,机器学习方便有着很重要的作用。 这个算法是基于动态规划(DP)的思想,解决了发音长短不一的模板匹配问题,简单来说,就是通过构建一个邻接矩阵,寻找最短路径和。 还以上面的2个序列作为例子,A中的10和B中的2对应以及A中的2和B中的10对应的时候,distance[3]以及distance[4]肯定是非常大的,这就直接导致了最后距离和的膨胀,这种时候,我们需要来调整下时间序列,如果我们让A中的10和B中的10 对应 ,A中的1和B中的2对应,那么最后的距离和就将大大缩短,这种方式可以看做是一种时间扭曲,看到这里的时候,我相信应该会有人提出来,为什么不能使用A中的2与B中的2对应的问题,那样的话距离和肯定是0了啊,距离应该是最小的吧,但这种情况是不允许的,因为A中的10是发生在2的前面,而B中的2则发生在10的前面,如果对应方式交叉的话会导致时间上的混乱,不符合因果关系。 接下来,以output[6][6](所有的记录下标从1开始,开始的时候全部置0)记录A,B之间的DTW距离,简单的介绍一下具体的算法,这个算法其实就是一个简单的DP,状态转移公式是output[i] [j]=Min(Min(output[i-1][j],output[i][j-1]),output[i-1][j-1])+distance[i] [j];最后得到的output[5][5]就是我们所需要的DTW距离.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Anyanyamy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值