oculus quest 2 使用体会

最近受网上一段视频的影响,入手了一个oculus quest2,这也是我的第一个VR设备。经过最近3个周的使用,越来越发现这个产品的体验真的很不错。
购买:我买的是quest2,亚马逊直邮的价格大约为2200人民币,后来又在TB,JD,PDD看了一下,价格也都差不多。有的还包激活+安装软件,但是需要开封。 最后我是在咸鱼上下单的,全新未拆封,包装盒也是美国亚马逊当时的箱子。

激活:激活需要facebook账号,同时需要无限制的互联网访问(TB上一些商家的套餐里会带特定路由器)。虽然我使用的网络本身并无限制,但是开机联网的时候还是提示连接限制。最后我通过手机配对,在手机上连接就可以了。

使用:由于是我的第一个vr设备,使用时候感觉效果非常好,真的是身临其境。尤其是看一些vr航拍视频,真的就感觉自己在飞机上飞行一样。
在看一些非VR视频时,可以通过手柄按钮调节虚拟屏幕大小。调到最大的时候效果相当于坐在影院前几排看电影的感觉。调到最小也相当于在家里看100寸电视的效果。同时,手柄的操作也是非常简单,而且定位非常准确,稳定。不会出现光标漂移。手柄使用的是5号电池,用了这么多天电量仍然是100%,看来低功耗是做的很好。
系统也支持手势操作,我也实验了一下,体验虽然不如手柄,但是正常使用也没有问题。手势操作时,会在画面中实时绘制你的手势,然后出现提示。
在激活开发者模式之后,也可以安装通用的android程序,比如爱奇艺之类的视频app。
另外,quest2还可以通过airlink或者有线方式连接电脑,玩steam vr游戏。我只试了FS2020,效果真是太逼真了。如果不是vr,我可能一辈子也体会不到坐在飞机的驾驶舱内,点击一个个真实的按钮操作飞机起飞的体验。感觉自己就是在操纵一架真实的飞机。

头盔耗电方面,每次充满电大约能使用5个小时左右,也算比较正常。

 

缺点:
作为一个vr头盔,缺点也有一些
1、带起来前重后轻,容易下坠。
2、戴眼镜看不太舒服。虽然自带眼睛托架,但还是有点难受。
3、需要特殊网络。

 

[Linux]最近遇到的奇怪的不同平台编译相同代码生产的elf运行不一致问题

在不同的平台上(virtualbox/vmware/windowssubsystem),编译出的elf运行不一致,有的平台运行之后一直高频率进input dma中断。

查看主要的库版本,libc libm等版本一致,操作系统为ubuntu,大版本一致,小版本有差别。从现象上看怀疑工具链在不同平台运行有问题。

后来平台编译信息对比,发现最后的链接顺序不一样。正常的平台按照异常的平台的链接顺序编译的话,也是无法运行。

由于问题跟中断有关,无法用gdb进行单步跟踪,只好用其他方法。

中断分析:
正常状态下,input dma中断为10ms一次(100hz),发现出问题时dma的中断频率为(730hz)。之后发现另外的一个现象,修改某个函数的代码,之前正常的平台编译出来的elf运行也是730hz。 两个不同的行为出现了相同的现象。

于是,要来了DMA与dma搬运数据的codec模块寄存器表,发现dma一切正常,但是codec异常,寄存器全部为默认值。此时开始怀疑模块没有初始化。后来跟踪代码发现,codec模块初始化是由一个判断控制。这个判断用于一个power模块,而这个模块又没有使用。此时这个判断会从0地址去获取数据用于判断。

由于不同的链接顺序下,0地址的代码并不一致,从而导致的不同平台的不同表现。至于修改某个函数的代码也会出现,恰恰是这个函数被链接到了0地址,从而也引发了相应的现象。

现在回头想的话,在修改代码也出现问题的时候,应该去怀疑对应的地址的变化会导致出问题。当然最终定位还是需要看寄存器的相关信息。

 

[linux]select实现非阻塞异步输入

最近要实现一个非阻塞输入的C代码,查到可以通过select函数来完成。
select用于同时监控多个fd,在io可读/写时返回。
正常来说,select是阻塞的,除非超时或者等待的fd内容发生变化。因此,我我们将select的超时时间设为0,便可以非阻塞。按照返回来判断当前监视的fd内容是否变化,从而根据这个返回进行相应的操作。
以下为根据select man page修改的非阻塞输入的代码。
int main(void)
{
fd_set rfds;//fd集合
struct timeval tv;
int retval;
/* Watch stdin (fd 0) to see when it has input. */
/* Wait up to five seconds. */
char c;
char buf[100];
while(1)
{
//select返回后会把以前加入的但并无事件发生的fd清空,则每次开始select前都要重新从array取得fd逐一加入
FD_ZERO(&rfds);
FD_SET(0, &rfds); //监控fd为0,也就是stdin
//FD_ISSET(int fd, fd_set *set);//若存在多个fd,可以用此接口逐个判断
tv.tv_sec = 0; //时间设0,无论fd有没有数据均继续运行
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv); //1 here means (fd=0)+1,see man page
/* Don’t rely on the value of tv now! */
if (retval == -1)
perror(“select()”);
else if (retval)//select检测到有数据之后,通过read读fd=0的数据
{
int ret = 0;
ret = read(0, buf, 100);
if(ret > 0)
{
int i = 0;
for(i = 0;i < ret; i++)
printf(“%c”, buf[i]);
}
//printf(“Data is available now.\n”);
}
/* FD_ISSET(0, &rfds) will be true. */
else//此处为非阻塞正常运行的程序
{
//printf(“No data\n”);
}
retval = 0;
}
exit(EXIT_SUCCESS);
}

[心情]premium是最值得买的视频会员

一般来说,y超过15s的广告都可以在5s之后跳过,因此单次广告时长最多15s。但是由于有的上传用户为了盈利,在视频中间自行增加多次广告,会很大的影响观看体验。

买了会员才发现,这是我买的最值的一个会员了,这个会员不会让你得到更清晰的视频和更快的加载速度,因为这些对任何用户都没有限制。

主要优势在于:

1、无广告。不仅视频中间无广告,视频开始,app页面,网页版播放页面全部一点广告也没有。不会跟某些国内视频厂商有所谓的会员专属广告和跳过广告。

2、视频下载。可以以最高1080p的分辨率将视频到本地。当然,这个在andriod下可以使用各种y downloader进行下载。

3、音乐会员,同样是无广告,可以下载。很简单的使用界面。缺点是中文歌曲不是很完整。

当然劣势就是价格,如果自行购买一年大概6,700人民币。不过,可以在tb上购买拼车的家庭会员,一年8,90块钱就可以。另外如果自己购买可以使用印度代理购买印度区会员,价格也能稍微便宜,一年大概50人民币。

[python] flask + ngnix

文本记录了当使用python+flask的应用时,如何配合ngnix实现通过80端口访问,从而也就可以使用域名直接访问python app。

https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-ubuntu-16-04

评论中有502错误解决方法。

如果有多个app,virtualenv可以共用,只要在service的路径里面写上实际路径即可

virtualenv webprojectenv

source webprojectenv/bin/activate

502

For those that have the 502 gateway error try changing chmod-socket = 660

uwsgi_pass unix:///home/sammy/myproject/myproject.sock;

[python] flask jinja HTML模板语法记录

Flask使用的是jinja模板,记录一下常用的语法

判断传入的dict/list是否为空
{% if input%}
定义一个变量值
{%set a = 0%}
获取输入list length
{%set a = (phr)|length%}
list循环
{% for row in input%}
{{row}}
{% endfor %}
dict打印
{% for k,v in input.items() %}
{{k}}
{{v}}
{% endfor %}
或者
{% {{input[‘key’]}}%}

if判断
{% if (a)>=16 %}
{% elif (a)<0 %}
{% else%}
{% endif%}
for循环
{% for a in range(0,10,2)%}
{% endfor %}
字符串拼接
{%set url = “https://sunjw.cn/html5/flight/swift/domestic/” ~ “AAA” ~ row[0] %}

循环里自加计数
{% set count = namespace(value=0) %}
{% for i in p %}
{{ count.value }}
{% set count.value = count.value + 1 %}
{% endfor %}

[python]使用苹果自带的快捷方式实现常用青岛公交查询

青岛工具查询的方式有多种,我经常使用的是微信小程序中的“青岛工具查询”。因为每天早晨上班都要查公交到哪一站便于出门,但是这种查询方式有点麻烦,于是就有了此方法。

我使用了青岛新闻网的公交查询接口,http://bus.qingdaonews.com/m/

http://bus.qingdaonews.com/m/detail.php?rid=128&isjson=1   用于查询128路所有站点名称及站名id及segment id,站名id与segment id用于后面具体的车辆位置查询。

http://bus.qingdaonews.com/m/detail_ajax.php?rid=128&smid=8525754&id=27
用于查询具体的最近的两辆公交信息,如果直接输入浏览器效果如下

理论上来说,将上述地址写到苹果的快捷方式里面的web-Get contents of URL就可以拿到信息了,但是这样可读性太差,于是我在我的vps上把返回数据格式变了一下,然后,跟默认只查询2辆车不同,我查询了两次,从而实现了最近的4辆车的信息的返回。

最后可以使用快捷方式里面的获取字典或者列表的方式将数据拿到通过弹出对话框显示。
最终结果如下:

[Python] seek使用 bytes转int 浮点特定位数

最近用python写了个计算pcm平均RMS幅度(dBfs)的脚本,其中不少小细节在此列一下

1、python没有跟C一样拿到参数个数的argc,需要使用len(sys.argv)拿到
2、seek第一个参数为offset,第二个为偏移位置 0-file start, 1-current,2-file end
3、python一个除“/”结果为浮点,即使可以整除,“//”为取整
4、‘rb’读文件拿到的数据为bytes类型,如果要转成int需要int.from_bytes方法,可以设置大小端跟有无符合。
5、浮点特定位数打印 print(“%.2f”% num);

if len(sys.argv) != 2: #there is no ARGC
print(“param must be 2”)
exit(0)

with open(sys.argv[1], ‘rb’) as fd:
    cnt = fd.seek(0,2)#2-seek to the end
    cnt = cnt//2 #use // here, other wise cnt is a float
fd.seek(0,0) #0-seek to start
for i in range(cnt):
num = fd.read(2)
        num=int.from_bytes(num, byteorder=”little”, signed=”True”)# byte to int
total += (num*num)
dbfs=20*math.log10(math.sqrt(total/cnt)/32768)+3.013
print(“%.2f”% dbfs); #to keep 2 decimal points

胶东地区过年风俗

前几天看到山东过年磕头上了热搜,闲来没事就想大概写一下胶东地区的国内风俗。
年前几天要准备蒸馒头,就是胶东部分的大馒头,有不同的花样代表着不同的寓意。
同时也要准备一些过年的食物。

上图为前几年过年馒头

一般来说,除夕前一天要贴春联贴福字,还要挂家谱,摆上各种贡品。其中馒头是必须的,也有点心,水果等,当然除夕晚上还要摆上饺子。多年之前的贡品必须要包含一直整鸡,摆好造型放在桌子上。后来估计很多人嫌麻烦就简化了。

除夕中午是最丰盛的一顿,各家各户都会做各种有好的寓意的菜肴,包括鱼,豆腐,芹菜,海鲜等。

除夕下午女人开始包饺子,一大家子的男人会去上坟,寓意将祖先请回家过年。小时候上坟的时候还要大声喊,好让祖先听见。

晚饭主要是饺子,当然也会把中午的菜全部摆到餐桌上,也是表示富有的含义。饺子里会包上小东西,比如硬币,枣,花生,栗子,糖等,也是代表各种好的寓意。我小时候晚饭基本要等到晚上12点,后来越来越早。前几年都是看着春节晚会的开幕煮饺子,这两天开始越来越多的人改到正常晚饭点了。

饺子煮好之后要摆一些做贡品,然后放鞭炮,寓意请财神(我也不知道为啥)。都准备完了才能开始吃。

按照我们的风俗,晚饭之后,第一次见到熟人就要说‘过年好’了。晚饭之后小辈男人们要去大家子的每一户拜年,然后,给长辈磕头。跟网上不一样的是,我们不会对着人,而是每家的家谱。磕完头小朋友们就可以要压岁钱了。

小时候感觉还挺热闹,大了之后越来越觉得麻烦了。一大家子的亲属有的基本都不熟悉,去拜年会感觉很尴尬。随便寒暄几句就磕头出来了。

按照风俗,女人们初一才能出去拜年。也是一家子女人们集合,开始每家拜年,当然女人不需要磕头。把自己的大家子转完之后,一般会到邻居或者比较近的朋友家里拜年坐一会。

初二成为送年,意思是年过完了。那天也是需要包饺子,跟除夕不同的是,这次是中午吃,也是需要上贡,同时把除夕的饺子替换下来。到晚上就可以放鞭炮送年了。

[C]Debug命令

生成map文件(列出所有变量,函数所属的段及地址)
gcc 1.c -Wl, -Map=out.map

objdump -d 也可以

gdb可以通过调试打印相应的变量/函数
make VERBOSE=1

make all VERBOSE=1可以打印详细编译信息,

size可以用来查看elf/.a/.so text/data/bss大小, 注意rodata会被计算在text中

readelf -t / -S查看section size,地址等情况