编译transmission0.2

作者尝试手动编写Makefile来编译Transmission-0.2版本,并解决了一系列编译过程中出现的问题,包括编译命令的调整及头文件依赖等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    内容提示:编译transmission0.2

   关键字: 手写Makefile,测试Makefile,确定编译错误要点,修正源文件,正确处理头文件依赖

 

    上次是决定了好好的开始研究Linux的编程技术。陆陆续续把Virual Box3.1.8 和fedora 12给装了上去,配置了共享目录。下载了transmission的1.7的代码,试着编译了一下,

    ./configure

    make

    OMG生成了一大片的lib依赖问题,虽然安装了openssl和一些其他库之后,编译过程很perfect,但是觉得有点无聊。因为太简单了,好像没有一点提高(通过设置configure 参数可以debug,问了QQ群的帮主)。而且transmission也是有点大的 ,不利于开始学习。柿子要拣软的捏啊

     OK,下载Transmission-0.2,解压之后,有点傻眼没有Makefile。犹豫了一天之后决定手写makefile,这星期二晚上看那个陈皓《跟我一起写makefile》从9点看到11点,看了大概二三十页的样子,就动手写(之前看过一些makefile的教材)。有参考了别的源代码的makefile的东西。

    解决问题一:Makefile的gcc -c -o

    Makefile中间最重要的命令

    $(OBJECTS): %o: %c
    $(CC) -c  $< -o -@ (如果有读者看的话,我很sorry,我发现我没办法将这个问题重现了)
    也就是编译 *.c 强制生成*.o(这样做有一个问题如果编译不过的话,就会将编译过程中的报错信息放入.o中,生成只有几个字节的o文件)

    首先是对libtransmission中文件的编译,最后打成一个a文件。OK,没有报错,然后编译transmissioncli.c。连接生成的a文件,形成新的a.out文件。但是transmission凡是连接到a文件的函数全部报错找不到地址。偶然间将 -o这个参数去掉,报错很多很多.注意到之前生成的.o文件只有几十字节.

    解决问题二:头文件依赖

    这个一个大的问题,中间出现了很多症状。其中包括

    1。“error: expected ‘)’ before ‘*’ token” ,

    2。“error: ‘benc_val_t’ undeclared (first use in this function)”

    3。“too many arguments to function ‘tr_bencLoad’”

    4。“expected declaration specifiers or ‘...’ before ‘benc_val_t’”

    5。“expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token”

    6。“too many arguments to function ‘tr_bencLoad’”

    7。 (概述)tr_torrent_t未声明 tr_io_t。

    这些都是编译时候,显示的错误。都是一些头文件依赖问题。需要一点一点纠正。有一些头文件我觉得是很无奈的问题。

比如tracker.h 头文件。tr_tracker_t定义中含有tr_torrent_t,,而tr_torrent_t又含有tr_tacker_t。头文件互相引用,就像计算机死锁一样。

    进行代码的调整,头文件的调整。很繁琐的过程。这个东西做过了,现在发现了我应该好好的记录遇到的错误。

 

    一个星期了transmission的编译问题终于解决了,下边要做的事情就是调试,学会使用以前没用过的东西,比如sha1这些东东 属于openssl的东西

<think>我们正在处理一个关于ROS中修改运动模型以适应四轮麦克纳姆轮底盘并集成odom数据用于建图的问题。 用户的需求是:在四轮麦克纳姆轮底盘上实现带有odom数据的建图功能。 分析: 麦克纳姆轮底盘的运动模型与普通差速底盘不同,它可以通过轮子的独立控制实现全向移动(包括横向移动)。 在ROS中,我们通常使用robot_localization包或robot_pose_ekf包来融合多个传感器数据(包括轮式里程计、IMU等)以提供更准确的odom数据。 但是,对于麦克纳姆轮,我们需要首先根据轮子的转速计算机器人的速度(线速度和角速度),然后通过积分得到里程计(odom)数据。 步骤: 1. 编写节点读取四个轮子的编码器数据(通常通过CAN总线或串口读取,具体取决于硬件)。 2. 根据麦克纳姆轮的运动学模型,将四个轮子的转速转换为机器人在底盘坐标系(通常是base_link)下的线速度和角速度。 3. 使用这些速度信息,结合时间戳,通过积分计算得到机器人的位置和方向(即里程计信息)。 4. 将计算得到的里程计数据发布为nav_msgs/Odometry消息,同时发布TF变换(从odom坐标系到base_link坐标系)。 5. 在建图过程中(如使用gmapping或cartographer),将odom数据作为输入之一,以辅助建图。 注意:由于麦克纳姆轮可能存在打滑,所以轮式里程计会有累积误差,因此通常需要与其他传感器(如IMU)融合以提高精度。 具体实现: 1. 运动学模型: 麦克纳姆轮的运动学模型可以用以下公式表示: $$ v_x = \frac{w_1 + w_2 + w_3 + w_4}{4} \cdot r $$ $$ v_y = \frac{-w_1 + w_2 + w_3 - w_4}{4} \cdot r $$ $$ \omega = \frac{-w_1 + w_2 - w_3 + w_4}{4} \cdot r \cdot \frac{1}{l_x + l_y} $$ 其中,$w_i$是各个轮子的转速(单位:rad/s),$r$是轮子半径,$l_x$和$l_y$分别是轮子中心到机器人中心在x和y方向的距离(半轴距)。 2. 里程计计算: 根据上述速度,我们可以积分得到位置和航向角: $$ x_{t} = x_{t-1} + v_x \cdot \Delta t \cdot \cos(\theta) - v_y \cdot \Delta t \cdot \sin(\theta) $$ $$ y_{t} = y_{t-1} + v_x \cdot \Delta t \cdot \sin(\theta) + v_y \cdot \Delta t \cdot \cos(\theta) $$ $$ \theta_{t} = \theta_{t-1} + \omega \cdot \Delta t $$ 注意:这里我们假设机器人在世界坐标系下的运动,因此需要将底盘坐标系下的速度转换到世界坐标系(通过航向角θ)。 3. 发布Odometry消息和TF变换: 我们需要创建一个节点,该节点订阅编码器数据(例如:/front_left_wheel_velocity, /front_right_wheel_velocity等),然后按照上述公式计算速度,并积分得到位置和方向。 然后,发布nav_msgs/Odometry消息到某个topic(比如/odom),同时发布TF变换:从odom坐标系到base_link坐标系。 4. 融合传感器数据(可选): 为了提高精度,可以使用robot_localization包来融合轮式里程计和IMU数据。这样可以得到更准确的odom数据。 5. 建图: 使用gmapping或cartographer等建图包时,需要提供激光雷达数据和里程计数据(即我们发布的/odom)。在启动建图节点时,设置使用odom数据。 示例代码框架: 我们可以创建一个ROS节点(例如mecanum_odom_node)来实现上述功能。 注意:由于编码器数据通常以脉冲计数或角速度形式给出,我们需要先将其转换为线速度(或者直接使用角速度,因为公式中用的是角速度)。 以下是一个简化的代码框架(Python示例): ```python #!/usr/bin/env python import rospy import math from nav_msgs.msg import Odometry from geometry_msgs.msg import Twist, Point, Quaternion, TransformStamped from tf.broadcaster import TransformBroadcaster from tf.transformations import quaternion_from_euler from sensor_msgs.msg import JointState # 假设我们通过JointState消息获取轮子速度 class MecanumOdom: def __init__(self): rospy.init_node('mecanum_odom') # 参数:轮子半径,半轴距lx, ly self.wheel_radius = rospy.get_param('~wheel_radius', 0.05) self.lx = rospy.get_param('~lx', 0.1) # 轮子中心到机器人中心在x方向的距离(米) self.ly = rospy.get_param('~ly', 0.1) # 轮子中心到机器人中心在y方向的距离(米) # 初始化变量 self.x = 0.0 self.y = 0.0 self.theta = 0.0 self.last_time = rospy.Time.now() # 订阅四个轮子的速度(假设通过JointState发布,名字分别为:front_left_wheel_joint, front_right_wheel_joint, rear_left_wheel_joint, rear_right_wheel_joint) rospy.Subscriber('wheel_velocities', JointState, self.vel_callback) # 发布odom消息 self.odom_pub = rospy.Publisher('odom', Odometry, queue_size=10) self.odom_broadcaster = TransformBroadcaster() def vel_callback(self, msg): current_time = rospy.Time.now() dt = (current_time - self.last_time).to_sec() if dt < 0.0001: return # 从JointState消息中获取四个轮子的速度(角速度,单位rad/s) # 注意:JointState消息中速度的顺序需要与我们的轮子顺序对应 # 假设顺序为:[front_left, front_right, rear_left, rear_right] if len(msg.velocity) >= 4: w1 = msg.velocity[0] # front_left w2 = msg.velocity[1] # front_right w3 = msg.velocity[2] # rear_left w4 = msg.velocity[3] # rear_right # 根据运动学模型计算底盘的速度 vx = (w1 + w2 + w3 + w4) * self.wheel_radius / 4.0 vy = (-w1 + w2 + w3 - w4) * self.wheel_radius / 4.0 vth = (-w1 + w2 - w3 + w4) * self.wheel_radius / (4.0 * (self.lx + self.ly)) # 积分得到位置和航向 delta_x = (vx * math.cos(self.theta) - vy * math.sin(self.theta)) * dt delta_y = (vx * math.sin(self.theta) + vy * math.cos(self.theta)) * dt delta_th = vth * dt self.x += delta_x self.y += delta_y self.theta += delta_th # 创建四元数 odom_quat = quaternion_from_euler(0, 0, self.theta) # 发布TF变换(odom坐标系到base_link) transform = TransformStamped() transform.header.stamp = current_time transform.header.frame_id = "odom" transform.child_frame_id = "base_link" transform.transform.translation.x = self.x transform.transform.translation.y = self.y transform.transform.translation.z = 0.0 transform.transform.rotation = Quaternion(*odom_quat) self.odom_broadcaster.sendTransform(transform) # 发布Odometry消息 odom = Odometry() odom.header.stamp = current_time odom.header.frame_id = "odom" odom.child_frame_id = "base_link" odom.pose.pose.position = Point(self.x, self.y, 0) odom.pose.pose.orientation = Quaternion(*odom_quat) odom.twist.twist.linear.x = vx odom.twist.twist.linear.y = vy odom.twist.twist.angular.z = vth self.odom_pub.publish(odom) self.last_time = current_time if __name__ == '__main__': try: node = MecanumOdom() rospy.spin() except rospy.ROSInterruptException: pass ``` 注意:上述代码是一个简化版本,实际应用中需要考虑: - 编码器数据的获取方式(可能是通过CAN总线或其他接口,需要相应的驱动节点发布JointState消息) - 初始位置和方向的设置(可以通过参数服务器或初始消息) - 累积误差的处理(建议使用robot_localization包进行传感器融合) 6. 建图启动: 在启动gmapping或cartographer时,确保将odom数据作为输入之一。例如,在gmapping中,设置`use_sim_time`为false,并指定odom topic。 7. 使用robot_localization包进行传感器融合(可选): 如果除了轮式里程计还有IMU等传感器,我们可以使用robot_localization包来融合这些数据,得到更准确的odom数据。具体配置可以参考robot_localization的文档。 这样,我们就能够为麦克纳姆轮底盘提供odom数据,并用于建图。 引用说明: 在ROS中,TF变换用于处理坐标系之间的关系,而里程计数据是建图的重要输入之一。通过正确计算和发布odom到base_link的TF变换,建图算法可以跟踪机器人的运动轨迹[^1]。 §§相关问题§§ 1. 麦克纳姆轮底盘的运动学模型具体如何推导? 2. 在ROS中,除了使用自定义节点,还有哪些方法可以实现麦克纳姆轮底盘的里程计计算? 3. 如何减小麦克纳姆轮里程计的累积误差?</think>### 在ROS中修改运动模型支持四轮麦克纳姆轮底盘并集成odom数据 以下是实现步骤及相关技术细节: #### 1. **运动学模型配置** 麦克纳姆轮的运动模型与普通差速轮不同,需实现全向运动模型。核心公式: $$ \begin{bmatrix} v_x \\ v_y \\ \omega \end{bmatrix} = \frac{r}{4} \begin{bmatrix} 1 & 1 & 1 & 1 \\ -1 & 1 & 1 & -1 \\ -\frac{1}{l_x + l_y} & \frac{1}{l_x + l_y} & -\frac{1}{l_x + l_y} & \frac{1}{l_x + l_y} \end{bmatrix} \begin{bmatrix} \omega_1 \\ \omega_2 \\ \omega_3 \\ \omega_4 \end{bmatrix} $$ 其中: - $r$ = 轮半径 - $l_x, l_y$ = 轮间距 - $\omega_i$ = 各轮角速度 #### 2. **修改ROS控制节点** 在`robot_control`包中创建麦克纳姆轮驱动节点: ```python #!/usr/bin/env python3 import rospy from geometry_msgs.msg import Twist from sensor_msgs.msg import JointState class MecanumController: def __init__(self): rospy.init_node('mecanum_controller') self.cmd_vel_sub = rospy.Subscriber('/cmd_vel', Twist, self.vel_callback) self.joint_pub = rospy.Publisher('/joint_commands', JointState, queue_size=10) # 机械参数(需根据实际底盘修改) self.wheel_radius = 0.0762 # 米 self.lx = 0.2 # 前后轮距/2 self.ly = 0.15 # 左右轮距/2 def vel_callback(self, msg): # 从Twist消息转换到轮速 vx = msg.linear.x vy = msg.linear.y wz = msg.angular.z # 运动学逆解 w1 = (vx - vy - (self.lx+self.ly)*wz) / self.wheel_radius w2 = (vx + vy + (self.lx+self.ly)*wz) / self.wheel_radius w3 = (vx + vy - (self.lx+self.ly)*wz) / self.wheel_radius w4 = (vx - vy + (self.lx+self.ly)*wz) / self.wheel_radius # 发布关节命令 joint_cmd = JointState() joint_cmd.name = ["front_left_wheel", "front_right_wheel", "rear_left_wheel", "rear_right_wheel"] joint_cmd.velocity = [w1, w2, w3, w4] self.joint_pub.publish(joint_cmd) if __name__ == '__main__': MecanumController() rospy.spin() ``` #### 3. **集成odom数据** 在`odom_publisher`节点中实现里程计计算: ```cpp // 基于轮编码器数据计算odom void calculateOdometry(const sensor_msgs::JointState::ConstPtr& msg) { double dt = (current_time - last_time).toSec(); // 从运动学正解获取底盘速度 double w1 = msg->velocity[0]; // 单位: rad/s double w2 = msg->velocity[1]; double w3 = msg->velocity[2]; double w4 = msg->velocity[3]; double vx = wheel_radius * (w1 + w2 + w3 + w4) / 4.0; double vy = wheel_radius * (-w1 + w2 + w3 - w4) / 4.0; double wz = wheel_radius * (-w1 + w2 - w3 + w4) / (4.0 * (lx + ly)); // 积分得到位姿 double delta_x = (vx * cos(theta) - vy * sin(theta)) * dt; double delta_y = (vx * sin(theta) + vy * cos(theta)) * dt; double delta_th = wz * dt; x += delta_x; y += delta_y; theta += delta_th; // 发布Odometry消息和TF publishOdometry(vx, vy, wz); publishTF(); } ``` #### 4. **URDF模型配置** 在底盘URDF文件中正确定义轮关节和传动: ```xml <transmission name="front_left_trans"> <type>transmission_interface/SimpleTransmission</type> <joint name="front_left_wheel_joint"> <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface> </joint> <actuator name="front_left_motor"> <mechanicalReduction>1</mechanicalReduction> </actuator> </transmission> <!-- 为其余三个轮重复类似配置 --> ``` #### 5. **建图配置(以gmapping为例)** 在启动文件中配置odom坐标系: ```xml <launch> <node pkg="gmapping" type="slam_gmapping" name="slam"> <param name="odom_frame" value="odom"/> <param name="base_frame" value="base_link"/> <remap from="scan" to="/lidar/scan"/> </node> <!-- 发布odom->base_link的TF --> <node pkg="robot_localization" type="ekf_localization_node" name="ekf_odom"> <param name="odom0" value="/wheel_odom"/> <param name="imu0" value="/imu/data"/> <!-- 可选IMU融合 --> </node> </launch> ``` #### 6. **关键注意事项** 1. **TF树结构**:确保TF树遵循标准结构: ``` map → odom → base_link → sensor_frame ``` 其中`odom→base_link`由里程计节点发布[^1] 2. **误差补偿**: - 使用`robot_localization`包融合IMU数据 - 定期通过`amcl`进行位姿校正 - 配置运动学参数时考虑轮子打滑系数 3. **调试工具**: ```bash # 检查TF树 rosrun tf2_tools view_frames.py # 可视化odom数据 rosrun rqt_robot_steering rqt_robot_steering ``` 通过以上步骤,您的麦克纳姆轮底盘即可在ROS中发布准确的odom数据,支持SLAM建图任务。实际部署时需根据底盘尺寸调整运动学参数,并通过`rqt_reconfigure`实时优化控制参数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值