Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changing servo group construction #495

Open
greenpepper123 opened this issue Nov 15, 2021 · 0 comments
Open

Changing servo group construction #495

greenpepper123 opened this issue Nov 15, 2021 · 0 comments

Comments

@greenpepper123
Copy link
Collaborator

Servo parameters and pub/subs are formed by servo groups and each group is top-level namespace for now (i.e. parent or root doesn't exist).

https://github.com/JSKAerialRobot/aerial_robot/blob/master/robots/hydrus_xi/config/quad/Servo.yaml
https://github.com/JSKAerialRobot/aerial_robot/blob/master/aerial_robot_model/src/servo_bridge/servo_bridge.cpp

This causes subscribers of the groups to be registered separately, even if topic names are the same.
It had not been the actual problem up until now, because only joint servos are set to be send_data_flag = True.

Now we started to let all joints to return the data.
If we don't change the code and write the config like this,

servo_controller:
  joints:
    state_sub_topic: servo/states
  gimbals:
    state_sub_topic: servo/states

then the same two callback for joints and gimbals are called when a new servo/states comes in.

I tried it and at first it worked correctly, but sometimes aerial_robot_base_node crashed (SEGFAULT).
Then I launched aerial_robot_base_node with gdb.
I found out that double-free and something similar happens in the callback.

#0  0x00007ffff5895f55 in _int_free (av=0x7fffbc000020, p=<optimized out>, have_lock=0) at malloc.c:4012
#1  0x00007ffff589a58c in __GI___libc_free (mem=<optimized out>) at malloc.c:2975
#2  0x00007ffff50fe1eb in void Eigen::internal::call_assignment_no_alias<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::internal::assign_op<double
> >(Eigen::Matrix<double, -1, -1, 0, -1, -1>&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::internal::assign_op<double> const&) () from /opt/ros/kinetic/lib/liborocos-kdl.so.1.3
#3  0x00007fffe679cdc3 in Eigen::internal::call_assignment<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::internal::assign_op<double> >(Eigen::Mat
rix<double, -1, -1, 0, -1, -1>&, Eigen::Matrix<double, -1, -1, 0, -1, -1> const&, Eigen::internal::assign_op<double> const&, Eigen::internal::enable_if<!Eigen::internal::evaluator_assume_ali
asing<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::internal::evaluator_traits<Eigen::Matrix<double, -1, -1, 0, -1, -1> >::Shape>::value, void*>::type) (func=..., src=...,
    dst=...) at /usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:712
#4  Eigen::internal::call_assignment<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1> > (src=...,
    dst=...) at /usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:693
#5  Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >::_set<Eigen::Matrix<double, -1, -1, 0, -1, -1> > (other=...,
    this=0x755320) at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:682
#6  Eigen::Matrix<double, -1, -1, 0, -1, -1>::operator= (other=..., this=0x755320) at /usr/include/eigen3/Eigen/src/Core/Matrix.h:208
#7  aerial_robot_model::RobotModel::setThrustWrenchMatrix (q_mat=..., this=0x754c80)
    at /home/leus/ros/aerial_robot_ws/src/aerial_robot/aerial_robot_model/include/aerial_robot_model/transformable_aerial_robot_model.h:347
#8  HydrusRobotModel::calcWrenchMatrixOnRoot (this=0x754c80)
    at /home/leus/ros/aerial_robot_ws/src/aerial_robot/robots/hydrus/src/hydrus_robot_model.cpp:103
#9  0x00007fffe67c43c7 in HydrusTiltedRobotModel::calcStaticThrust (this=0x754c80)
    at /home/leus/ros/aerial_robot_ws/src/aerial_robot/robots/hydrus/src/hydrus_tilted_robot_model.cpp:10
#10 0x00007ffff0733594 in aerial_robot_model::RobotModel::updateRobotModelImpl (this=this@entry=0x754c80, joint_positions=...)
    at /home/leus/ros/aerial_robot_ws/src/aerial_robot/aerial_robot_model/src/transformable_aerial_robot_model/robot_model.cpp:130
#11 0x00007fffe67c2ae5 in HydrusTiltedRobotModel::updateRobotModelImpl (this=0x754c80, joint_positions=...)
    at /home/leus/ros/aerial_robot_ws/src/aerial_robot/robots/hydrus/src/hydrus_tilted_robot_model.cpp:89
#12 0x00007ffff2cebb15 in aerial_robot_model::RobotModel::updateRobotModel (joint_positions=..., this=0x754c80)
    at /home/leus/ros/aerial_robot_ws/src/aerial_robot/aerial_robot_model/include/aerial_robot_model/transformable_aerial_robot_model.h:70
#13 aerial_robot_model::RobotModel::updateRobotModel (state=..., this=0x754c80)
    at /home/leus/ros/aerial_robot_ws/src/aerial_robot/aerial_robot_model/include/aerial_robot_model/transformable_aerial_robot_model.h:71
#14 aerial_robot_model::RobotModelRos::jointStateCallback (this=0xa13ac0, state=...)
    at /home/leus/ros/aerial_robot_ws/src/aerial_robot/aerial_robot_model/src/transformable_aerial_robot_model/robot_model_ros.cpp:41
#15 0x00007ffff2cf246e in boost::function1<void, boost::shared_ptr<sensor_msgs::JointState_<std::allocator<void> > const> const&>::operator() (a0=..., this=<optimized out>) at /usr/include/b
oost/function/function_template.hpp:773
#16 boost::detail::function::void_function_obj_invoker1<boost::function<void (boost::shared_ptr<sensor_msgs::JointState_<std::allocator<void> > const> const&)>, void, boost::shared_ptr<senso
r_msgs::JointState_<std::allocator<void> > const> >::invoke(boost::detail::function::function_buffer&, boost::shared_ptr<sensor_msgs::JointState_<std::allocator<void> > const>) (function_obj
_ptr=..., a0=...)
    at /usr/include/boost/function/function_template.hpp:159
#17 0x00007ffff2cffe32 in boost::function1<void, boost::shared_ptr<sensor_msgs::JointState_<std::allocator<void> > const> >::operator() (

jointStateCallback is called twice when a servo/states comes in because it is double-registered by joints and gimbals, and then it violated the multi-thread rule.

Actually, it happens even when I unsubscribed servo/states for gimbals (as usual), but the frequency of it is much higher when I double-subbed.
It is natural because the program is writing to the same object in the robot model from another thread in navigation without any mutex, but the frequency of SEGFAULT is greatly increased by double-register.

Is it blamed to the servo group implementation or not?

Possible solution: Create the parent of servo groups and put it to top-level. Write the common parameters to parent namespace and pub/subs are registered once as the parent-level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant