[{"content":"一、实验目的\n使用光流，无人机定位模式 找无人机突然失控的原因 二、实验过程记录\n首先使用姿态模式起飞，无异常情况 换为位置模式起飞，起飞后存在左右小幅度摇摆偏移 降落未断电后重新起飞，无人机失控向左后方偏移然后遥控器急停 未断电重新尝试解锁，不能解锁并报错如下图 断电后可以解锁，位置模式仍然失控\n重新使用姿态起飞，姿态仍然正常\n三、实验结果\n查看日志发现姿态估计结果异常，飞机水平放置时，飞控仍会以为飞机存在水平倾斜，判断是姿态估计出错导致的失控 还发现报错imu stopped aidding，看源码发现在ekf滤波开始前有相关判断，并在下图两处为PV_AidingMode赋值为AID_NONE然后报错，推测报错原因为参数里ek3_src1_yaw没有赋值 继续跳转发现AID_NONE会导致滤波结果重置和yaw方向的融合，推测是这个原因导致的姿态估计错误 然而ek3_src1_yaw这个参数只有none, Compass, GPS, GPS with Compass Fallback, ExternalNav, GSF几种，只能选compass，但是又会报错compass unhealthy，尚未解决 2023.06.24:\n后续发现kakute mini飞控中并没有磁力计, 板载imu只有加速度记和陀螺仪. 外置磁力计后能够跳出该判断条件, 避免估计的状态量和观测值清零. 在大角度旋转无人机, 状态因光流测算异常而估计错误后能够自动返回正确的姿态\n此时仍存在室内定位漂移以及使用光流的激光测高模块会使高度估计失控的情况, 下一步买回来自带陀螺仪补偿的px4flow后再进行实验找到问题\n","date":"2023-06-15T19:30:45+08:00","image":"https://raw.githubusercontent.com/TioeAre/imageHost/main/pictures/103449092_p0_master1200.jpg","permalink":"/daily/2023.06.15/","title":"调试室内定位"},{"content":"Ardupilot补偿光流 问题概述 主要问题: 光流传感器假定无人机为完全水平飞行, 当无人机姿态发生微小倾斜时, 光流认为此时无人机有位移, 进而输出该位移数据, 导致Loiter模式下出现左右浮动\n衍生问题: 1.光流模块并不在无人机旋转中心, 当无人机位姿发生变化时, 光流模块的旋转角速度与imu的角速度不一定相同. 2.光流数据的频率与imu发布频率不一定相同, 中间可能出现时间差影响补偿效果\n融合方案 代码修改 获取光流得到的x轴和y轴速度 获取加速度计得到的pitch和roll轴速度 将加速度计得到的数据转化为光流坐标系下的速度 光流速度减去加速度计速度即可 参考[4], [5]中的代码\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ///参考资料[4] Flow_Decode(\u0026amp;Flow_Buffer[0]);\t// 光流数据解析 TimePeriod(\u0026amp;flow_Delta);\t// 得到这段代码运行时间ms Flow_Delta_T = Flow_Delta.Time_Delta/1000.0f;\t// 得到周期时间 // 得到陀螺仪数据角速度(弧度) gyro_y = imu.gyroRaw[1] * 180.0f / M_PI_F;\t// gyro[1] pitch光流Y轴 gyro_x = imu.gyroRaw[0] * 180.0f / M_PI_F;\t// gyro[0] roll光流X轴 // 陀螺仪滤波 LPF_1_(8.0f, Flow_Delta_T, gyro_y, gyro_lpf_y);\t// gyro low pass filter (delay) for fitting flow data() LPF_1_(8.0f, Flow_Delta_T, gyro_x, gyro_lpf_x);\t// 8.0需要调参, 保证光流数值和陀螺仪数值相位相差不多 // 对光流原始数据进行滤波 LPF_1_(30.0f, Flow_Delta_T, flow_dat.x, flow_dat.x);\t// 对光流数据进行简单滤波 LPF_1_(30.0f, Flow_Delta_T, flow_dat.y, flow_dat.y); // 速度计算方法: (H * flow_dat.x / T) * 100 H为高度, 单位m. T为间隔时间, 单位s, 100是m-\u0026gt;cm的转换 UPflow_speed_x = flow_dat.x / Flow_Delta_T ; // 速度 rad/s UPflow_speed_y = flow_dat.y / Flow_Delta_T ; // 速度 rad/s /* --------------------利用陀螺仪对光流进行补偿，保证在原地旋转时，光流输出几乎为 0 -----------------*/ // 1.105和1.101系数需要调参, 用来抵消低通滤波带来的幅值减小 UPflow_speed_x = US100_Distance * (UPflow_speed_x - 1.105 * LIMIT(((gyro_lpf_x) / 57.295779f), -flow_t2, flow_t2)) * 100.0f;\t// 速度 cm/s UPflow_speed_y = US100_Distance * (UPflow_speed_y + 1.101 * LIMIT(((gyro_lpf_y) / 57.295779f), -flow_t1, flow_t1)) * 100.0f; 其中Flow_Decode(), LPF_1_(), LIMIT()函数由该博主使用的光流模块厂家提供, 用于获取光流速度和滤波等\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 /// 参考资料[5] if (get_flow_quality() != 0) { flow_angle_fix_x = +(120.0f * tan(pitch_delay[3])); flow_angle_fix_y = -(120.0f * tan(roll_delay[3])); } else { flow_angle_fix_x = 0; flow_angle_fix_y = 0; } flow_cal_distance_x = flow_ori_distance_x - flow_angle_fix_x; // cm flow_cal_distance_y = flow_ori_distance_y - flow_angle_fix_y; // cm float flow_speed_x = (flow_cal_distance_x - last_distance_x) / 0.02f; float flow_speed_y = (flow_cal_distance_y - last_distance_y) / 0.02f; last_distance_x = flow_cal_distance_x; last_distance_y = flow_cal_distance_y; 以上两篇中主要思想都是通过光流的模块的相关函数获取到光流的数据, 然后将该数据乘以一个需要自己调整的参数, 然后再减去从imu获得的数据.\n不同点是[4]中直接获取的光流速度然后利用他的模块手册提供的滤波函数对数据进行滤波之后再减去imu补偿量, 得到补偿后的速度. [5]中是先获取速度然后积分成位移, 再用位移减去补偿量然后再微分成速度.(这么做主要考虑到速度不好标定, 但位移相对来说更容易得到测量值用于矫正参数的赋值)\n目前使用的MTF-01光流传感器只提供了读取光流速度的相关函数, 如下\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 // mtf01.h #pragma once #include \u0026lt;stdbool.h\u0026gt; #include \u0026lt;stdint.h\u0026gt; #include \u0026lt;string.h\u0026gt; #define MICOLINK_MSG_HEAD 0xEF #define MICOLINK_MAX_PAYLOAD_LEN 64 #define MICOLINK_MAX_LEN MICOLINK_MAX_PAYLOAD_LEN + 7 /* 消息ID定义 */ enum { MICOLINK_MSG_ID_RANGE_SENSOR = 0x51, // 测距传感器 }; /* 消息结构体定义 */ typedef struct { uint8_t head; uint8_t dev_id; uint8_t sys_id; uint8_t msg_id; uint8_t seq; uint8_t len; uint8_t payload[MICOLINK_MAX_PAYLOAD_LEN]; uint8_t checksum; uint8_t status; uint8_t payload_cnt; } MICOLINK_MSG_t; /* 数据负载定义 */ #pragma pack(1) // 测距传感器 typedef struct { uint32_t time_ms; // 系统时间 ms uint32_t distance; // 距离(mm) 最小值为10，0表示数据不可用 uint8_t strength; // 信号强度 uint8_t precision; // 精度 uint8_t tof_status; // 状态 uint8_t reserved1; // 预留 int16_t flow_vel_x; // 光流速度x轴 int16_t flow_vel_y; // 光流速度y轴 uint8_t flow_quality; // 光流质量 uint8_t flow_status; // 光流状态 uint16_t reserved2; // 预留 } MICOLINK_PAYLOAD_RANGE_SENSOR_t; #pragma pack() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 // mtf01.c #include \u0026#34;mtf01.h\u0026#34; /* 说明： 用户使用micolink_decode作为串口数据处理函数即可 距离有效值最小为10(mm),为0说明此时距离值不可用 光流速度值单位：cm/s@1m 飞控中只需要将光流速度值*高度，即可得到真实水平位移速度 计算公式：实际速度(cm/s)=光流速度*高度(m) */ bool micolink_parse_char(MICOLINK_MSG_t *msg, uint8_t data); void micolink_decode(uint8_t data) { static MICOLINK_MSG_t msg; if (micolink_parse_char(\u0026amp;msg, data) == false) return; switch (msg.msg_id) { case MICOLINK_MSG_ID_RANGE_SENSOR: { MICOLINK_PAYLOAD_RANGE_SENSOR_t payload; memcpy(\u0026amp;payload, msg.payload, msg.len); /* 此处可获取传感器数据: 距离 = payload.distance; 强度 = payload.strength; 精度 = payload.precision; 距离状态 = payload.tof_status; 光流速度x轴 = payload.flow_vel_x; 光流速度y轴 = payload.flow_vel_y; 光流质量 = payload.flow_quality; 光流状态 = payload.flow_status; */ break; } default: break; } } bool micolink_check_sum(MICOLINK_MSG_t *msg) { uint8_t length = msg-\u0026gt;len + 6; uint8_t temp[MICOLINK_MAX_LEN]; uint8_t checksum = 0; memcpy(temp, msg, length); for (uint8_t i = 0; i \u0026lt; length; i++) { checksum += temp[i]; } if (checksum == msg-\u0026gt;checksum) return true; else return false; } bool micolink_parse_char(MICOLINK_MSG_t *msg, uint8_t data) { switch (msg-\u0026gt;status) { case 0: // 帧头 if (data == MICOLINK_MSG_HEAD) { msg-\u0026gt;head = data; msg-\u0026gt;status++; } break; case 1: // 设备ID msg-\u0026gt;dev_id = data; msg-\u0026gt;status++; break; case 2: // 系统ID msg-\u0026gt;sys_id = data; msg-\u0026gt;status++; break; case 3: // 消息ID msg-\u0026gt;msg_id = data; msg-\u0026gt;status++; break; case 4: // 包序列 msg-\u0026gt;seq = data; msg-\u0026gt;status++; break; case 5: // 负载长度 msg-\u0026gt;len = data; if (msg-\u0026gt;len == 0) msg-\u0026gt;status += 2; else if (msg-\u0026gt;len \u0026gt; MICOLINK_MAX_PAYLOAD_LEN) msg-\u0026gt;status = 0; else msg-\u0026gt;status++; break; case 6: // 数据负载接收 msg-\u0026gt;payload[msg-\u0026gt;payload_cnt++] = data; if (msg-\u0026gt;payload_cnt == msg-\u0026gt;len) { msg-\u0026gt;payload_cnt = 0; msg-\u0026gt;status++; } break; case 7: // 帧校验 msg-\u0026gt;checksum = data; msg-\u0026gt;status = 0; if (micolink_check_sum(msg)) { return true; } default: msg-\u0026gt;status = 0; msg-\u0026gt;payload_cnt = 0; break; } return false; } 推测读取光流速度后直接减去陀螺仪获取的速度然后赋给ek3进行后续的数据融合即可\nArdupilot官方文档中的校准传感器 见参考资料[6], 在文档中发现一出校准光流传感器的操作, 其中提到FLOW_FXSCALER, FLOW_FYSCALER两个参数用于把光流速度与imu速度调整到相近波形, 尚未经过测试这个参数的用处\n参考资料 [1] 光流定点若干问题分析_权盛光流 无法定高_engineerlixl的博客-CSDN博客\n[2] Ardupilot光流代码分析 - CodeAntenna\n[3] PX4FLOW光流模块DIY（含部分代码讲解）_xian_z的博客-CSDN博客\n[4] 无人机—加速度计与光流数据融合_光流融合_经纬的无疆的博客-CSDN博客\n[5] 无人机飞控之光流知识小结（包含LK算法的讲解，across写的） | 码农家园 (codenong.com)\n[6] Optical Flow Sensor Testing and Setup — Copter documentation (ardupilot.org)\n","date":"2023-04-28T02:02:45+08:00","image":"https://raw.githubusercontent.com/TioeAre/imageHost/main/pictures/85626613_p0_master1200.jpg","permalink":"/daily/2023.04.28/","title":"imu补偿光流"},{"content":"RealSense D455的标定 imu自校准 intel发布的d455深度相机自带的有一个imu，在对相机进行标定之前首先要校准一下imu\n校准操作见官方文档，官方提供有python脚本用于自动化校准，pdf中对具体操作有明确表述。这里提到一点操作时的一个bug\n正常情况下执行校准程序输出应当类似于\n只要按照pdf中示例的方式摆放相机，当三轴角度都为true的时候就会自动收集数据，但是我最开始遇到了\n一直停留在Status.rotate状态，无论怎么转都无法稳定在collect中，然后在github的issue中发现了相似问题\n解决方法：\n修改rs-imu-calibration.py第100行与616行，范围改大一些到0.6就可以了\n1 2 3 self.max_norm = np.linalg.norm(np.array([0.6, 0.6, 0.6])) max_norm = np.linalg.norm(np.array([0.6, 0.6, 0.6])) 参考链接:https://github.com/IntelRealSense/librealsense/issues/10418#issuecomment-1103125414\n打开realsense-viewer可以发现校准后竖直摆放相机，重力加速度近似于9.8，而校准前显示为8.8，说明校准起到效果\n联合标定 出现了以下bug，需要sudo apt install libelf-dev\n1 2 3 /home/username/packages/realsense_imu_catkin_ws/src/code_utils/include/code_utils/backward.hpp:216:25: fatal error: elfutils/libdw.h: No such file or directory 216 | # include \u0026lt;elfutils/libdw.h\u0026gt; | ^~~~~~~~~~~~~~~~~~ 但是安装的时候apt报错\n1 2 3 4 5 6 7 8 9 10 Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies. libdw-dev : Depends: libelf-dev but it is not going to be installed Depends: libdw1 (= 0.165-3ubuntu1.2) but 0.176-1.1build1 is to be installed E: Unable to correct problems, you have held broken packages. 下载最新的安装包手动安装\nhttp://archive.ubuntu.com/ubuntu/pool/main/e/elfutils/libelf-dev_0.176-1.1build1_amd64.deb\nhttp://archive.ubuntu.com/ubuntu/pool/main/e/elfutils/libdw-dev_0.176-1.1build1_amd64.deb\n1 2 3 4 /home/username/packages/realsense_imu_catkin_ws/src/code_utils/src/sumpixel_test.cpp:2:10: fatal error: backward.hpp: No such file or directory 2 | #include \u0026#34;backward.hpp\u0026#34; | ^~~~~~~~~~~~~~ compilation terminated. 修改sumpixel_test.cpp第2行为`#include \u0026ldquo;code_utils/backward.hpp\u0026rdquo;\n1 error: ‘integer_sequence’ is not a member of ‘std’ 75 | std::integer_sequence\u0026lt;T, N, Ns...\u0026gt; 修改CMakests.txt\n1 set(CMAKE_CXX_STANDARD 14) 1 2 3 /home/username/packages/realsense_imu_catkin_ws/src/code_utils/src/mat_io_test.cpp:33:47: error: ‘CV_LOAD_IMAGE_UNCHANGED’ was not declared in this scope 33 | Mat img1 = imread( \u0026#34;/home/gao/IMG_1.png\u0026#34;, CV_LOAD_IMAGE_UNCHANGED ); | ^~~~~~~~~~~~~~~~~~~~~~~ opencv版本宏定义问题，改相关代码为新版的就行\nhttps://blog.csdn.net/weixin_44675820/article/details/124796674\nhttps://www.cnblogs.com/zzzsj/p/15699524.html\n1 /home/tioeare/packages/realsense_imu_catkin_ws/src/imu_utils/src/imu_an.cpp:68:19: error: aggregate ‘std::ofstream out_t’ has incomplete type and cannot be defined 修改imu_an.cpp，添加#include \u0026lt;fstream\u0026gt;\n1 2 3 4 5 6 7 Errors \u0026lt;\u0026lt; aslam_time:make /home/tioeare/packages/kalibr_workspace/logs/aslam_time/build.make.000.log /home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_cv/aslam_time/src/time.cpp:84:25: error: ISO C++17 does not allow dynamic exception specifications 84 | throw (NoHighPerformanceTimersException) | ^~~~~ make[2]: *** [CMakeFiles/aslam_time.dir/build.make:76: CMakeFiles/aslam_time.dir/src/time.cpp.o] Error 1 make[1]: *** [CMakeFiles/Makefile2:295: CMakeFiles/aslam_time.dir/all] Error 2 make: *** [Makefile:146: all] Error 2 把代码里这一行注释掉，很奇怪，这种用法应该C++11就禁止了，github上也没人提\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 gyr x numData 240384 gyr x start_t 1.6799e+09 gyr x end_t 1.6799e+09 gyr x dt -------------600.003 s -------------10 min -------------0.166667 h gyr x freq 400.636 gyr x period 0.00249603 gyr y numData 240384 gyr y start_t 1.6799e+09 gyr y end_t 1.6799e+09 gyr y dt -------------600.003 s -------------10 min -------------0.166667 h gyr y freq 400.636 gyr y period 0.00249603 gyr z numData 240384 gyr z start_t 1.6799e+09 gyr z end_t 1.6799e+09 gyr z dt -------------600.003 s -------------10 min -------------0.166667 h gyr z freq 400.636 gyr z period 0.00249603 Gyro X C -2.40087 59.1038 -17.8144 3.38392 -0.0618206 Bias Instability 3.00267e-05 rad/s Bias Instability 5.92447e-05 rad/s, at 26.0036 s White Noise 16.8009 rad/s White Noise 0.00479981 rad/s bias 0.0580428 degree/s ------------------- Gyro y C -3.7193 89.2566 -24.0407 4.84558 -0.260302 Bias Instability 2.69712e-06 rad/s Bias Instability 9.61604e-05 rad/s, at 22 s White Noise 26.42 rad/s White Noise 0.00733927 rad/s bias -0.304682 degree/s ------------------- Gyro z C -1.0341 30.2021 -13.4864 3.95908 -0.244715 Bias Instability 4.5525e-06 rad/s Bias Instability 1.78885e-05 rad/s, at 56.7372 s White Noise 7.71113 rad/s White Noise 0.00214285 rad/s bias -0.095305 degree/s ------------------- ============================================== ============================================== acc x numData 240384 acc x start_t 1.6799e+09 acc x end_t 1.6799e+09 acc x dt -------------600.003 s -------------10 min -------------0.166667 h acc x freq 400.636 acc x period 0.00249603 acc y numData 240384 acc y start_t 1.6799e+09 acc y end_t 1.6799e+09 acc y dt -------------600.003 s -------------10 min -------------0.166667 h acc y freq 400.636 acc y period 0.00249603 acc z numData 240384 acc z start_t 1.6799e+09 acc z end_t 1.6799e+09 acc z dt -------------600.003 s -------------10 min -------------0.166667 h acc z freq 400.636 acc z period 0.00249603 acc X C -3.7565e-05 0.00153459 -0.000440891 5.14013e-05 1.36731e-05 Bias Instability 0.000415133 m/s^2 White Noise 0.0229567 m/s^2 ------------------- acc y C -0.000153981 0.00273578 0.000838508 -0.000456266 4.36107e-05 Bias Instability 0.000674808 m/s^2 White Noise 0.0392674 m/s^2 ------------------- acc z C -4.04458e-05 0.00242156 -0.00204122 0.000559034 -3.01212e-05 Bias Instability 0.000795269 m/s^2 White Noise 0.0348949 m/s^2 ------------------- [imu_an-1] process has finished cleanly 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Traceback (most recent call last): File \u0026#34;build/kalibr/atomic_configure/kalibr_calibrate_cameras\u0026#34;, line 15, in \u0026lt;module\u0026gt; exec(compile(fh.read(), python_script, \u0026#39;exec\u0026#39;), context) File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_calibrate_cameras\u0026#34;, line 465, in \u0026lt;module\u0026gt; main() File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_calibrate_cameras\u0026#34;, line 175, in main cam = kcc.CameraGeometry(cameraModel, targetConfig, dataset, verbose=(parsed.verbose or parsed.showextraction)) File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_camera_calibration/CameraCalibrator.py\u0026#34;, line 48, in __init__ self.ctarget = TargetDetector(targetConfig, self.geometry, showCorners=verbose) File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_camera_calibration/CameraCalibrator.py\u0026#34;, line 81, in __init__ targetParams = targetConfig.getTargetParams() File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_common/ConfigReader.py\u0026#34;, line 187, in func return f(*args, **kwargs) File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_common/ConfigReader.py\u0026#34;, line 620, in getTargetParams errList.append(\u0026#34;invalid tagSpacing (float)\u0026#34;) NameError: name \u0026#39;errList\u0026#39; is not defined 相应位置的文件中errList全部换成途中的print语句\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Traceback (most recent call last): File \u0026#34;build/kalibr/atomic_configure/kalibr_calibrate_imu_camera\u0026#34;, line 15, in \u0026lt;module\u0026gt; exec(compile(fh.read(), python_script, \u0026#39;exec\u0026#39;), context) File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_calibrate_imu_camera\u0026#34;, line 247, in \u0026lt;module\u0026gt; main() File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_calibrate_imu_camera\u0026#34;, line 173, in main chain.printDetails() File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_common/ConfigReader.py\u0026#34;, line 765, in printDetails camConfig.printDetails(dest) File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_common/ConfigReader.py\u0026#34;, line 387, in printDetails dist_model, dist_coeff = self.getDistortion() File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_common/ConfigReader.py\u0026#34;, line 187, in func return f(*args, **kwargs) File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_common/ConfigReader.py\u0026#34;, line 355, in getDistortion self.checkDistortion(self.data[\u0026#34;distortion_model\u0026#34;], File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_common/ConfigReader.py\u0026#34;, line 350, in checkDistortion self.raiseError(\u0026#34;distortion model \u0026#39;{}\u0026#39; requires {} coefficients; {} given\u0026#34;.format( File \u0026#34;/home/tioeare/packages/kalibr_workspace/src/kalibr/aslam_offline_calibration/kalibr/python/kalibr_common/ConfigReader.py\u0026#34;, line 235, in raiseError raise RuntimeError( \u0026#34;{0}{1}\u0026#34;.format(header, message) ) RuntimeError: [CameraConfig Reader]: distortion model \u0026#39;radtan\u0026#39; requires 4 coefficients; 1 given chain.yaml加逗号\n1 2 3 4 5 pcl::transformPointCloud(*cloud_voxel_tem, *cloud1, T.matrix()); //报错 Signal: SIGSEGV (Segmentation fault) [pcl::VoxelGrid::applyFilter] Leaf size is too small for the input dataset. Integer indices would overflow. Assignment with new_width equal to 0,setting width to size of the cloud and height to 1 ","date":"2023-03-26T02:02:45+05:00","image":"https://raw.githubusercontent.com/TioeAre/imageHost/main/pictures/102368197_p0_master1200.jpg","permalink":"/daily/2023.03.26/","title":"D455标定与pcl点云库的学习"},{"content":"周一至周三 由于交付时间有点紧，生产的同事主要在做交付到西藏的大型无人机，然后我就去帮忙装配小无人机\n周三到周五 继续我的算法部分，这两天先跑通了orb-slam3，ORB-SLAM是西班牙 Zaragoza 大学的 Raúl Mur-Arta 编写的视觉 SLAM 系统。 它是一个完整的 SLAM 系统，包括视觉里程计、跟踪、回环检测，是一种完全基于稀疏特征点的单目 SLAM 系统，同时还有单目、双目、RGBD 相机的接口。核心是使用 ORB (Orinted FAST and BRIEF) 作为整个视觉 SLAM 中的核心特征。\n这周首先在我的电脑上跑通了20年发布的orb-slam3。\n效果如下:\n图中左侧窗口为构建的稀疏地图，蓝色表示相机位姿，散点为提取的orb特征点，右侧窗口为双目红外相机实时拍摄到的图像，绿色点为图像中的检测到的特征点\n运行步骤 主要运行环境为ubuntu20.04系统，ROS版本为noetic，OpenCV版本4.5.5，eigen版本3.4.0\n在运行过程中主要官方文档，其中主要遇到了两个bug，如下\nopencv版本问题 在运行ROS的实例中，由于安装时ROS noetic自带的有4.2.0的OpenCV，cv_bridge也是4.2的，导致会出现如下错误\n1 2 \u0026#39;cv::Exception\u0026#39; what(): OpenCV(4.5.5) /home/ubuntu/Downloads/opencv-4.5.5/opencv/modules/core/src/matrix.cpp:250: error: (-215:Assertion failed) s \u0026gt;= 0 in function \u0026#39;setSize\u0026#39;` \u0026#39;cv::Exception\u0026#39; what(): OpenCV(4.5.5) /home/ubuntu/Downloads/opencv-4.5.5/opencv/modules/core/src/alloc.cpp:73: error: (-4:Insufficient memory) Failed to allocate 87219830269440 bytes in function \u0026#39;OutOfMemoryError 需要自己再下载一个cv_bridge的源码，然后编译出本机4.5.5版本的cv_bridge，随后在orbslam3的CMakeLists.txt中修改如下\n1 2 3 4 5 6 7 8 9 10 11 12 set(cv_bridge_DIR \u0026#34;/home/username/path_to_cvbridge_build_ws/devel/share/cv_bridge/cmake\u0026#34;) set(OpenCV_DIR /usr/local/share/opencv4) LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules) find_package(OpenCV 4.5.5 REQUIRED) if(NOT OpenCV_FOUND) message(FATAL_ERROR \u0026#34;OpenCV \u0026gt; 4.4 not found.\u0026#34;) endif() MESSAGE(\u0026#34;OPENCV VERSION:\u0026#34;) MESSAGE(${OpenCV_VERSION}) c++版本问题 原版默认的c++为c++11版本，但实操发现编译无法通过，需要修改为c++14，修改如下\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # Check C++11 or C++0x support include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG(\u0026#34;-std=c++14\u0026#34; COMPILER_SUPPORTS_CXX11) CHECK_CXX_COMPILER_FLAG(\u0026#34;-std=c++0x\u0026#34; COMPILER_SUPPORTS_CXX0X) if(COMPILER_SUPPORTS_CXX14) set(CMAKE_CXX_FLAGS \u0026#34;${CMAKE_CXX_FLAGS} -std=c++14\u0026#34;) add_definitions(-DCOMPILEDWITHC11) message(STATUS \u0026#34;Using flag -std=c++14.\u0026#34;) elseif(COMPILER_SUPPORTS_CXX0X) set(CMAKE_CXX_FLAGS \u0026#34;${CMAKE_CXX_FLAGS} -std=c++0x\u0026#34;) add_definitions(-DCOMPILEDWITHC0X) message(STATUS \u0026#34;Using flag -std=c++0x.\u0026#34;) else() message(FATAL_ERROR \u0026#34;The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.\u0026#34;) endif() #添加c++14标准 eigen3 1 2 3 4 5 6 7 8 9 CMake Error at CMakeLists.txt:44 (find_package): Found package configuration file: /usr/local/lib/cmake/Pangolin/PangolinConfig.cmake but it set Pangolin_FOUND to FALSE so package \u0026#34;Pangolin\u0026#34; is considered to be NOT FOUND. Reason given by package: Pangolin could not be found because dependency Eigen3 could not be found. cmakelists.txt中eigen部分换为\n1 FIND_PACKAGE(Eigen3 REQUIRED NO_MODULE) intel realsense d455相关设置 需要将红外相机的红外发射器关掉，否则会极大影响特征的提取\n1 stereo_module emitter_enabled 需要将lanuch文件中这两项设为false\n下一周计划 目前的算法中只能建立起稀疏地图用于自身的定位，下一步需要借助pcl库和深度相机建立起稠密点云地图来实现避障和导航功能\n","date":"2023-03-26T02:02:45+08:00","image":"https://raw.githubusercontent.com/TioeAre/imageHost/main/pictures/100285476_p0_master1200.jpg","permalink":"/daily/2023.03.23/","title":"装配并学习点云库"},{"content":"Caddy v2, webhook, hugo搭建博客并配置bitwarden与v2ray 项目概述 版本说明 caddy 之前我的服务器(amd64, debain10)上一直用的是caddy 1.x版本, 目前官方为了推广2.0版本, 已经绝情的将v1版本的官方下载渠道, 插件安装脚本以及文档等全都删掉了🙃, 导致我最开始看的关于v1版搭建博客的教程全都用不了. 并且由于v1版已经发布很多年了, 而v2在2020年才发布. 网上绝大部分教程以及git, webhook相关的插件还都是v1版的, 对纯萌新来说挺难找到合适的教程来详细描述具体如何配置. 目前网上也有了很多大佬开源的包含有caddy v2, hugo等的docker镜像可以方便的一键搭建博客. 但不知道为什么在我的服务器上运行时似乎没有办法正常监听端口一样，总是接受不到相关的请求\n此外, caddy v2与v1相比配置文件改成了原生json格式, 之前v1版本的时候使用的配置文件是Caddyfile, 写起来即简便又易读. 现在换成json之后, 虽然还是可以用Caddyfile来写, 但是实际运行caddy似乎会先将Caddyfile转化成json然后再运行. 这就导致写在Caddyfile里的配置, 尤其是相关插件的配置很可能在转化的时候出现某些问题导致运行失败. 还有另外一个很重要的问题是, 大多v2版本的caddy插件是支持Caddyfile的写法的, 但有些插件就只有json格式的配置写法. 而前面也提到Caddyfile是可以被caddy转化为json格式的, 可以使用caddy adapt命令显式转化文件。所以即使部分插件在文档中只写了Caddyfile的写法, 你也可以先写这部分的配置写道Caddyfile里然后再转化为json继续配置\n总上所述, 最终选择了本地使用xcaddy构建带有vrongmeal/caddygit, WingLim/caddy-webhook , mholt/caddy-webdav这三个插件的caddy v2.6.4在本地运行json格式配置文件的方式完成服务器的路由配置\nbitwarden bitwarden是一个开源, 方便的密码管理器, 在网页(chrome, firefox, safair)/android/ios/windows/linux等全平台都有相关客户端(网页插件), 支持部署到自己的服务器构建自己专属的密码库，有效的提高了安全性. 之前caddy配置bitwarden的时候, 可以使用官方的docker镜像, 只用映射一下端口就可以一键部署. 现在caddy升级到v2之后好像对bitwarden还不适配, 只能使用最新版本的vaultwarden(bitwarden的一个第三方版本)来部署\nhugo hugo是一个方便的从md文档构建静态网页的工具, 非常符合我目前的需求. 但是注意很多网站的主题要求hugo是extend版(hugo官方也推荐使用extend版), 同时由于主题模板的更新, 很多主题对hugo的版本要求会比较新. 但apt安装的是0.55版的, 不符合我目前主题的要求. 官方还提供了snap安装, 但我在服务器上装的时候出现了好像说系统不匹配的错误😔, 看github的issue上有人提过类似的, 下面有个回答说他已经修复了, 可是我的这个还是不行. 所以最后采用了在github的release里下载extend版的deb安装包，然后再在本地dpkg -i安装\n格式说明 本文假定你已经有一个属于自己的服务器和域名, 并且已经把dns解析好了, 国内服务器的备案也不在本文讨论范围内. 本文仅包含caddy的安装配置, 配置文件caddyfile.json的编写, hugo的安装配置和vaultwarden docker镜像的配置\n本文接下来在配置文件中出现的必需需要读者本人根据自己服务器等进行修改的地方会使用类似@1{path}的方式代指，例如你本地的某个文件夹地址为/usr/local/bin, 在配置文件中会以@1{path}代指这个地址(数字指的是这个文件中出现的第几个, 如果两个地方用一个的话就是一个地址). 同理@1{domain}代指文件中第一个出现的需要你修改成自己的域名www.your-domain.com\n安装 caddy caddy从官方途径apt安装的是没有插件的, 没插件没办法完成接下来的部署, 但是从apt安装的会配套相关的systemd服务, 方便后续管理运行重启等. 因此先apt安装没有插件的caddy然后再通过xcaddy来编译带有插件的caddy, 编译完成后替换掉之前apt安装的caddy\napt安装caddy 1 2 3 4 5 apt install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf \u0026#39;https://dl.cloudsmith.io/public/caddy/stable/gpg.key\u0026#39; | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf \u0026#39;https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt\u0026#39; | tee /etc/apt/sources.list.d/caddy-stable.list apt update apt install caddy go环境 由于xcaddy是由go语言编译安装的, 所以需要先配置环境\n1 2 3 4 5 6 7 8 9 wget https://go.dev/dl/go1.20.7.linux-amd64.tar.gz rm -rf /usr/local/go \u0026amp;\u0026amp; tar -C /usr/local -xzf go1.20.7.linux-amd64.tar.gz \u0026amp;\u0026amp; rm go1.20.7.linux-amd64.tar.gz vim ~/.bashrc #写入文件 export PATH=$PATH:/usr/local/go/bin #保存文件 source ~/.bashrc xcaddy 安装xcaddy\n1 go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest xcaddy编译带插件的caddy\n1 2 3 4 5 export version=$(curl -s \u0026#34;https://api.github.com/repos/caddyserver/caddy/releases/latest\u0026#34; | grep tag_name | cut -f4 -d \u0026#34;\\\u0026#34;\u0026#34;) go/bin/xcaddy build ${version} \\ --with github.com/WingLim/caddy-webhook \\ --with github.com/mholt/caddy-webdav \\ --with github.com/vrongmeal/caddygit 之后会编译出带有这三个插件的caddy到当前目录, 如果你需要其他插件的话, 后面--with接着跟插件的github仓库地址就行了\n编译完成后使用whereis caddy查看之前apt安装的caddy安装到哪里了, 再用mv把刚编译的带插件的替换掉apt安装的\n1 mv caddy /usr/bin/caddy hugo 1 2 3 export version=$(curl -s \u0026#34;https://api.github.com/repos/gohugoio/hugo/releases/latest\u0026#34; | grep tag_name | cut -f4 -d \u0026#34;\\\u0026#34;\u0026#34; | grep -oE \u0026#39;([0-9]+\\.?)+\u0026#39;) wget https://github.com/gohugoio/hugo/releases/download/v${version}/hugo_extended_${version}_linux-amd64.deb dpkg -i hugo_extended_${version}_linux-amd64.deb vaultwarden 需要先安装docker, 安装好后再\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 apt-get install ca-certificates curl gnupg install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg echo \u0026#34;deb [arch=\u0026#34;$(dpkg --print-architecture)\u0026#34; signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \u0026#34;$(. /etc/os-release \u0026amp;\u0026amp; echo \u0026#34;$VERSION_CODENAME\u0026#34;)\u0026#34; stable\u0026#34; | tee /etc/apt/sources.list.d/docker.list \u0026gt; /dev/null apt-get update apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker run -d --name vaultwarden \\ -e SIGNUPS_ALLOWED=true \\ -e WEBSOCKET_ENABLED=true \\ -e LOG_FILE=/data/bitwarden.log \\ -p @1{vault_port}:80 \\ -p @2{vault_port}:3012 \\ -v /vw-data/:/data/ \\ vaultwarden/server:1.27.0 此处的@1{vault-port}和@2{vault-port}需要替换掉成之后你在caddy的配置文件中反代的端口, 因此建议配置好其他之后再安装这个\n配置 变量解释如下，需要将下面所有配置文件中出现的地方替换成你自己的\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @1{vault_port}:80\t--caddy反代的bitwarden端口，例如8080：80 @2{vault_port}:3012\t--caddy反代的bitwarden端口，例如3012：3012 @3{v2ray_port}\t--caddy反代的v2ray端口，例如2233 @1{cer_path}\t--bitwarden网站的证书cer部分，例如usr/local/etc/ssl/bitwarden.cer @1{key_path} --bitwarden网站的证书key部分, 例如usr/local/etc/ssl/bitwarden.key @2{cer_path}\t--blog网站的证书cer部分 @2{key_path}\t--blog网站的证书key部分 @3{v2ray_path}\t--v2ray的访问路径，以/开头，例如/vvv。但是不能和@4{v2ray_www_path}的最后一级相同，即如果@4{v2ray_www_path}是/var/www/v2ray的话，就不能是/v2ray @4{v2ray_www_path}\t--v2ray网站的存放路径，例如/var/www/v2ray @5{blog_path}\t--存放博客网站的地址, 例如/var/www/myblog @1{vault_domain}\t--bitwarden的域名 @2{blog_domain}\t--blog的域名 @3{v2ray_domain}\t--v2ray的伪装域名 @1{github_url}\t--存放博客文档的github仓库地址 @1{github_token}\t--有存放博客文档的github仓库访问权限的token @1{github_secret}\t--webhook的secret @1{v2ray_uuid}\t--v2ray配置 @1{your_email}\t--注册域名时使用的邮箱 @1{cloudflare_key}\t--cloudflare的key caddy caddy.service 首先需要修改以下caddy.service配置相关服务\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 vim /etc/systemd/system/caddy.service # caddy.service # # For using Caddy with a config file. # # Make sure the ExecStart and ExecReload commands are correct # for your installation. # # See https://caddyserver.com/docs/install for instructions. # # WARNING: This service does not use the --resume flag, so if you # use the API to make changes, they will be overwritten by the # Caddyfile next time the service is restarted. If you intend to # use Caddy\u0026#39;s API to configure it, add the --resume flag to the # `caddy run` command or use the caddy-api.service file instead. [Unit] Description=Caddy Documentation=https://caddyserver.com/docs/ After=network.target network-online.target Requires=network-online.target [Service] Type=notify User=caddy Group=caddy ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/caddyfile.json ExecReload=/usr/bin/caddy reload --config /etc/caddy/caddyfile.json --force TimeoutStopSec=5s LimitNOFILE=1048576 LimitNPROC=512 PrivateTmp=true ProtectSystem=full AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] WantedBy=multi-user.target chown root:root /etc/systemd/system/caddy.service chmod 644 /etc/systemd/system/caddy.service systemctl daemon-reload chown root:root /usr/bin/caddy chmod 755 /usr/bin/caddy setcap \u0026#39;cap_net_bind_service=+ep\u0026#39; /usr/bin/caddy groupadd -g 33 caddy useradd \\ -g caddy --no-user-group \\ --home-dir /var/caddy --no-create-home \\ --shell /usr/sbin/nologin \\ --system --uid 33 caddy mkdir /etc/caddy mkdir /var/www mkdir /var/caddy mkdir /etc/ssl/caddy touch /etc/caddy/caddyfile.json touch /var/log/caddy.log chown caddy:caddy /var/caddy chown -R root:caddy /etc/caddy chown -R root:caddy /etc/ssl/caddy chown -R root:caddy /var/www chmod 555 /var/caddy chmod 777 /var/www chmod 0770 /etc/ssl/caddy chown root:caddy /var/log/caddy.log chown root:root /etc/caddy/caddyfile.json chmod 770 /var/log/caddy.log chmod 644 /etc/caddy/caddyfile.json caddyfile.json 接着配置caddyfile.json\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 vim /etc/caddy/caddyfile.json { \u0026#34;logging\u0026#34;: { \u0026#34;logs\u0026#34;: { \u0026#34;default\u0026#34;: { \u0026#34;exclude\u0026#34;: [ \u0026#34;http.log.access.log0\u0026#34;, \u0026#34;http.log.access.log1\u0026#34;, \u0026#34;http.log.access.log2\u0026#34; ] }, \u0026#34;log0\u0026#34;: { \u0026#34;writer\u0026#34;: { \u0026#34;filename\u0026#34;: \u0026#34;/var/log/caddy.log\u0026#34;, \u0026#34;output\u0026#34;: \u0026#34;file\u0026#34;, \u0026#34;roll_keep\u0026#34;: 10, \u0026#34;roll_size_mb\u0026#34;: 10 }, \u0026#34;level\u0026#34;: \u0026#34;INFO\u0026#34;, \u0026#34;include\u0026#34;: [ \u0026#34;http.log.access.log0\u0026#34; ] }, \u0026#34;log1\u0026#34;: { \u0026#34;writer\u0026#34;: { \u0026#34;filename\u0026#34;: \u0026#34;/var/log/caddy.log\u0026#34;, \u0026#34;output\u0026#34;: \u0026#34;file\u0026#34; }, \u0026#34;include\u0026#34;: [ \u0026#34;http.log.access.log1\u0026#34; ] }, \u0026#34;log2\u0026#34;: { \u0026#34;writer\u0026#34;: { \u0026#34;filename\u0026#34;: \u0026#34;/var/log/caddy.log\u0026#34;, \u0026#34;output\u0026#34;: \u0026#34;file\u0026#34; }, \u0026#34;include\u0026#34;: [ \u0026#34;http.log.access.log2\u0026#34; ] } } }, \u0026#34;apps\u0026#34;: { \u0026#34;tls\u0026#34;: { \u0026#34;certificates\u0026#34;: { \u0026#34;load_files\u0026#34;: [ { \u0026#34;certificate\u0026#34;: \u0026#34;@1{cer_path}\u0026#34;, \u0026#34;key\u0026#34;: \u0026#34;@1{key_path}\u0026#34;, \u0026#34;tags\u0026#34;: [ \u0026#34;cert0\u0026#34; ] }, { \u0026#34;certificate\u0026#34;: \u0026#34;@2{cer_path}\u0026#34;, \u0026#34;key\u0026#34;: \u0026#34;@2{cer_path}\u0026#34;, \u0026#34;tags\u0026#34;: [ \u0026#34;cert1\u0026#34; ] } ] }, \u0026#34;automation\u0026#34;: { \u0026#34;policies\u0026#34;: [ { \u0026#34;subjects\u0026#34;: [ \u0026#34;@1{vault_domain}\u0026#34;, \u0026#34;@2{blog_domain}\u0026#34; ] }, { \u0026#34;subjects\u0026#34;: [ \u0026#34;@3{v2ray_domain}\u0026#34; ], \u0026#34;issuers\u0026#34;: [ { \u0026#34;email\u0026#34;: \u0026#34;@1{your_email}\u0026#34;, \u0026#34;module\u0026#34;: \u0026#34;acme\u0026#34; }, { \u0026#34;email\u0026#34;: \u0026#34;@1{your_email}\u0026#34;, \u0026#34;module\u0026#34;: \u0026#34;zerossl\u0026#34; } ] } ] } }, \u0026#34;http\u0026#34;: { \u0026#34;servers\u0026#34;: { \u0026#34;srv1\u0026#34;: { \u0026#34;listen\u0026#34;: [ \u0026#34;:80\u0026#34; ], \u0026#34;routes\u0026#34;: [ { \u0026#34;match\u0026#34;: [ { \u0026#34;host\u0026#34;: [ \u0026#34;@1{vault_domain}\u0026#34; ] } ], \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;subroute\u0026#34;, \u0026#34;routes\u0026#34;: [ { \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;static_response\u0026#34;, \u0026#34;headers\u0026#34;: { \u0026#34;Location\u0026#34;: [ \u0026#34;https://@1{vault_domain}\u0026#34; ] }, \u0026#34;status_code\u0026#34;: 302 } ] } ] } ], \u0026#34;terminal\u0026#34;: true }, { \u0026#34;match\u0026#34;: [ { \u0026#34;host\u0026#34;: [ \u0026#34;@2{blog_domain}\u0026#34; ] } ], \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;subroute\u0026#34;, \u0026#34;routes\u0026#34;: [ { \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;static_response\u0026#34;, \u0026#34;headers\u0026#34;: { \u0026#34;Location\u0026#34;: [ \u0026#34;https://@2{blog_domain}\u0026#34; ] }, \u0026#34;status_code\u0026#34;: 302 } ] } ] } ], \u0026#34;terminal\u0026#34;: true }, { \u0026#34;match\u0026#34;: [ { \u0026#34;host\u0026#34;: [ \u0026#34;@3{v2ray_domain}\u0026#34; ] } ], \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;subroute\u0026#34;, \u0026#34;routes\u0026#34;: [ { \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;static_response\u0026#34;, \u0026#34;headers\u0026#34;: { \u0026#34;Location\u0026#34;: [ \u0026#34;https://@3{v2ray_domain}\u0026#34; ] }, \u0026#34;status_code\u0026#34;: 302 } ] } ] } ], \u0026#34;terminal\u0026#34;: true } ] }, \u0026#34;srv0\u0026#34;: { \u0026#34;listen\u0026#34;: [ \u0026#34;:443\u0026#34; ], \u0026#34;tls_connection_policies\u0026#34;: [ { \u0026#34;match\u0026#34;: { \u0026#34;sni\u0026#34;: [ \u0026#34;@2{blog_domain}\u0026#34; ] }, \u0026#34;certificate_selection\u0026#34;: { \u0026#34;any_tag\u0026#34;: [ \u0026#34;cert1\u0026#34; ] } }, { \u0026#34;match\u0026#34;: { \u0026#34;sni\u0026#34;: [ \u0026#34;@1{vault_domain}\u0026#34; ] }, \u0026#34;certificate_selection\u0026#34;: { \u0026#34;any_tag\u0026#34;: [ \u0026#34;cert0\u0026#34; ] } }, { \u0026#34;match\u0026#34;: { \u0026#34;sni\u0026#34;: [ \u0026#34;@3{v2ray_domain}\u0026#34; ] }, \u0026#34;cipher_suites\u0026#34;: [ \u0026#34;TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\u0026#34;, \u0026#34;TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256\u0026#34; ], \u0026#34;protocol_min\u0026#34;: \u0026#34;tls1.2\u0026#34;, \u0026#34;protocol_max\u0026#34;: \u0026#34;tls1.3\u0026#34; }, {} ], \u0026#34;logs\u0026#34;: { \u0026#34;logger_names\u0026#34;: { \u0026#34;@3{v2ray_domain}\u0026#34;: \u0026#34;log0\u0026#34; }, \u0026#34;logger_names\u0026#34;: { \u0026#34;@1{vault_domain}\u0026#34;: \u0026#34;log1\u0026#34; }, \u0026#34;logger_names\u0026#34;: { \u0026#34;@2{blog_domain}\u0026#34;: \u0026#34;log2\u0026#34; }, \u0026#34;skip_hosts\u0026#34;: [ \u0026#34;@1{vault_domain}\u0026#34;, \u0026#34;@2{blog_domain}\u0026#34;, \u0026#34;@3{v2ray_domain}\u0026#34; ] }, \u0026#34;routes\u0026#34;: [ { \u0026#34;match\u0026#34;: [ { \u0026#34;host\u0026#34;: [ \u0026#34;@3{v2ray_domain}\u0026#34; ] } ], \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;subroute\u0026#34;, \u0026#34;routes\u0026#34;: [ { \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;vars\u0026#34;, \u0026#34;root\u0026#34;: \u0026#34;@4{v2ray_www_path}\u0026#34; }, { \u0026#34;encodings\u0026#34;: { \u0026#34;gzip\u0026#34;: {} }, \u0026#34;handler\u0026#34;: \u0026#34;encode\u0026#34;, \u0026#34;prefer\u0026#34;: [ \u0026#34;gzip\u0026#34; ] } ] }, { \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;reverse_proxy\u0026#34;, \u0026#34;upstreams\u0026#34;: [ { \u0026#34;dial\u0026#34;: \u0026#34;localhost:@3{v2ray_port}\u0026#34; } ] } ], \u0026#34;match\u0026#34;: [ { \u0026#34;header\u0026#34;: { \u0026#34;Connection\u0026#34;: [ \u0026#34;*Upgrade*\u0026#34; ], \u0026#34;Upgrade\u0026#34;: [ \u0026#34;websocket\u0026#34; ] }, \u0026#34;path\u0026#34;: [ \u0026#34;@3{v2ray_path}\u0026#34; ] } ] }, { \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;file_server\u0026#34;, \u0026#34;hide\u0026#34;: [ \u0026#34;/etc/caddy/Caddyfile\u0026#34; ] } ] } ] } ], \u0026#34;terminal\u0026#34;: true }, { \u0026#34;match\u0026#34;: [ { \u0026#34;host\u0026#34;: [ \u0026#34;@1{vault_domain}\u0026#34; ] } ], \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;subroute\u0026#34;, \u0026#34;routes\u0026#34;: [ { \u0026#34;handle\u0026#34;: [ { \u0026#34;encodings\u0026#34;: { \u0026#34;gzip\u0026#34;: {} }, \u0026#34;handler\u0026#34;: \u0026#34;encode\u0026#34;, \u0026#34;prefer\u0026#34;: [ \u0026#34;gzip\u0026#34; ] } ] }, { \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;reverse_proxy\u0026#34;, \u0026#34;upstreams\u0026#34;: [ { \u0026#34;dial\u0026#34;: \u0026#34;localhost:@2{vault_port}\u0026#34; } ] } ], \u0026#34;match\u0026#34;: [ { \u0026#34;path\u0026#34;: [ \u0026#34;/notifications/hub\u0026#34; ] } ] }, { \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;reverse_proxy\u0026#34;, \u0026#34;headers\u0026#34;: { \u0026#34;request\u0026#34;: { \u0026#34;set\u0026#34;: { \u0026#34;X-Real-Ip\u0026#34;: [ \u0026#34;localhost\u0026#34; ] } } }, \u0026#34;upstreams\u0026#34;: [ { \u0026#34;dial\u0026#34;: \u0026#34;localhost:@1{vault_port}\u0026#34; } ] } ] } ] } ], \u0026#34;terminal\u0026#34;: true }, { \u0026#34;match\u0026#34;: [ { \u0026#34;host\u0026#34;: [ \u0026#34;@5{blog_domain}\u0026#34; ] } ], \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;subroute\u0026#34;, \u0026#34;routes\u0026#34;: [ { \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;vars\u0026#34;, \u0026#34;root\u0026#34;: \u0026#34;@5{blog_path}/public\u0026#34; }, { \u0026#34;handler\u0026#34;: \u0026#34;file_server\u0026#34;, \u0026#34;hide\u0026#34;: [ \u0026#34;/etc/caddy/Caddyfile\u0026#34; ] } ] } ] } ], \u0026#34;terminal\u0026#34;: true, \u0026#34;match\u0026#34;: [ { \u0026#34;not\u0026#34;: [ { \u0026#34;path\u0026#34;: [ \u0026#34;/webhook\u0026#34; ] } ] } ] }, { \u0026#34;handle\u0026#34;: [ { \u0026#34;handler\u0026#34;: \u0026#34;subroute\u0026#34;, \u0026#34;routes\u0026#34;: [ { \u0026#34;handle\u0026#34;: [ { \u0026#34;branch\u0026#34;: \u0026#34;main\u0026#34;, \u0026#34;handler\u0026#34;: \u0026#34;webhook\u0026#34;, \u0026#34;path\u0026#34;: \u0026#34;@5{blog_path}/content\u0026#34;, \u0026#34;repo\u0026#34;: \u0026#34;@1{github_url}\u0026#34;, \u0026#34;token\u0026#34;: \u0026#34;@1{github_token}\u0026#34;, \u0026#34;secret\u0026#34;: \u0026#34;@1{github_secret}\u0026#34;, \u0026#34;command\u0026#34;: [ \u0026#34;hugo\u0026#34;, \u0026#34;--destination\u0026#34;, \u0026#34;@5{blog_path}/public\u0026#34; ], \u0026#34;submodule\u0026#34;: true, \u0026#34;type\u0026#34;: \u0026#34;github\u0026#34; } ] } ] } ], \u0026#34;match\u0026#34;: [ { \u0026#34;path\u0026#34;: [ \u0026#34;/webhook\u0026#34; ] } ] } ] } } } } } v2ray https://github.com/zxcvos/Xray-script\nconfig.json mkdir -p /usr/local/etc/v2ray/\nmkdir -p /usr/local/etc/ssl/ecc/\nvim /usr/local/etc/v2ray/config.json\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 { \u0026#34;log\u0026#34;: { \u0026#34;access\u0026#34;: \u0026#34;/var/log/v2ray/access.log\u0026#34;, \u0026#34;error\u0026#34;: \u0026#34;/var/log/v2ray/error.log\u0026#34;, \u0026#34;loglevel\u0026#34;: \u0026#34;warning\u0026#34; }, \u0026#34;dns\u0026#34;: {}, \u0026#34;stats\u0026#34;: {}, \u0026#34;inbounds\u0026#34;: [ { \u0026#34;port\u0026#34;: @3{v2ray_port}, \u0026#34;listen\u0026#34;: \u0026#34;127.0.0.1\u0026#34;, \u0026#34;protocol\u0026#34;: \u0026#34;vmess\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;clients\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;@1{v2ray_uuid}\u0026#34;, \u0026#34;level\u0026#34;: 0, \u0026#34;email\u0026#34;: \u0026#34;@1{your_email}\u0026#34; } ], \u0026#34;decryption\u0026#34;: \u0026#34;none\u0026#34; }, \u0026#34;streamSettings\u0026#34;: { \u0026#34;network\u0026#34;: \u0026#34;ws\u0026#34;, \u0026#34;security\u0026#34;: \u0026#34;none\u0026#34;, \u0026#34;wsSettings\u0026#34;: { \u0026#34;path\u0026#34;: \u0026#34;@3{v2ray_path}\u0026#34; } } } ], \u0026#34;outbounds\u0026#34;: [ { \u0026#34;tag\u0026#34;: \u0026#34;direct\u0026#34;, \u0026#34;protocol\u0026#34;: \u0026#34;freedom\u0026#34;, \u0026#34;settings\u0026#34;: {} }, { \u0026#34;tag\u0026#34;: \u0026#34;blocked\u0026#34;, \u0026#34;protocol\u0026#34;: \u0026#34;blackhole\u0026#34;, \u0026#34;settings\u0026#34;: {} } ], \u0026#34;routing\u0026#34;: { \u0026#34;domainStrategy\u0026#34;: \u0026#34;IPIfNonMatch\u0026#34;, \u0026#34;rules\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34;, \u0026#34;domain\u0026#34;: [ \u0026#34;googleapis.cn\u0026#34;, \u0026#34;goofle.cn\u0026#34; ], \u0026#34;outboundTag\u0026#34;: \u0026#34;direct\u0026#34; }, { \u0026#34;outboundTag\u0026#34;: \u0026#34;blocked\u0026#34;, \u0026#34;ip\u0026#34;: [ \u0026#34;geoip:private\u0026#34; ], \u0026#34;type\u0026#34;: \u0026#34;field\u0026#34; } ] }, \u0026#34;policy\u0026#34;: {}, \u0026#34;reverse\u0026#34;: {}, \u0026#34;transport\u0026#34;: {} } hugo 1 hugo new site @5{blog_path} 会在@5{blog_path}处建立网站的目录\nvaultwarden 编写脚本监视git活动并更新网页 按理来说是不需要这一步的，应该是caddy接收到github发来的webhook然后就启动相关插件把更新的仓库pull下来, 然后就调用hugo --destination @5{blog_path}/public命令更新网页了\n但实际上发现这个命令居然是在/根目录下执行的, 即使在caddyfile.json里指定root * @5{blog_path} 了也不行.\n开始还想把命令换成执行其他的脚本, 然后在脚本中cd到路径再执行hugo生成网页. 但是好像也没法正常运行起来\n只能退而求其次, 单独编写一个inotify.sh监测@5{blog_path}/content/.git/index这个文件的变动情况然后再执行更新网页, 脚本如下(需要先安装inotify)\n1 2 3 4 5 6 #!/bin/sh filename=$@5{blog_path}/content/.git/index inotifywait -mrq --format \u0026#39;%e\u0026#39; --event create,delete,modify $filename | while read event do cd @5{blog_path} \u0026amp;\u0026amp; hugo done 之后执行nohup bash inotify.sh \u0026gt; /dev/null 2\u0026gt;\u0026amp;1让脚本在后台运行就可以了\n为网站申请证书 (以cloudflare为例) 安装acme.sh\n1 2 curl https://get.acme.sh | sh source ~/.bashrc 1 2 3 export CF_Key=\u0026#34;@1{cloudflare_key}\u0026#34; export CF_Email=\u0026#34;@1{your_email}\u0026#34; acme.sh --register-account -m @1{your_email} 之后运行如下命令即可为blog网站申请证书\n1 acme.sh --issue --dns dns_cf -d @2{blog_domain} --keylength ec-256 #--debug 2 如果出错可以加这个参数看看哪里报错 如下命令可将证书安装在@2{cer_path}, @2{key_path}路径下\n1 acme.sh --installcert -d @2{blog_domain} --ecc --key-file @2{key_path} --fullchain-file @2{cer_path} --force 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 vim /etc/sysctl.conf # max open files fs.file-max = 51200 # max read buffer net.core.rmem_max = 67108864 # max write buffer net.core.wmem_max = 67108864 # default read buffer net.core.rmem_default = 65536 # default write buffer net.core.wmem_default = 65536 # max processor input queue net.core.netdev_max_backlog = 4096 # max backlog net.core.somaxconn = 4096 # resist SYN flood attacks net.ipv4.tcp_syncookies = 1 # reuse timewait sockets when safe net.ipv4.tcp_tw_reuse = 1 # turn off fast timewait sockets recycling net.ipv4.tcp_tw_recycle = 0 # short FIN timeout net.ipv4.tcp_fin_timeout = 30 # short keepalive time net.ipv4.tcp_keepalive_time = 1200 # outbound port range net.ipv4.ip_local_port_range = 10000 65000 # max SYN backlog net.ipv4.tcp_max_syn_backlog = 4096 # max timewait sockets held by system simultaneously net.ipv4.tcp_max_tw_buckets = 5000 # TCP receive buffer net.ipv4.tcp_rmem = 4096 87380 67108864 # TCP write buffer net.ipv4.tcp_wmem = 4096 65536 67108864 # turn on path MTU discovery net.ipv4.tcp_mtu_probing = 1 # for high-latency network net.core.default_qdisc=fq net.ipv4.tcp_congestion_control = bbr sysctl -p apt install libcap2-bin setcap \u0026#39;cap_net_bind_service=+ep\u0026#39; /usr/bin/caddy chown root:root /usr/bin/caddy chown -R root:root /etc/caddy chown -R root:www-data /etc/ssl/caddy chown root:www-data /var/log/caddy.log chown root:root /etc/systemd/system/caddy.service chmod 755 /usr/bin/caddy chmod 770 /etc/ssl/caddy chmod 770 /var/log/caddy.log chmod 644 /etc/systemd/system/caddy.service chown root:root /usr/local/etc/v2ray/v2ray.cer chown root:root /usr/local/etc/v2ray/v2ray.key chmod 644 /usr/local/etc/v2ray/v2ray.cer chmod 644 /usr/local/etc/v2ray/v2ray.key chown root:root /usr/local/etc/ssl/ecc/password.cer chown root:root /usr/local/etc/ssl/ecc/password.key chmod 644 /usr/local/etc/ssl/ecc/password.cer chmod 644 /usr/local/etc/ssl/ecc/password.key chown root:root /usr/local/etc/v2ray/txt.cer chown root:root /usr/local/etc/v2ray/txt.key chmod 644 /usr/local/etc/v2ray/txt.cer chmod 644 /usr/local/etc/v2ray/txt.key mkdir /var/www/public vim /var/www/public/index.html 常用命令表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 bash \u0026lt;(curl -L -s check.unlock.media) acme: export CF_Key=\u0026#34;\u0026#34; export CF_Email=\u0026#34;\u0026#34; acme.sh --register-account -m example@gmail.com acme.sh --issue --dns dns_cf -d example.com --keylength ec-256 --debug 2 acme.sh --installcert -d example.com --ecc --key-file /usr/local/etc/ssl/example.key --fullchain-file /usr/local/etc/ssl/example.cer --force caddy: vim /etc/caddy/caddyfile.json systemctl daemon-reload caddy list-modules\t#查看caddy安装了哪些插件 journalctl --boot -u caddy.service\t#查看caddy详细运行日志 systemctl restart caddy \u0026amp;\u0026amp; systemctl status caddy\t#重启caddy并查看运行状态 v2ray： vim /usr/local/etc/v2ray/config.json systemctl daemon-reload systemctl stop v2ray systemctl restart v2ray \u0026amp;\u0026amp; systemctl status v2ray journalctl -u v2ray bash install-release.sh\t#更新v2ray版本 ufw: utf allow 80\t#防火墙开启80端口允许外界访问， 需要提前apt安装ufw ufw delete 80\t#关闭80端口 ufw status numbered\t#查看开启了哪些端口 docker： docker run -d --name vaultwarden \\ -e SIGNUPS_ALLOWED=true \\ -e WEBSOCKET_ENABLED=true \\ -e LOG_FILE=/data/bitwarden.log \\ -p @1{vault_port}:80 \\ -p @2{vault_port}:3012 \\ -v /vw-data/:/data/ \\ vaultwarden/server:1.27.0 xcaddy： xcaddy build v2.6.0 \\ --with github.com/WingLim/caddy-webhook \\ --with github.com/mholt/caddy-webdav \\ --with github.com/vrongmeal/caddygit inotify: nohup bash inotify.sh \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 其他 搭建所用的所有配置文件如上所示, 接下来写写我在搭建中遇到的一些问题\n原本v2ray使用的是h2+tls协议, 但是似乎没法在caddy v2中正常运行, 然后看到好多教程都是用ws, 我就也改成了ws, 然后就顺利运行了 bitwarden之前的官方docker镜像是可以直接监听443端口传来的https请求. 但新版的Vaultwarden要配备https的话好像很麻烦, 并且申请的证书是在docker容器里的, caddy无法访问. 但实际上可以先给域名申请证书, https的请求发给caddy之后再让caddy转发到aultwarden的docker容器映射的80端口那里. 这样实际访问的时候依然是https加密访问. 不用担心安全问题 参考资料 在搭建这篇博客时参考了以下链接, 感谢各位大佬的分享\ncaddy: Caddy2 简明教程\n利用Caddy实现Hugo个人博客的自动化部署\nvrongmeal/caddygit\nWingLim/caddy-webhook\nWingLim/caddy-webhook\nLadderOperator/docker-caddy2-hugo-alidns\ncaddy community\nvaultwarden: dani-garcia/vaultwarden\nhugo: hugo-command-usage\nHugo 目录组织\nHugo 静态博客食用指南\nStack主题\n","date":"2023-03-16T02:02:45+08:00","image":"https://raw.githubusercontent.com/TioeAre/imageHost/main/pictures/84738802_p0_master1200.jpg","permalink":"/daily/2023.03.16/","title":"搭建自己的第一篇博客"}]