Victor Petin
Published © GPL3+

Robot for remote processing of premises using a UV lamp, v1

Robot on a moving platform for the treatment of premises from COVID19 bacteria using an ultraviolet lamp, remotely controlled

AdvancedFull instructions providedOver 4 days395

Things used in this project

Hardware components

Programmable Robot iRobot Create or iRobot Create 2
×1
Notebook c OS Ubuntu 16.04 (Xenial)
×2
UF lamp
×1
Neato XV-11 lidar
×1
LM2596 DC-DC Step-down Converter
×2
Arduino UNO & Genuino UNO
Arduino UNO & Genuino UNO
×1
usb-com adapter
×1
Li-ion battery 12V 7AH
×1
Defender USB Hub 7 port
×1
Wireless Joystick Defender Scorpion RS3
×1
solid state relay DC/DC
×1

Software apps and online services

Arduino IDE
Arduino IDE
OS Ubuntu 16.04 (Xenial)
ROS Kinetic Kame
js virtual joystick

Story

Read more

Code

Step 9. Creating a page for rossbridge (controlling the movement of the platform and web-camera)

XML
main22.launch
<launch>
   <include file="$(find rosbridge_server)/launch/rosbridge_websocket.launch"></include>
   <!-- iRobot create -->
   <arg name="config" default="$(find ca_driver)/config/default.yaml" ></arg>
   <arg name="desc" default="true" ></arg>

   <node name="ca_driver" pkg="ca_driver" type="ca_driver" output="screen">
    <rosparam command="load" file="$(arg config)" ></rosparam>
    <param name="robot_model" value="CREATE_1" />
   </node>

   
   <include if="$(arg desc)" file="$(find ca_description)/launch/create_1.launch" ></include>

   <!-- camera -->
   <node name="web_video_server1" pkg="web_video_server" type="web_video_server">
  </node>
  <node name="usb_cam0" pkg="usb_cam" type="usb_cam_node" output="screen" >
    <param name="video_device" value="/dev/video0"></param>
    <param name="image_width" value="320"></param>
    <param name="image_height" value="240"></param>
    <param name="pixel_format" value="yuyv"></param>
    <param name="camera_frame_id" value="usb_cam"></param>
    <param name="io_method" value="mmap"></param>
  </node>
  


 
</launch>

Step 5. Control the robot using a wireless joystick

XML
main21.launch
<launch>
    <!-- iRobot create -->
   <arg name="config" default="$(find ca_driver)/config/default.yaml" ></arg>
   <arg name="desc" default="true" ></arg>

   <node name="ca_driver" pkg="ca_driver" type="ca_driver" output="screen">
    <rosparam command="load" file="$(arg config)" ></rosparam>
    <param name="robot_model" value="CREATE_1" />
   </node>

   
   <include if="$(arg desc)" file="$(find ca_description)/launch/create_1.launch" ></include>

  <!-- joystick -->   

  <arg name="joy_dev" default="/dev/input/js0" ></arg>
  <arg name="joy_config" default="xbox360" ></arg>
  <arg name="teleop_config" default="$(find ca_tools)/config/$(arg joy_config).yaml" ></arg>

  <rosparam file="$(arg teleop_config)" command="load" ></rosparam>

  <node pkg="joy" type="joy_node" name="joy_node">
    <param name="dev" value="$(arg joy_dev)" />
    <param name="deadzone" value="0.2" />
    <param name="autorepeat_rate" value="20" />
  </node>

  <node pkg="joy_teleop" type="joy_teleop.py" name="joy_teleop">
  </node>

 
</launch>

Step 11. Starting the robot - command file main23.launch

XML
<launch>
   <include file="$(find rosbridge_server)/launch/rosbridge_websocket.launch"></include>
   <!-- iRobot create -->
   <arg name="config" default="$(find ca_driver)/config/default.yaml" ></arg>
   <arg name="desc" default="true" ></arg>

   <node name="ca_driver" pkg="ca_driver" type="ca_driver" output="screen">
    <rosparam command="load" file="$(arg config)" ></rosparam>
    <param name="robot_model" value="CREATE_1" />
   </node>

   
   <include if="$(arg desc)" file="$(find ca_description)/launch/create_1.launch" ></include>

   <!-- camera -->
   <node name="web_video_server1" pkg="web_video_server" type="web_video_server">
  </node>
  <node name="usb_cam0" pkg="usb_cam" type="usb_cam_node" output="screen" >
    <param name="video_device" value="/dev/video0"></param>
    <param name="image_width" value="320"></param>
    <param name="image_height" value="240"></param>
    <param name="pixel_format" value="yuyv"></param>
    <param name="camera_frame_id" value="usb_cam"></param>
    <param name="io_method" value="mmap"></param>
  </node>
  // arduino
  <node name="serial_node" pkg="rosserial_python" type="serial_node.py">
            <param name="port" value="/dev/ttyACM0"/>
            <param name="baud" value="57600" />
  </node>
</launch>

Step 9. Creating a page for rossbridge (controlling the movement of the platform and web-camera)

HTML
index13.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />

<script type="text/javascript" src="js/roslib.min.js"></script>
<script type="text/javascript" src="js/nipplejs.js"></script>
<script type="text/javascript" type="text/javascript">
  var ip="192.168.2.111";
  var ros = new ROSLIB.Ros({
    url : 'ws://'+ip+':9090'
  });

  ros.on('connection', function() {
    document.getElementById("status").innerHTML = "Connected";
  });

  ros.on('error', function(error) {
    document.getElementById("status").innerHTML = "Error";
  });

  ros.on('close', function() {
    document.getElementById("status").innerHTML = "Closed";
  });
  var txt_listener = new ROSLIB.Topic({
    ros : ros,
    name : '/txt_msg',
    messageType : 'std_msgs/String'
  });

  txt_listener.subscribe(function(m) {
    document.getElementById("msg").innerHTML = m.data;
  });

  cmd_vel_listener = new ROSLIB.Topic({
    ros : ros,
    name : "/cmd_vel",
    messageType : 'geometry_msgs/Twist'
  });

  move = function (linear, angular) {
    var twist = new ROSLIB.Message({
      linear: {
        x: linear,
        y: 0,
        z: 0
      },
      angular: {
        x: 0,
        y: 0,
        z: angular
      }
    });
    cmd_vel_listener.publish(twist);
  }


    createJoystick = function () {
      var options = {
        zone: document.getElementById('zone_joystick'),
        threshold: 0.1,
        position: { left: 50 + '%' },
        mode: 'static',
        size: 150,
        color: '#000000',
      };
      manager = nipplejs.create(options);
      linear_speed = 0;
      angular_speed = 0;
      manager.on('start', function (event, nipple) {
        timer = setInterval(function () {
          move(linear_speed, angular_speed);
        }, 25);
      });
      manager.on('move', function (event, nipple) {
        max_linear = 1.0; // m/s
        max_angular = 1.0; // rad/s
        max_distance = 75.0; // pixels;
        linear_speed = Math.sin(nipple.angle.radian) * max_linear * nipple.distance/max_distance;
				angular_speed = -Math.cos(nipple.angle.radian) * max_angular * nipple.distance/max_distance;
      });
      manager.on('end', function () {
        if (timer) {
          clearInterval(timer);
        }
        self.move(0, 0);
      });
    }
    window.onload = function () {
      //createJoystick();
    }

  function set_ip()
    {
    ip=document.getElementById("ip").value;
    ros.close();
    ros = new ROSLIB.Ros({
       url : 'ws://'+ip+':9090'
       });
    alert("new ip - "+ip);
    if(ros.isConnected === true)
       {document.getElementById("status").innerHTML = "Connected";}
    else 
       {document.getElementById("status").innerHTML = "Closed";}
    var obj=document.getElementById("choice_camera");
    //alert(obj.value);
    new_camera(obj.value);
    }

  function new_camera(topic)
    {
    alert(topic);
    document.getElementById("camera_robot").src="http://"+ip+":8080/stream?topic="+topic;
    }
</script>

</script>
</head>

<body onload='createJoystick();new_camera(document.getElementById("choice_camera").value);'>
  <h1>Simple ROS User Interface</h1>
  <p>Connection status: <span id="status"></span></p>
  <p>Last /txt_msg received: <span id="msg"></span></p>
  <div id="zone_joystick" style="position: relative;"></div>

    <form id=formoptions name=formoptions action="javascript:void();" onsubmit="return false;">
      <select name=choice_camera id=choice_camera onchange='new_camera(this.value)'>
        <option value="/usb_cam1/image_raw"> /usb_cam1/image_raw
         <option value="/usb_cam0/image_raw"> /usb_cam0/image_raw
      </select>
      <input type='text' name='ip' id='ip' value='192.168.2.111' onchange='set_ip();'>
      
    </form>
    <img id=camera_robot src="">

</body>
</html>

Step 11. HTML code web-page

HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />

<script type="text/javascript" src="js/roslib.min.js"></script>
<script type="text/javascript" src="js/nipplejs.js"></script>
<script type="text/javascript" >
  var uf=0;
  var ip="192.168.2.111";
  var ros = new ROSLIB.Ros({
    url : 'ws://'+ip+':9090'
  });

  ros.on('connection', function() {
    document.getElementById("status").innerHTML = "Connected";    
  });

  ros.on('error', function(error) {
    document.getElementById("status").innerHTML = "Error";
  });

  ros.on('close', function() {
    document.getElementById("status").innerHTML = "Closed";
  });
  var UF = new ROSLIB.Topic({
    ros : ros,
    name : '/setUF',
    messageType : 'std_msgs/Int8'
  });


  cmd_vel_listener = new ROSLIB.Topic({
    ros : ros,
    name : "/cmd_vel",
    messageType : 'geometry_msgs/Twist'
  });

  move = function (linear, angular) {
    var twist = new ROSLIB.Message({
      linear: {
        x: linear,
        y: 0,
        z: 0
      },
      angular: {
        x: 0,
        y: 0,
        z: angular
      }
    });
    cmd_vel_listener.publish(twist);
  }

  var UF = new ROSLIB.Topic({
       ros : ros,
       name : '/setUF',
       messageType : 'std_msgs/Int8t'
     });
     
    createJoystick = function () {
      var options = {
        zone: document.getElementById('zone_joystick'),
        threshold: 0.1,
        position: { left: 50 + '%' },
        mode: 'static',
        size: 150,
        color: '#000000',
      };
      manager = nipplejs.create(options);
      linear_speed = 0;
      angular_speed = 0;
      manager.on('start', function (event, nipple) {
        timer = setInterval(function () {
          move(linear_speed, angular_speed);
        }, 25);
      });
      manager.on('move', function (event, nipple) {
        max_linear = 1.0; // m/s
        max_angular = 1.0; // rad/s
        max_distance = 75.0; // pixels;
        linear_speed = Math.sin(nipple.angle.radian) * max_linear * nipple.distance/max_distance;
				angular_speed = -Math.cos(nipple.angle.radian) * max_angular * nipple.distance/max_distance;
      });
      manager.on('end', function () {
        if (timer) {
          clearInterval(timer);
        }
        self.move(0, 0);
      });
    }
    window.onload = function () {
      //createJoystick();
    }

  function set_ip()
    {
    ip=document.getElementById("ip").value;
    ros.close();
    ros = new ROSLIB.Ros({
       url : 'ws://'+ip+':9090'
       });
    alert("new ip - "+ip);
    if(ros.isConnected === true)
       {document.getElementById("status").innerHTML = "Connected";}
    else 
       {document.getElementById("status").innerHTML = "Closed";}
    var obj=document.getElementById("choice_camera");
    //alert(obj.value);
    new_camera(obj.value);
    }

  function new_camera(topic)
    {
    alert(topic);
    document.getElementById("camera_robot").src="http://"+ip+":8080/stream?topic="+topic;
    }

function change_UF()
    {
    uf=1-uf;
    alert(uf);
    if(uf===1)
      {document.getElementById("button_uf").style.background="blue"; 
       document.getElementById("button_uf").innerText="UF ON";
       UF.publish({'data':1});
      }
    else
      {document.getElementById("button_uf").style.background="transparent";
       document.getElementById("button_uf").innerText="UF OFF";
       UF.publish({'data':0});

      }
    }

</script>

</head>

<body onload='createJoystick();new_camera(document.getElementById("choice_camera").value);'>
  <h1>Simple ROS User Interface</h1>
  <p>Connection status: <span id="status"></span></p>
  <p>Last /txt_msg received: <span id="msg"></span></p>
  <div><button id="button_uf" onclick="change_UF();">UF OFF</button></div>
  <div id="zone_joystick" style="position: relative;"></div>

    <form id=formoptions name=formoptions action="javascript:void();" onsubmit="return false;">
      <select name=choice_camera id=choice_camera onchange='new_camera(this.value)'>
        <option value="/usb_cam1/image_raw"> /usb_cam1/image_raw
         <option value="/usb_cam0/image_raw"> /usb_cam0/image_raw
      </select>
      <input type='text' name='ip' id='ip' value='192.168.2.111' onchange='set_ip();'>
      
    </form>
    <img id=camera_robot src="">

</body>
</html>

repository on github

Credits

Victor Petin

Victor Petin

2 projects • 3 followers
Author of more than 10 books on programming (web, Arduino, Raspberry pi, IoT) for the Russian-speaking audience, developer and teacher.

Comments