Couldn't control the speed in Odrive in teleop

Hi i create my own code for a robot but it is my first time using the OdriveS1 , I created the low level controller for OdriveS1 to run but there is a mistake about i couldn’t increase or decrease the velocity in teleop while driving it take the same velocity(0.03) for the whole process when i reduce certain amount of velocity the both wheel is stopped when it done where can i have to check the code for adjust the velocity to drive using teleop in keypad.

this is for ros2 cpp file

Thank you

Hi! Can you post your code?

#include “lower_level_controller/LowerLevelInterface.hpp”

/**

  • @brief LowerLevelInterface Constructor
    */
    bool prev_estop=false;
    int prev_selectsw=0;

LowerLevelInterface::LowerLevelInterface()
{
rclcpp::init(0,nullptr);
p_node =rclcpp::Node::make_shared(“lower_level_controller”);
p_odrive_1 = new ODrive(“/dev/ttyACM0”);
p_odrive_2 = new ODrive(“/dev/ttyACM1”);
p_getVariables = new RosClass(p_node);
p_lowerLevelComputation = new LowerLevelComputations(p_node);

m_lastTime = m_currentTime = millis();


p_node->get_parameter("publish_tf",m_publishTF);
m_publishTF=1;

}

/**

  • @brief LowerLevelInterface distructor
    */

LowerLevelInterface::~LowerLevelInterface()
{

delete p_getVariables;
}
/**

  • @brief Entire control flow for the LowerLevelInterface
    */
    void LowerLevelInterface::controlFlow()
    {
    //std::cout<<“in control flow”<<std::endl;
    m_currentTime = millis();
    m_deltaTime = m_currentTime - m_lastTime;

    bool estop;
    int ret;
    int selectswitch;

    // battery_voltage

    geometry_msgs::msg::Twist cmdVel = p_getVariables->getCommandVelocity();

    estop=p_getVariables->getEstop();
    selectswitch=p_getVariables->getSelectsw();
    if(prev_estop!= estop)
    {
    if(!estop)
    {
    RCLCPP_WARN(rclcpp::get_logger(“lower_level_controller”),“Estop Released” );
    // ret=p_modbusRTU->eStophandler();
    }
    prev_estop=estop;
    }

    if(prev_selectsw != selectswitch)
    {
    if(selectswitch==0)
    {
    RCLCPP_WARN(rclcpp::get_logger(“lower_level_controller”),“Selection switch state changed” );
    // ret=p_modbusRTU->eStophandler();
    }
    prev_selectsw=selectswitch;
    }

    p_lowerLevelComputation->computation(cmdVel);
    float left_vel = p_lowerLevelComputation->m_leftRPS;
    float right_vel = p_lowerLevelComputation->m_rightRPS;
    p_odrive_1->setVelocity(0,(-left_vel));
    p_odrive_2->setVelocity(0,right_vel);
    od_1=p_odrive_1->getPosition_Velocity(0);
    od_2=p_odrive_2->getPosition_Velocity(0);
    std::cout<<“odom 1”<<od_1.first<<std::endl;
    std::cout<<“odom 2”<<od_2.first<<std::endl;
    p_lowerLevelComputation->updateOdometry(m_deltaTime,od_1.first,od_2.first,m_odom);
    p_getVariables->sendOdometry(m_odom);

    if(m_publishTF==1)
    {
    p_getVariables->updateTF(m_odom);
    }
    m_lastTime = m_currentTime;

}

rclcpp::Node::SharedPtr LowerLevelInterface::getNode()
{
return p_node;
}

/**

  • @brief Computes time in millis
  • @returns time in millis based on system clock
    */
    uint64_t LowerLevelInterface::millis()
    {
    uint64_t ms =std::chrono::duration_caststd::chrono::milliseconds(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
    return ms;
    }

/**

  • @brief Entire control flow for the LowerLevelInterface
    */

int main(int argc, char * argv)
{
LowerLevelInterface lowerlevelcontroller;
auto node=lowerlevelcontroller.getNode();

rclcpp::Rate rate(60);

while (rclcpp::ok())
{

rclcpp::spin_some(node);
lowerlevelcontroller.controlFlow();
rate.sleep();

}

rclcpp::shutdown();
return 0;

What ODrive library are you using for this? I’m not familiar of one designed for a Linux environment that uses UART. Maybe this is an issue with conversion from floating point numbers to ASCII. Have you verified you’re actually sending the correct velocity setpoints to the ODrive?

We have a first-party ROS2 node that works over CAN, maybe that would be easier? GitHub - odriverobotics/ros_odrive