Package org.ros.poark

Source Code of org.ros.poark.PoarkClient

/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

package org.ros.poark;

import java.util.Collection;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

import org.ros.exception.ParameterNotFoundException;
import org.ros.message.MessageListener;
import org.ros.message.std_msgs.UInt16MultiArray;
import org.ros.message.std_msgs.UInt8MultiArray;
import org.ros.node.Node;
import org.ros.node.topic.Publisher;
import org.ros.poark.Poark;
import org.ros.poark.PinChangeListener;

/**
* This class wraps Poark messages in easy to use high level interface.
*
* @author pastarmovj@google.com (Julian Pastarmov)
*/
public class PoarkClient {

  private final int kMaxI2CDataLength = 10;

  private class PoarkPinsMessageListener implements MessageListener<UInt16MultiArray> {
    public Multimap<Byte, PinChangeListener> pinsListenerClients =
        HashMultimap.create();

    /**
     * Implements the pins listener and delegates messages to the registered
     * PinChangeLister objects.
     */
    @Override
    public void onNewMessage(UInt16MultiArray message) {
      Collection<PinChangeListener> globalListeners =
          pinsListenerClients.get((byte)-1);
      for (int i = 0;i < message.data.length / 2;++i) {
        // First notify all global listeners.
        for (PinChangeListener entry : globalListeners)
          entry.onPinStateChange((byte)message.data[i*2], message.data[i*2 + 1]);
        // Then all that are registered for this particular pin.
        for (PinChangeListener entry :
             pinsListenerClients.get((byte)message.data[i*2])) {
          entry.onPinStateChange((byte)message.data[i*2], message.data[i*2 + 1]);
        }
      }
    }
  }

  private class PoarkI2CMessageListener implements MessageListener<UInt8MultiArray> {
    public Multimap<Byte, I2CResponseListener> listenerClients =
      HashMultimap.create();

    /**
     * Implements the pins listener and delegates messages to the registered
     * PinChangeLister objects.
     */
    @Override
    public void onNewMessage(UInt8MultiArray message) {
      byte[] data = new byte[message.data.length - 2];
      System.arraycopy(message.data, 2, data, 0, data.length);
      for (I2CResponseListener entry : listenerClients.get((byte)-1))
        entry.onI2CResponse(message.data[0], message.data[1], data);
      // Then all that are registered for this particular address.
      for (I2CResponseListener entry : listenerClients.get(message.data[0]))
        entry.onI2CResponse(message.data[0], message.data[1], data);
    }
  }

  private Poark.BoardLayout layout;
  private Publisher<UInt8MultiArray> setPinStatePub;
  private Publisher<UInt8MultiArray> setPinsPub;
  private Publisher<UInt8MultiArray> i2cIoPub;
  private PoarkPinsMessageListener pinsListener = new PoarkPinsMessageListener();
  private PoarkI2CMessageListener i2cListener = new PoarkI2CMessageListener();
  /**
   * Contructs a PoarkClient instance.
   *
   * @param layout - The layout of the board to talk to.
   */
  public PoarkClient(Poark.BoardLayout layout, Node node) {
    this.layout = layout;
    setPinStatePub =
        node.newPublisher("set_pins_state", "std_msgs/UInt8MultiArray");
    setPinsPub =
        node.newPublisher("set_pins", "std_msgs/UInt8MultiArray");
    i2cIoPub =
      node.newPublisher("i2c_io", "std_msgs/UInt8MultiArray");
    node.newSubscriber("pins", "std_msgs/UInt16MultiArray", pinsListener);
    node.newSubscriber("i2c_response", "std_msgs/UInt8MultiArray", i2cListener);
  }

  /**
   * Adds a new pin listener for a specific pin or for all pins. Note that one listener
   * can be registered multiple times for different pins or that one listener can be used
   * for all pins at the same time.
   * {@linktourl http://code.google.com/p/poark/wiki/HowToUse#pins}
   * @param pin The pin number. If -1 is specified will listen to all pins.
   * @param listener The listener object.
   * @return True if the listener has been successfully added.
   */
  public boolean addPinChangeListener(byte pin, PinChangeListener listener) {
    return pinsListener.pinsListenerClients.put(pin, listener);
  }

  /**
   * Removes a listener.
   * @param pin The pin this listener was registered for.
   * @param listener The listener object to be removed.
   * @return True if the listener has been successfully removed.
   */
  public boolean removePinChangeListener(byte pin, PinChangeListener listener) {
    return pinsListener.pinsListenerClients.remove(pin, listener);
  }

  /**
   * Sends a set_pins_state message. See the Poark's documentation for
   * more information regarding the set_pins_state message
   * {@linktourl http://code.google.com/p/poark/wiki/HowToUse#set_pins_state}.
   *
   * @param pin - the pin to be set.
   * @param mode - pin mode can be OUT, IN, ANALOG, ANALOG_FILTERED, PWM_MODE, SERVO or
   * NONE.
   * @param state - the initial pin state depends on the pin mode.
   */
  public void setPinMode(byte pin, byte mode, byte initial_state) {
    UInt8MultiArray pinsModes = new UInt8MultiArray();
    Poark.createPinMode(pinsModes, pin, mode, initial_state);
    setPinStatePub.publish(pinsModes);
  }

  /**
   * The same as @SetPinMode but accept an array of pins to set with a single ROS message.
   * @param pins array of pin indexes to set
   * @param modes array of modes indexes to set
   * @param initialStates array of initial states to set
   * @throws IllegalArgumentException if the arrays have mismatching lengths.
   */
  public void setPinsMode(
      byte[] pins, byte[] modes, byte[] initialStates) throws IllegalArgumentException {
    if (pins.length != modes.length || pins.length != initialStates.length)
      throw new IllegalArgumentException();
    UInt8MultiArray pins_modes = new UInt8MultiArray();
    for (int i = 0;i < pins.length; ++i)
      Poark.createPinMode(pins_modes, pins[i], modes[i], initialStates[i]);
    setPinStatePub.publish(pins_modes);
  }

  /**
   * Creates an entry for a set_pins message. See the Poark's documentation for
   * more information regarding the set_pins message
   * {@linktourl http://code.google.com/p/poark/wiki/HowToUse#set_pins}.
   *
   * @param pin - the pin to be set.
   * @param state - the new pin state depends on the pin mode.
   */
  public void setPinState(byte pin, byte state) {
    UInt8MultiArray pinsStates = new UInt8MultiArray();
    Poark.createPinState(pinsStates, pin, state);
    setPinsPub.publish(pinsStates);
  }

  /**
   * Creates an entry for a set_pins message. See the Poark's documentation for
   * more information regarding the set_pins message
   * {@linktourl http://code.google.com/p/poark/wiki/HowToUse#set_pins}.
   *
   * @param pin - the pin to be set.
   * @param state - the new pin state depends on the pin mode.
   */
  public void setPinsState(byte[] pins, byte[] states) throws IllegalArgumentException {
    if (pins.length != states.length)
      throw new IllegalArgumentException();
    UInt8MultiArray pinsStates = new UInt8MultiArray();
    for (int i = 0;i < pins.length; ++i)
      Poark.createPinState(pinsStates, pins[i], states[i]);
    setPinsPub.publish(pinsStates);
  }

  /**
   * Initiates I2C transfer. Can be used for both sending and receiving data on the I2C
   * bus.
   * @param address The address of the slave device to talk to.
   * @param token A user defined token used to identify the corresponding i2c_repsonse.
   * @param data Up to (now) 10 bytes of data to transmit to the slave.
   * @param receiveLenght The amount of data to read from the slave device.
   * @throws IllegalArgumentException if the data to transmit is too long.
   */
  public void performI2CTransfer(byte address, byte token,
                                 byte[] data,
                                 int receiveLenght) throws IllegalArgumentException{
    if (data.length > kMaxI2CDataLength || receiveLenght > kMaxI2CDataLength)
      throw new IllegalArgumentException();
    UInt8MultiArray i2cIoData = Poark.createI2CPackage(
        address, token, data, receiveLenght);
    i2cIoPub.publish(i2cIoData);
  }

  /**
   * Adds a new i2c listener for a specific address or for all addresses. Note that one
   * listener can be registered multiple times for different addresses or that one
   * listener can be used for all addresses at the same time.
   * {@linktourl http://code.google.com/p/poark/wiki/HowToUse#i2c_response}
   * @param address The i2c slave address. If -1 is specified will listen to addresses.
   * @param listener The listener object.
   * @return True if the listener has been successfully added.
   */
  public boolean addI2CResponseListener(byte address, I2CResponseListener listener) {
    return i2cListener.listenerClients.put(address, listener);
  }

  /**
   * Removes a listener.
   * @param address The i2c slave address.
   * @param listener The listener object to be removed.
   * @return True if the listener has been successfully removed.
   */
  public boolean removeI2CResponseListener(
      byte address, I2CResponseListener listener) {
    return i2cListener.listenerClients.remove(address, listener);
  }

  /**
   * simplifies calls to @Poark.GetAPin.
   * @param analogInput - The analog pin number as printed on the board.
   * @return the real pin number as needed for the Poark.
   * @throws ParameterNotFoundException if the pin number is not valid for the current
   * layout.
   */
  public byte getAPin(int analogInput) throws ParameterNotFoundException{
    return Poark.getAPin(analogInput, layout);
  }
}
TOP

Related Classes of org.ros.poark.PoarkClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.