Android 与ROS机器人交互APP开发笔记(二)-地图数据订阅

上篇笔记记录了如何使用RosBridge连接Ros机器人,这篇主要记录话题的订阅。本想地图数据订阅和绘制slam地图一起放上来,但绘制地图代码块有点多,就放在下一篇,仅放置绘制的slam地图。

话题订阅

关于Ros话题(Topic)的发布与订阅概述或者介绍不多描述。知道Ros机器人端发布话题,Android端通过订阅这个话题来获取数据,并且数据是以JSON格式进行传递就OK了。

  /**
     * 获取地图数据 的话题订阅
     */
    public void subscribeGetMapDataTopic() {
        MessageHandler<OccupancyGrid> handler =new MessageHandler<OccupancyGrid>() {
            @Override
            public void onMessage(OccupancyGrid message) {
                if (message != null) {
                    occupancyGrid = message;
                }
            }
        };
        // "/map"代表话题名称,双方约定好。
        Topic<OccupancyGrid> mapDateTopic = new Topic<>("/map", OccupancyGrid.class, client);
        mapDateTopic.subscribe(handler);
    }

OccupancyGrid 地图数据类,

public class OccupancyGrid extends Message {
    /**
     * 时间戳信息
     */
    public Header header;
    /**
     *地图的一些基本信息,宽高、分辨率
     */
    public MapMetaData info;
    /**
     * 地图数据
     */
    public byte[] data;

}

Topic类封装了话题订阅、取消订阅及数据 回调方法

public class Topic<T extends Message> extends LinkedBlockingQueue<T> implements FullMessageHandler {
    protected String topic;
    private Class<? extends T> type;
    private String messageType;
    private ROSClient client;
    private Thread handlerThread;
    
    public Topic(String topic, Class<? extends T> type, ROSClient client) {
        this.topic = topic;
        this.client = client;
        this.type = type;
        messageType = Message.getMessageType(type);
        handlerThread = null;
    }
    
    @Override
    public void onMessage(String id, Message message) {
        add((T) message);
    }
    
    
    // warning: there is a delay between the completion of this method and 
    //          the completion of the subscription; it takes longer than
    //          publishing multiple other messages, for example.    
    public void subscribe(MessageHandler<T> handler) {
        startRunner(handler);
        subscribe();
    }
    
    public void subscribe() {
        client.register(Publish.class, topic, type, this);
        send(new Subscribe(topic, messageType));
    }
    
    public void unsubscribe() {
        // need to handle race conditions in incoming message handler
        //    so that once unsubscribe has happened the handler gets no more
        //    messages
        send(new Unsubscribe(topic));        
        client.unregister(Publish.class, topic);
        stopRunner();
    }
    
    private void startRunner(MessageHandler<T> handler) {
        stopRunner();
        handlerThread = new Thread(new MessageRunner(handler));
        handlerThread.setName("Message handler for " + topic);
        handlerThread.start();
    }
    
    private void stopRunner() {
        if (handlerThread != null) {
            handlerThread.interrupt();
            clear();
            handlerThread = null;
        }
    }
    
    
    public void advertise() {
        send(new Advertise(topic, messageType));
    }
    
    public void publish(T message) {
        advertise();
        send(new Publish(topic, message));
        unadvertise();
    }
    
    public void unadvertise() {
        send(new Unadvertise(topic));
    }
    
    private void send(Operation operation) {
        client.send(operation);
    }
    
    public void verify() throws InterruptedException {

        boolean hasTopic = false;
        for (String s : client.getTopics()) {
            if (s.equals(topic)) {
                hasTopic = true;
                break;
            }
        }
        if (!hasTopic)
            throw new RuntimeException("Topic \'" + topic + "\' not available.");
        
        client.typeMatch(client.getTopicMessageDetails(topic), type);
    }
    
    private class MessageRunner implements Runnable {
        private MessageHandler<T> handler;

        public MessageRunner(MessageHandler<T> handler) {
            this.handler = handler;
        }             
        
        @Override
        public void run() {
            while (!Thread.interrupted()) {
                try {
                    handler.onMessage(take());
                }
                catch (InterruptedException ex) {
                    break;
                }
            }
        }
    }
    
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值