Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

Ok, it's been more than half a year since my previous post on building robots! I know, it's unacceptable, but other big and important things (such as organizing SAP Inside Track Singapore; Internal SAP d-codes in many SAP locations; and finally planning to take over the world) were keeping me busy.

So let's continue where we left off.

Introduction

Do you remember the robotic arm from the previous post? Well, let's talk about it. Here's the story. Once at an internal SAP meeting I overheard a manager of a sales team telling all reporting employees that their annual performance reviews will be super streamlined: if the sales quota is met, they will get their bonus. If the sales quota is not met, they will not get the bonus*. Simple and easy, black and white. And of course all of the sales data is in HANA now, so quick access to it is easier than it was before. I thought it was an amazing idea, and that is also because I realized that with such an approach we could fire the manager, and replace him/her with a robot!

Because I do not like the concept of annual performance reviews, and prefer continuous feedback, I thought it would be really cool to build a sales manager robot that would interact with employees on a daily basis. It would consist of a hand only. Claw, to be more precise. The claw would be used to strangle a sales person (manager's subordinate) if the expected sales for the day were low. Once sales go up, the claw would let the sales person go, only to punish him or her if they underperformed again. Simple, isn't it? And exactly as the said manager would imagine it, I guess.

Let me describe it in a more visual way**.

Exhibit one: happy sales person, not knowing that the manager is about to review the sales results.


Exhibit two: the manager's claw (Clawager)


Exhibit three: the sales person being strangled by the Clawager because the sales numbers are low.


Exhibit four: the sales person caught up, sales got better, time to breathe in!

Now, let us analyze how the whole thing was implemented.

HANA

First, we created a schema and a table to store our sample revenue sales data. Obviously the data is used just to demonstrate the concept. In fact, we do not have daily data in our dataset, but it is fairly easy to modify the code accordingly.


create schema PLUGIN;
create column table "PLUGIN".revenue (ID INTEGER PRIMARY KEY, GROSS DOUBLE, QUARTER INTEGER);
INSERT INTO "PLUGIN".revenue values (1, 100.0, 1);
INSERT INTO "PLUGIN".revenue values (2, 40.0, 2);
INSERT INTO "PLUGIN".revenue values (3, 120.0, 3);
INSERT INTO "PLUGIN".revenue values (4, 320.0, 4);
INSERT INTO "PLUGIN".revenue values (5, 10.0, 5);
INSERT INTO "PLUGIN".revenue values (6, 0.0, 6);
INSERT INTO "PLUGIN".revenue values (7, 1000.0, 7);
INSERT INTO "PLUGIN".revenue values (8, 100.0, 8);
INSERT INTO "PLUGIN".revenue values (9, 500.0, 9);
INSERT INTO "PLUGIN".revenue values (10, 500.0, 10);
INSERT INTO "PLUGIN".revenue values (11, 1000.0, 11);
INSERT INTO "PLUGIN".revenue values (12, 100.0, 12);
INSERT INTO "PLUGIN".revenue values (13, 300.0, 13);
INSERT INTO "PLUGIN".revenue values (14, 300.0, 14);
INSERT INTO "PLUGIN".revenue values (15, 400.0, 15);
INSERT INTO "PLUGIN".revenue values (16, 10.0, 16);
INSERT INTO "PLUGIN".revenue values (17, 90.0, 17);
INSERT INTO "PLUGIN".revenue values (18, 150.0, 18);
INSERT INTO "PLUGIN".revenue values (19, 250.0, 19);
INSERT INTO "PLUGIN".revenue values (20, 50.0, 20);


Then we created a view to compute the moving average over the last 3 quarters.


create view "PLUGIN".MOVING_AVG as
select AVG(GROSS) AS MOVING_AVG from
(
       select GROSS from "PLUGIN".revenue order by id limit 3
)


Finally, we created an XS file ‘moving_avg.xsjs’ to expose the moving average of the sales data to the outside world. It retrieves the moving average and the last quarter data and computes the trend as the ratio between the two. We normalize the resulting value to a [0, 1] interval using a sigmoid curve.

The result is output as the final value to be consumed by the client (i.e the Clawager's Arduino)

We originally wanted to use OData but stumbled across the problem a OData required a primary key. It was our lack of experience with HANA, as we later found out that OData can generate the keys automatically if configured correctly but oh well, XS did the job as well.

moving_avg.xsjs


$.response.contentType = "text/html";
var conn = $.db.getConnection();
var output = "";
var pstmt = conn.prepareStatement("select MOVING_AVG FROM \"PLUGIN\".MOVING_AVG");
var latest = conn.prepareStatement("select GROSS from \"PLUGIN\".REVENUE ORDER BY ID DESC limit 1");
var rs = pstmt.executeQuery();
if(!rs.next())
{
        $.response.setBody("Failed to retrieve data");
        $.response.status = $.net.http.INTERNAL_SERVER_ERROR;
}
else
{
       var mv_avg = output + rs.getDouble(1);
}
rs = latest.executeQuery();
if(!rs.next())
{
        $.response.setBody("Failed to retrieve data");
        $.response.status = $.net.http.INTERNAL_SERVER_ERROR;
}
else
{
       var last_value = output + rs.getDouble(1);
}
var trend = last_value / mv_avg;
trend = 1/ (1 + Math.exp( - trend));
trend = (trend - 0.5) * 2;
output = output + trend + "\n" ;
rs.close();
pstmt.close();
latest.close();
conn.close();
$.response.setBody(output);


Arduino

We wrote a short piece of python code that would connect to HANA from a laptop computer to get the service response. This response was then sent over serial to Arduino. Now, since it was done a few months ago, I cannot find this particular piece of code anymore. But in principle and in short, we followed the steps outlined in Connecting to HANA with Python using ODBC or oData and then sent the output digit over serial.


Clawager is built using two servos. One controls the spread of the claws, the other tilts the claw. In the end the tilt of the Clawager was controlled using a flex sensor (so that we could manually tilt it to grab an employee) and the spread was determined based on the values coming from HANA. Here's the Arduino code.



#include <Servo.h>
Servo bottomservo;  // create servo object to control a servo
Servo topservo;
int potpin = 2;  // analog pin used to connect the flex sensor
int val;    // variable to read the value from the analog pin
int incomingByte = 0; // this is what we're getting from our XS service
void setup()
{
  Serial.begin(9600);
  bottomservo.attach(9);  // attaches the servo on pin 9 to the servo object  - this is the flex sensor controlled servo
  topservo.attach(10);  // this is where we attach the actual claw
}
void loop()
{
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  // Serial.println(val);
  val = map(val, 128, 350, 0, 179);     // scale it to use it with the servo (value between 0 and 180)
  bottomservo.write(val);                  // sets the servo position according to the scaled value
   if (Serial.available() > 0) {
                // read the incoming byte:
                incomingByte = Serial.read();
                Serial.print("I received: "); //
                Serial.println(incomingByte-48, DEC);
topservo.write((incomingByte-48)*15);
   }
  delay(500);                           // waits for the servo to get there
}


Final result

The whole setup was done in about two hours of work, during an internal SAP event, called PLUGin. The code was written by a few people during the event, and biggest kudos go to: daniel.dahlmeier, zbigniew.mandziejewicz and marclester.tan from the SAP office in Singapore.

Clawager being tested on a real human

Full hardware setup of Clawager. From the left: battery pack, claw, Arduino, breadboard.

Note the flex sensor on the far right (in focus).

Photo: We also realized that if put upside down, the Clawager looks like a chicken. Which leads us to the final video below.

Video

This is just a fun summary of a fun project. If you observe carefully, you will see that the tilt of the head of Clawager is controlled by the flex servo. The spread, which appears to be random, is in fact the claw's response to the sales data coming from HANA. We thought it looked like a fun dance, and decided to put a colleague's badge on top of the claw, to make it more human.

I hope you enjoyed reading this summary as much as I did working on this project. Hoping that it will take me a bit less time to write the next post in the series, let me just say that I am currently working with Arduino Yún, which is a cloud-connected Arduino with Linux (Linino) on board. It's a perfect little microcontroller for small hardware projects. I am also playing with more powerful microcontrollers (such as Raspberry Pi) and computer vision. Perhaps this is the next area we are going to explore in this blog series!

* All the internal stories I ever share are completely made up, I will nether confirm nor deny whether similar situations actually happen at SAP.

** Big thanks to my kids for allowing me to use some of their toys for this blog post.

5 Comments