RobotWebTools / roslibjs

The Standard ROS JavaScript Library
https://robotwebtools.github.io/roslibjs
Other
673 stars 378 forks source link

Ros2 Actions are not working for me with ROSLIBJS (app crashed) #782

Closed dineshHarikrishnan closed 4 days ago

dineshHarikrishnan commented 6 days ago

Description I am using ROSLIBJS for ROS2 actions I have referrred your examples also.

Steps To Reproduce

const navigateToPose = (x, y, res) => {

  // Create an action client
  const actionClient = new ROSLIB.Action({
    ros: ros,
    name: "/navigate_to_pose", // Action topic name
    actionType: "nav2_msgs/action/NavigateToPose", // Action message type
  });

  // Define the goal message
  const goal = {
    pose: {
      header: {
        frame_id: "map", // Replace with your desired frame ID
        stamp: {sec: 0, nanosec:0 },
      },
      pose: {
        position: { x: x, y: y, z: 0.0 },
        orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 },
      },
    },
    behavior_tree: "", // Adjust as needed
  };

  // Set up event listeners
  actionClient.on("feedback", (feedback) => {
    console.log("Received feedback:", feedback);
  });

  actionClient.on("result", (result) => {
    console.log("Goal completed with result:", result);
    res.send(result);
  });

  actionClient.on("status", (status) => {
    console.log("Current goal status:", status);
  });

  // Send the goal
  actionClient.sendGoal(goal);

  console.log("Goal sending...");
  res.status(200).send("Goal sending...."); 

  // Return a function to cancel the goal
  return () => {
    actionClient.cancel();
    console.log("Navigation goal cancelled");
  };
};

Actual Behavior

/home/dinesh/webapp/server/controllers/ros2Controller.js:168
  const actionClient = new ROSLIB.Action({
                       ^

TypeError: ROSLIB.Action is not a constructor
    at navigateToPose (/home/dinesh/_webapp/server/controllers/ros2Controller.js:168:24)
    at /home/dinesh/_webapp/server/controllers/ros2Controller.js:153:11
    at RosTCP.<anonymous> (/home/dinesh/_webapp/server/node_modules/roslib/src/core/Service.js:53:9)
    at RosTCP.listener (/home/dinesh/_webapp/server/node_modules/eventemitter2/lib/eventemitter2.js:931:17)
    at EventEmitter.emit (/home/dinesh/_webapp/server/node_modules/eventemitter2/lib/eventemitter2.js:1011:19)
    at handleMessage (/home/dinesh/_webapp/server/node_modules/roslib/src/core/SocketAdapter.js:38:14)
    at handlePng (/home/dinesh/_webapp/server/node_modules/roslib/src/core/SocketAdapter.js:54:7)
    at WebSocket.onMessage (/home/dinesh/_webapp/server/node_modules/roslib/src/core/SocketAdapter.js:125:9)
    at callListener (/home/dinesh/_webapp/server/node_modules/ws/lib/event-target.js:290:14)
    at WebSocket.onMessage (/home/dinesh/_webapp/server/node_modules/ws/lib/event-target.js:209:9)

Node.js v18.20.4 [nodemon] app crashed - waiting for file changes before starting...

When I tried with Ros1 classes the app doesnt crashed but the actionCall doesnt happening.

const navigateToPose = (x, y, res) => {
  // Ensure that ros is connected (assuming ros is initialized earlier)
  if (!ros.isConnected) {
    console.error("ROS is not connected!");
    return;
  }

  // Create an action client for NavigateToPose
  const actionClient = new ROSLIB.ActionClient({
    ros: ros,
    serverName: "/navigate_to_pose",
    actionName: "nav2_msgs/action/NavigateToPose",
  });

  // Define the goal
  const goal = new ROSLIB.Goal({
    actionClient: actionClient,
    goalMessage: {
      pose: {
        header: {
          frame_id: '',
          stamp: { sec: 0, nanosec: 0 }, // You might need to set the actual time
        },
        pose: {
          position: { x: x, y: y, z: 0.0 },
          orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 },
        },
      },
      behaviourtree:''
    },
  });

  // Set up feedback handler
  goal.on("feedback", function (feedback) {
    console.log("Received feedback:", feedback);
  });

  // Set up result handler
  goal.on("result", function (result) {
    console.log("Goal completed with result:", result);
    // res.send(result); // If you need to return the result somewhere
  });

  // Set up status handler
  goal.on("status", function (status) {
    console.log("Current goal status:", status);
  });

  // Send the goal
  goal.send();

  console.log("Goal sending...");
  res.send("Goal sending..."); 

  // Provide method to cancel the goal if needed
  const cancelNavigation = () => {
    goal.cancel();
    console.log("Navigation goal cancelled");
  };

  // Return the cancel function, allowing the caller to cancel if needed
  return cancelNavigation;
};
rosbridge_websocket-1] [ERROR] [1726044476.264745137] [rosbridge_websocket]: [Client 6d47382f-0cc2-4371-b251-b5475b9dadc2] [id: advertise:/navigate_to_pose/goal:4] advertise: Unable to import msg class NavigateToPoseGoal from package nav2_msgs. Caused by module 'nav2_msgs.msg' has no attribute 'NavigateToPoseGoal'
[rosbridge_websocket-1] [INFO] [1726044477.065377367] [rosbridge_websocket]: [Client 6d47382f-0cc2-4371-b251-b5475b9dadc2] Subscribed to /navigate_to_pose/status
[rosbridge_websocket-1] [ERROR] [1726044477.074187079] [rosbridge_websocket]: [Client 6d47382f-0cc2-4371-b251-b5475b9dadc2] [id: subscribe:/navigate_to_pose/feedback:7] subscribe: Unable to import msg class NavigateToPoseFeedback from package nav2_msgs. Caused by module 'nav2_msgs.msg' has no attribute 'NavigateToPoseFeedback'
[rosbridge_websocket-1] [ERROR] [1726044477.178373522] [rosbridge_websocket]: [Client 6d47382f-0cc2-4371-b251-b5475b9dadc2] [id: subscribe:/navigate_to_pose/result:8] subscribe: Unable to import msg class NavigateToPoseResult from package nav2_msgs. Caused by module 'nav2_msgs.msg' has no attribute 'NavigateToPoseResult'
[rosbridge_websocket-1] [ERROR] [1726044477.229978720] [rosbridge_websocket]: [Client 6d47382f-0cc2-4371-b251-b5475b9dadc2] [id: publish:/navigate_to_pose/goal:9] publish: Cannot infer topic type for topic /navigate_to_pose/goal as it is not yet advertised
dineshHarikrishnan commented 6 days ago

Any Immediate fix for this?

MatthijsBurgh commented 6 days ago

ROS2 action support is not in a relaeased version yet. You will need to build from source to use this feature. As you may have seen everything related to the ROS2 action is tagged with v2. And you can also see this is not released yet.

dineshHarikrishnan commented 5 days ago

I have tried building from source like installing the ros2-actions-no-typescript branch roslib because it only has support to ros2-action-client I have used ros2 action classes only but still I am facing issues I am using expressJS backend and roslibjs

"roslib": "github:RobotWebTools/roslibjs#ros2-actions-no-typescript" 

Also I have cloned this version of rosbridge_suite

git clone https://github.com/RobotWebTools/rosbridge_suite.git -b humble 

code snippet

const navigateToPose = (x, y, res) => {
  //Create an action client
  var actionClient = new ROSLIB.Action({
    ros: ros,
    name: "/navigate_to_pose",
    actionType: "nav2_msgs/action/NavigateToPose",
  });

  //Goal message for navigateToPose
  var goal = new ROSLIB.ActionGoal({
    goalMessage: {
      goal: {
        // Add the goal field here
        pose: {
          header: {
            frame_id: "map",
            stamp: {
              sec: Date.now(), // You can set the actual timestamp here
              // nanosec: Date.now(), // You can set the actual timestamp here
            },
          },
          pose: {
            position: { x: x, y: y, z: 0.0 },
            orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 },
          },
        },
        behavior_tree: "",
      },
    },
  });
  console.log(goal);
  // console.log(goal.pose.pose.position);
  var goal_id = actionClient.sendGoal(
    goal,
    (result) => {
      console.log("Result for action goal:", result.result.sequence);
      res.status(200).send(result.result.sequence);
    },
    (feedback) => {
      console.log(
        "Feedback for action on " +
          actionClient.name +
          ": " +
          feedback.partial_sequence
      );
    }
  );
  console.log("Goal sent with ID: ", goal_id);
  res.send("Goal sending...");
};

Error Message

[rosbridge_websocket-1] [ERROR] [1726144153.273787272] [rosbridge_websocket]: [Client 401053d3-55c4-4472-a823-9e5061e8321a] send_action_goal NonexistentFieldException: send_action_goal:/navigate_to_pose:4
Tomaslapes commented 5 days ago

ROS2 action support is not in a relaeased version yet. You will need to build from source to use this feature. As you may have seen everything related to the ROS2 action is tagged with v2. And you can also see this is not released yet.

Oh no I just stumbled on this. I saw you in this issue: https://github.com/RobotWebTools/roslibjs/issues/646 show how to install a different branch:

pnpm install roslib@github:RobotWebTools/roslibjs#ros2-actions-no-typescript

Which branch would be ideal if I need ROS2? Is this the one? Also would you consider it stable enough to be used or is it still some highly WIP thing. UPDATE: I tried installing this branch and so far I didnt notice any problems. I only need to use actions and services so if that works I guess this will work. Thank you!