
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; |