blink1_node.cpp
Go to the documentation of this file.
00001 /*
00002 * Copyright (c) 2016 Carnegie Mellon University, Guilherme Pereira <gpereira@cmu.edu>
00003 *
00004 * For License information please see the LICENSE file in the root directory.
00005 *
00006 */
00007 
00008 /* 
00009  * This node was adapted from the original code of the blink1-mini-tool:
00010  * 
00011  * https://github.com/todbot/blink1/tree/master/commandline/blink1-mini-tool
00012  * 
00013  * blink1-mini-tool -- minimal command-line tool for controlling blink(1)s
00014  *                     
00015  * Will work on small unix-based systems that have just libusb-0.1.4
00016  * No need for pthread & iconv, which is needed for hidapi-based tools
00017  * 
00018  * Known to work on:
00019  * - Ubuntu Linux
00020  * - Mac OS X 
00021  * - TomatoUSB WRT / OpenWrt / DD-WRT
00022  *
00023  * 2012, Tod E. Kurt, http://todbot.com/blog/ , http://thingm.com/
00024  *
00025  */
00026 
00027 
00028 #include <ros/ros.h>
00029 #include <signal.h>
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <string.h>    // for memset() et al
00033 #include <stdint.h>    // for uint8_t
00034 #include <unistd.h>    // for usleep()
00035 #include <time.h>      // for time()
00036 
00037 #include "blink1/hiddata.h"
00038 #include "blink1/Blink.h"
00039 #include "blink1/blinkfn.h"
00040 
00041 // taken from blink1/hardware/firmware/usbconfig.h
00042 #define IDENT_VENDOR_NUM        0x27B8
00043 #define IDENT_PRODUCT_NUM       0x01ED
00044 #define IDENT_VENDOR_STRING     "ThingM"
00045 #define IDENT_PRODUCT_STRING    "blink(1)"
00046 
00047 usbDevice_t *dev;
00048 bool blink_control;
00049 bool exit_;
00050 blink1::Blink::Request last_request;
00051 
00052 int blink1_open(usbDevice_t **dev);
00053 char *blink1_error_msg(int errCode);
00054 void blink1_close(usbDevice_t *dev);
00055 int blink1_fadeToRGB(usbDevice_t *dev, int fadeMillis, 
00056                      uint8_t r, uint8_t g, uint8_t b );
00057 int blink1_setRGB(usbDevice_t *dev, uint8_t r, uint8_t g, uint8_t b );
00058 static int  hexread(char *buffer, char *string, int buflen);
00059 
00060 void SigintHandler(int sig)
00061 {
00062   exit_=true; 
00063   blink1_fadeToRGB(dev, 1000, 0, 0, 0);
00064   ros::Duration(1).sleep();
00065   blink1_close(dev);
00066   ros::Duration(0.5).sleep();
00067   ros::shutdown();
00068 }
00069 
00070 bool blinkCB(blink1::Blink::Request  &req,  blink1::Blink::Response &res)
00071 {
00072   if (req.function == BL_FADE){
00073        res.on=blink1_fadeToRGB(dev, req.t, req.r, req.g, req.b);
00074        blink_control=false;
00075        return true;
00076   } 
00077   
00078   if (req.function == BL_ON){       
00079        res.on=blink1_fadeToRGB(dev, 0.0, req.r, req.g, req.b);
00080        blink_control=false; 
00081        return true;
00082   }
00083   
00084   if ((req.function == BL_BLINK) || (req.function == BL_RANDBLINK)){
00085        blink_control=true;
00086        last_request.function=req.function;
00087        last_request.t=req.t;
00088        last_request.r=req.r;
00089        last_request.g=req.g;
00090        last_request.b=req.b;
00091        res.on=true;
00092        return true;
00093   }
00094 }
00095 
00096 
00097 int main(int argc, char **argv) {
00098 
00099   ros::init(argc, argv, "blink1_node");
00100   ros::NodeHandle n;
00101   ros::Rate loop_rate(5);
00102 
00103   signal(SIGINT, SigintHandler);
00104   
00105   if( blink1_open(&dev) ) {
00106         ROS_ERROR("error: couldn't open blink1\n");
00107         exit(1);
00108   }
00109   
00110   blink_control = false;
00111   exit_=false;
00112   
00113   ros::ServiceServer service = n.advertiseService("blink1/blink", blinkCB);
00114   
00115    while (ros::ok() && !exit_)
00116      {
00117       
00118       ros::spinOnce();
00119        
00120 
00121       if (blink_control){
00122           if (last_request.function ==  BL_RANDBLINK)
00123             blink1_fadeToRGB(dev, last_request.t/4, rand()%256, rand()%256, rand()%256);
00124           else 
00125             blink1_fadeToRGB(dev, last_request.t/4, last_request.r, last_request.g, last_request.b);
00126           
00127           ros::Duration((double)last_request.t/2000).sleep();
00128           blink1_fadeToRGB(dev, last_request.t/4, 0, 0, 0);
00129           ros::Duration((double)last_request.t/2000).sleep();   
00130       }
00131       loop_rate.sleep();
00132      }
00133    
00134 
00135 }
00136 
00137 
00144 int blink1_open(usbDevice_t **dev)
00145 {
00146     return usbhidOpenDevice(dev, 
00147                             IDENT_VENDOR_NUM,  NULL,
00148                             IDENT_PRODUCT_NUM, NULL,
00149                             1);  // NOTE: '0' means "not using report IDs"
00150 }
00151 
00155 void blink1_close(usbDevice_t *dev)
00156 {
00157     usbhidCloseDevice(dev);
00158 }
00159 
00163 int blink1_fadeToRGB(usbDevice_t *dev, int fadeMillis,
00164                         uint8_t r, uint8_t g, uint8_t b )
00165 {
00166     char buf[9];
00167     int err;
00168 
00169     if( dev==NULL ) {
00170         return -1; // BLINK1_ERR_NOTOPEN;
00171     }
00172 
00173     int dms = fadeMillis/10;  // millis_divided_by_10
00174 
00175     buf[0] = 1;
00176     buf[1] = 'c';
00177     buf[2] = r;
00178     buf[3] = g;
00179     buf[4] = b;
00180     buf[5] = (dms >> 8);
00181     buf[6] = dms % 0xff;
00182     buf[7] = 0; // ledn
00183     //buf[8] = 0; // unused
00184 
00185     if( (err = usbhidSetReport(dev, buf, sizeof(buf))) != 0) {
00186         ROS_ERROR("fadeToRGB: error writing: %s\n",blink1_error_msg(err));
00187     }
00188     return err;  
00189 }
00190 
00194 int blink1_setRGB(usbDevice_t *dev, uint8_t r, uint8_t g, uint8_t b )
00195 {
00196     char buf[9];
00197     int err;
00198 
00199     if( dev==NULL ) {
00200         return -1; // BLINK1_ERR_NOTOPEN;
00201     }
00202 
00203     buf[0] = 1;
00204     buf[1] = 'n';
00205     buf[2] = r;
00206     buf[3] = g;
00207     buf[4] = b;
00208     
00209     if( (err = usbhidSetReport(dev, buf, sizeof(buf))) != 0) {
00210         ROS_ERROR("setRGB: error writing: %s\n",blink1_error_msg(err));
00211     }
00212     return err;  
00213 }
00214 
00215 
00216 //
00217 char *blink1_error_msg(int errCode)
00218 {
00219     static char buffer[80];
00220 
00221     switch(errCode){
00222         case USBOPEN_ERR_ACCESS:    return "Access to device denied";
00223         case USBOPEN_ERR_NOTFOUND:  return "The specified device was not found";
00224         case USBOPEN_ERR_IO:        return "Communication error with device";
00225         default:
00226             sprintf(buffer, "Unknown USB error %d", errCode);
00227             return buffer;
00228     }
00229     return NULL;    /* not reached */
00230 }
00231 
00232 //
00233 static int  hexread(char *buffer, char *string, int buflen)
00234 {
00235 char    *s;
00236 int     pos = 0;
00237 
00238     while((s = strtok(string, ", ")) != NULL && pos < buflen){
00239         string = NULL;
00240         buffer[pos++] = (char)strtol(s, NULL, 0);
00241     }
00242     return pos;
00243 }
00244 


blink1
Author(s): Guilherme Pereira (The AIR lab, Carnegie Mellon University)
autogenerated on Sat Jun 8 2019 20:13:43