qcoding

[Ros Web] rosapi를 활용한 Topic /Node List 받아오기 #3 본문

Ros

[Ros Web] rosapi를 활용한 Topic /Node List 받아오기 #3

Qcoding 2022. 5. 13. 11:22
반응형

* 이 글에서는 ROS INTERFACE 생성 시 현재 사용중인 Topic 과 None 등 여러 정보를 받아오는 방법에 대해서 정리하였다. 현재는 Topic 과 Node만 받아왔지만 필요에 따라서 공식문서를 보면서 추가할 수 있다.

http://docs.ros.org/en/melodic/api/rosapi/html/index-msg.html

 

rosapi Msg/Srv Documentation

 

docs.ros.org

 

1) 구조

-> ROS Service를 이용하여, JSON 형태로 원하는 정보를 받아오는 구조를 띈다.

1-1) ros service

// Topic Service 생성
var topicsClient = new ROSLIB.Service({
    ros : ros,
    name : '/rosapi/topics',
    serviceType : 'rosapi/Topics'
});

// Node Service 생성
var NodeClient = new ROSLIB.Service({
    ros : ros,
    name : '/rosapi/nodes',
    serviceType : 'rosapi/nodes'
});

1-2) Service request 생성 및 callback 등록

// 받은 정보를 담을 array 생성
  let received_topic_list=[]
  let received_node_list=[]
    
 // Topic  
var request = new ROSLIB.ServiceRequest();

topicsClient.callService(request, function(result) {
console.log("Getting topics...");

    // reulst shape 
    // string[] topics / string[] types
    // http://docs.ros.org/en/melodic/api/rosapi/html/srv/Topics.html
    received_topic_list.push(result)
});


//Node
var request = new ROSLIB.ServiceRequest();

NodeClient.callService(request, function(result) {
    console.log("Getting nodes...");
    // reulst shape 
    // string[] publishers
    // http://docs.ros.org/en/melodic/api/rosapi/html/srv/Publishers.html
    received_node_list.push(result)
});

 

2) 받아온 정보를 UI 형태로 변경하기 위한 함수

--> 위에서 callService를 통해 받은 JSON 형태의 자료를 각각 received_topic_list / received_node_list 에 담아 두었으므로, 형태에 맞게 각각의 자료를 사용하면 된다. 이 때 HTML 에 표시 된 자리에 추가하여 넣기 위하여 h1으로 된 listComponent를 생성하고 list아래에 계속 추가하였다. 

  //Topic
  // get srv msg
  let topic_list=getTopics();

  //set the topic list
  const setTopicList=(topiclist)=>{

  for (let i=0;i<topiclist.topics.length;i++){
    let topic=topiclist.topics[i]
    let type=topiclist.types[i]

    document.getElementById("topic_list_length").innerHTML=`${topiclist.topics.length} topics`
    let list = document.getElementById("topic_list");
    let listCoponent = document.createElement('h1');
    listCoponent.innerHTML=`Topic : ${topic}  ,   Type : ${type}`
    list.appendChild(listCoponent)
  }
}

//Node
  let nodeList=getNodes();

    //set the topic list
    const setPubList=(nodeList)=>{

      for (let i=0;i<nodeList.nodes.length;i++){
        let node=nodeList.nodes[i]
    
        document.getElementById("node_list_length").innerHTML=`${nodeList.nodes.length} Nodes`
        let list = document.getElementById("node_list");
        let listCoponent = document.createElement('h1');
        listCoponent.innerHTML=`Node : ${node}`
        list.appendChild(listCoponent)
        
      }
    
    }

HTML 코드

  <p>Topic list:<h1 id="topic_list_length"></h1> <h1 id="topic_list"></h1></p>
  <p>Node list:<h1 id="node_list_length"></h1> <h1 id="node_list"></h1></p>

 

전체코드

-> callback 되어 오는 정보를 받기 위해서 setTImeout 함수를 썻는 데, 좋은 방법은 아닌 것 같다. 보통은 정보를 받아올 때 Promise나 aync - await로 비동기 처리를 해줘야 하는 데 현재는 간단하게 만들기 위해서 setTimeout을 사용하였다. 정보를 Feching 후 promise를 받아와서 처리하는 것이 정확한 것으로 추후에 변경예정이다.

 

  // srv array
  let received_topic_list=[]
  let received_node_list=[]

  /////////////////////////////// Get Publisher list
  const getNodes=()=>{
    var NodeClient = new ROSLIB.Service({
    ros : ros,
    name : '/rosapi/nodes',
    serviceType : 'rosapi/nodes'
    });

    var request = new ROSLIB.ServiceRequest();

    NodeClient.callService(request, function(result) {
    console.log("Getting nodes...");
    // reulst shape 
    // string[] publishers
    // http://docs.ros.org/en/melodic/api/rosapi/html/srv/Publishers.html
    received_node_list.push(result)
    });

    return received_node_list
};

  let nodeList=getNodes();

    //set the topic list
    const setPubList=(nodeList)=>{

      for (let i=0;i<nodeList.nodes.length;i++){
        let node=nodeList.nodes[i]
    
        document.getElementById("node_list_length").innerHTML=`${nodeList.nodes.length} Nodes`
        let list = document.getElementById("node_list");
        let listCoponent = document.createElement('h1');
        listCoponent.innerHTML=`Node : ${node}`
        list.appendChild(listCoponent)
        
      }
    
    }

  
  ////////////////////////// Get Topic list
  const getTopics=()=>{
    var topicsClient = new ROSLIB.Service({
    ros : ros,
    name : '/rosapi/topics',
    serviceType : 'rosapi/Topics'
    });

    var request = new ROSLIB.ServiceRequest();

    topicsClient.callService(request, function(result) {
    console.log("Getting topics...");

    // reulst shape 
    // string[] topics / string[] types
    // http://docs.ros.org/en/melodic/api/rosapi/html/srv/Topics.html
    received_topic_list.push(result)
    });

    return received_topic_list
};
  // get srv msg
  let topic_list=getTopics();

  //set the topic list
  const setTopicList=(topiclist)=>{

  for (let i=0;i<topiclist.topics.length;i++){
    let topic=topiclist.topics[i]
    let type=topiclist.types[i]

    document.getElementById("topic_list_length").innerHTML=`${topiclist.topics.length} topics`
    let list = document.getElementById("topic_list");
    let listCoponent = document.createElement('h1');
    listCoponent.innerHTML=`Topic : ${topic}  ,   Type : ${type}`
    list.appendChild(listCoponent)
    
  }

}

setTimeout(()=>{

    setTopicList(topic_list[0])
    setPubList(nodeList[0])

},2000)

정보를 받아온 화면

반응형
Comments