
Python-Unity Network
Python 和 Unity 间通讯
https://github.com/Siliconifier/Python-Unity-Socket-Communication
https://github.com/Siliconifier/Python-Unity-Socket-Communication
首先 RGB-D 相机识别出桌面上的某一个物体,反馈到 hololens 的界面中,用户会看到对应物体上渲染出来了一个边界框和表示位姿的坐标轴:
随后用户可以通过手部的射线来移动这个目标框(物体上的检测框依然会存在)到某个位置,然后目标框上会显示一个 UI 询问是否要把物体移动到这里,如果点击确认,机械臂就会把对应的物体到目标框的位置。
可以在路径中设置一些障碍,展示机械臂障碍识别的功能。
用户凝视一个物体时显示一个界面,即是否要将操作员注视的物体移动到他的手上,如果手腕翻起,即为确认。随后机械臂会将该物体移动到手上。
仓库:https://github.com/liuyuan-pal/Gen6D
手册:https://github.com/liuyuan-pal/Gen6D/blob/main/custom_object.md
步骤指令:
1 | python prepare.py --action video2image --input data/custom/part1/ref.mp4 --output data/custom/part1/images --frame_inter 10 --image_size 960 |
关于判定不准确怎么解决:https://github.com/liuyuan-pal/Gen6D/issues/29
unity 使用左手坐标系,普遍的 6d 算法使用右手坐标系,所以得出[R;t]后需要做一步针对 y 轴的反射变换
1 | def right_to_left_hand_pose_R(R): |
可以看到效果很好:
State of The Art: Foundation Pose (https://github.com/NVlabs/FoundationPose)
CASAPose (https://github.com/fraunhoferhhi/casapose?tab=readme-ov-file)
MegaPose (https://github.com/megapose6d/megapose6d)
MegaPose (https://github.com/megapose6d/megapose6d)
OVE6D (https://github.com/dingdingcai/OVE6D-pose)
使用 pyRobotiqGripper
但是只兼容 linux 电脑的串口,所以部署在笔记本上并且创建一个局域网服务器供台式机调用。
1 | import pyRobotiqGripper |
1 | (base) cyl@arch ~/450> python gripper_test.py |
台式机通过
1 | # 定义要发送的命令和URL |
来控制
用于将关键点数据转化为关节动作(各关节旋转角度)
希望机械臂的末端始终竖直。方便夹取。
Unity IK: https://github.com/2000222/Robotic-Arm-IK-in-Unity
自定义自由度,非常好用,基于关节梯度迭代的方法
由这个 IK 算法负责机械臂前三个 joint 的旋转,确保 j4 的 anchor(红点)处于物体后上方的特定位置。
j4 位置的计算方法:
1 | public Vector3 GetPositionForJ4(Vector3 pos) |
之后由向量计算得出 j4 应该旋转的角度,以确保末端竖直。
j5 不旋转,j6 的旋转角度由物体朝向决定。
一条路径由若干个关键点构成,在构建路径时只需输入若干 turning point,就会自行生成路径中的关键点。
1 | public class KeyPoint |
IK 只需要获取关键点的坐标信息就可以生成各个关节旋转的数据。
1 | InverseKinematics(GetPositionForJ4(position)); |
Hexo plugin -- hexo-photo-wall
因为觉得hexo post的图片排版太烂了,手打html插入图片又很烦,于是乎决定写一个hexo的插件,能够通过一些关键字,识别图片组,然后再把这些图片以照片墙的方式组合在一起。
顺带可以了解一下hexo的渲染管道和javascript。
初始化阶段:
内容处理阶段:
生成阶段:
部署阶段:
我们需要做的就是在内容处理阶段,重新生成图片墙部分的html代码。
过滤器是通过 hexo.extend.filter.register() 方法来注册的。每个过滤器都绑定在特定的生命周期事件上,当这些事件触发时,Hexo 会依次执行所有注册在该事件上的过滤器。
1 | hexo.extend.filter.register('after_post_render', function(data) { |
after_post_render 过滤器需要返回修改后的文章内容。before_exit)不需要返回值。首先创建一个存放插件的文件夹,我放在hexo_root/plugins/hexo-photo-wall
文件夹中创建一个js入口文件index.js
文件中注册filter并且实现替换功能
1 | hexo.extend.filter.register('before_generate', () => { |
此处的照片墙的排版和原本应该并没有区别,只是处于同一个class="picture-wall"的div下。后续需要通过修改css或者直接更改html来实现照片墙的效果。
For this RC, we will go through Lab 4 in detail.
We need to generate PWM signal on PB14(embeded with an LED D1, or D2 if you like)
In STM32, Input Capture and Output Compare is configured in Timer channels.
Let’s check which Timer is connected to PB14
Then we configure timer 1.
Prescaler: 7200-1 Counter Period: 200-1 (50Hz) Pulse: 180 (duty cycle of 90%; TIM_CNT 0~179: HIGH, TIM_CNT 180~199: LOW) CHN Polarity: LOW (needed for CHN) > CHxN is the complementary channel of CHx in Timer1. > If the polarity of CHxN and CHx are different, the two channels will follow the same output pattern, otherwise they will be complementaryAlso remember to configure PB12 (SW4) as GPIO_Input.
1 | /* USER CODE BEGIN 2 */ |
Change PWM duty cycle:
1 | void ChangeDutyCycle(int pulse_width) |
Get the press/release action of the button (PB12):
1 | int pressed = 0; |