Questions about the "Remote Camera Robot" project

Breakthrough!

It turns out that my code works “as expected” in Chrome, but not in Firefox for some reason.  I can work with that!

Once I find out what the differences are, it’s knocked!

2 Likes

Success with the Joystick test code!

The difference was the page was being cached in Firefox and not in Chrome.

I am now reading the first five axes, (0 - 4), and the first five buttons, (0 - 4), in real-time and displaying the results on the browser screen.

I am going to attach the completed HTML file to this message for 3 reasons:

  1. I’ve tried it using Firefox and Chrome on Win-10, 64-bit.  If anyone else could test it on a different operating system and/or browser, I’d really appreciate.
  2. I’ve tried it using my Saitek X52 Joystick.  If anyone wants to try it with a different joystick/gamepad, I’d also really appreciate it.

Most important:

  1. I’d really appreciate the courtesy of a code review.  Any suggestions for improvements in coding, clarity, style, or whatever would be most gratefully appreciated.

Thanks!

joystick_test-2.html.txt (5.0 KB)

1 Like

Related question:

Issue:
In the course of using the robot with the joystick, I may want the robot to send messages back to the web client displaying the images.

Example:
Let’s say I want to implement a “parking brake” for the robot. Once engaged, the robot will not move, regardless of joystick position, until released.

I could set a variable in the client-side JavaScript, and display a message at the bottom of the viewport whenever the user tries to set the parking brake, but - what if the robot misses the message for whatever reason?  The parking brake message would be visible, but the robot would still be active.

What I want to do, (in this example), is to send, (as part of the normal status updates to the robot), a data object that would contain a request to set/release/skip the parking brake.  If the robot receives the message, it would programmatically set or release the brake, and then send a message back with the status of the parking brake, either set, released, or ignored as the case may be.

This way the robot is ALWAYS in sync with the web page.

Note that I have spent quite a while researching this and - without exception - every blinkin’ page I’ve seen assumes I’m doing something fancy like streaming YouTube videos, loading a dynamic page using a massive SQL database, running a fancy POS web-site, etc., and the examples look like the source-code for nipple.js!

NO!!!

All I want to do is send some simple data, in a consistent format, back to the client to let it know what the robot is actually doing.

Right now, the client is successfully pushing data TO the server, (the data on how the robot is supposed to be moving), but I am not how to retrieve formatted status data BACK from the 'bot.

I don’t need WordPress. I don’t need JavaBeans. I don’t need Ruby-On-Rails, Ajax, or whatever. I don’t need PHP or SQL and I have no desire to implement a Postgres or Oracle database. I just want to send simple text/numeric data variables back to the client with status-of-the-bot data that may, (or may not), change.

Note that the returned data would be assembled very similarly to the data the page sends to the robot - a list of variables with data that indicates the status of various attributes of the 'bot. (i.e. Is the battery about to die? Have we slammed face-first into my wife’s chair?)

Any ideas or resources I might try? MDN, Stack Overflow, (and all the other usual Fountains of Wisdom), have all failed me, regardless of how I phrase my request.

It seems that they believe it is so very elementary that you already know this before you get your first computer.

Sheesh! :man_facepalming: :crazy_face:

No, they expect that you did not skip all the elementary client server lessons where the client makes requests and the server responds,and then progress to dynamic HTML where the client sets up a destination for asynchronous responses.

The code base you started with has only one thing coming from the server, the camera output. It is not trivial to set up aNother div to show the brake status based on an asynchronous server response.

1 Like

Maybe I missed that, but this is what I was trying to find - a simple explanation how to get there from here.

And I do realize that I am starting a course in elementary pyrotechnics by making a nuclear weapon. :wink:

1 Like

Interesting factoid:
Apparently you cannot buy anything by VKBsim in Russia. No dealers, no stock, no results on Yandex (Russian “Google”)

I’d have to either buy one when I return or have it shipped.

Unfortunately, since they weigh in at $250+, I don’t think I will be ordering one soon.

1 Like

$250 sounds way too much. This is the one I bought $99

https://store.x-plane.org/Gladiator-MK-II_p_595.html

1 Like

October 22:
Charlie Rides Again!

Between the middle of July and now, a number of things happened which kept me away from both Charlie and my research.

I have - finally! - gotten back to it, re-installed VS Code and rebuilt my dev environment.

I did some playing around with the camera’s white balance and stuff like that, just to verify that I could make changes, commit, and push to GitHub.

There appear to be a few “tweaks” that hadn’t been pushed to GitHub when things went pear-shaped, so I’m tracking them down and re-adding them as I find them.

I still need a new joystick though. :slightly_frowning_face:

1 Like

Update:

Total glitch-up time. . . .

Got myself all re-configured, (re)-installed my Visual Studio Code tool-chain, sync’d up with GitHub, (verified push, pull, and sync on my repositories), and even created a new repo for my startup and configuration scripts for Charlie.

The Acid Test:
Actually transferring files to Charlie and trying to run them - especially my new startup scripts.
Bzzzzzzzt! We’re sorry, but your answer must be in the form of a question!

Things went haywire for bizarre reasons - like the script could not find the /usr/bin/python (or python3) interpreters, but I could find it, launch it, and even run scripts against it.

There were other bizarro errors, ( “,” expected between a class and it’s method instead of a “.”, missing brackets/parenthesis, etc.) All of which were in programs/scripts that had always worked before I temporarily stopped and rebuilt my machine.

After many hours of searching on the 'Net, (and re-installing VS Code after clearing out everything, and re-syncing the repos), I finally figured out the problem. . .

Visual Studio Code had never been re-set to use Unix-style line endings after the rebuild and re-install - so everything I touched, edited, copied, transferred, or even breathed on, was saved with the Windows-style line endings (CR/LF) instead of just line-feeds.

Something you Mac folks never see because your machine uses Unix-style line endings.

What a mess!

Not only did I have to set the global setting for Unix-style line endings, but I had to go to each and every file I had and manually convert them, one-by-one.

Sigh. . . :crazy_face:

Noticed an interesting thing:

I have several python files that do similar things - like moving the pan-and-tilt, calculating force and direction, etc.

If I modify one file and determine the best values for, for example, head position or the calibration constants for motion/speed, I have to propagate these changes through to every file that uses those functions.

I’m thinking that the best way to handle this would be to break this functionality out into one or more “include” modules that would become common to all the code.

I’m also considering creating an “includes” folder instead of putting it/them in the root of my project.

Is there any reason why this might NOT be a good idea?

I don’t speak Windows anymore but use to always install cygwin which had a magic command

dos2unix *

Did them all in one fell swoop.

I do this but it can be a bit of a pain if you start using them across more than one project.

You can make python understand a folder has a package of importable stuff in it with the empty file named:

__init__.py

see http://effbot.org/pyfaq/what-is-init-py-used-for.htm

I keep all my universal routines in Carl/plib/

My python template:

#!/usr/bin/env python3
#
# filename.py

"""
Documentation:

"""

# from __future__ import print_function # use python 3 syntax but make it compatible with python 2
# from __future__ import division       #                           ''

import sys
try:
    sys.path.append('/home/pi/Carl/plib')
    import speak
    import tiltpan
    import status
    import battery
    import myDistSensor
    import lifeLog
    import runLog
    import myconfig
    import myimutils   # display(windowname, image, scale_percent=30)
    Carl = True
except:
    Carl = False
import easygopigo3 # import the EasyGoPiGo3 class
import numpy as np
import datetime as dt
import argparse
from time import sleep

import cv2

# ARGUMENT PARSER
# ap = argparse.ArgumentParser()
# ap.add_argument("-f", "--file", required=True, help="path to input file")
# ap.add_argument("-n", "--num", type=int, default=5, help="number")
# ap.add_argument("-l", "--loop", default=False, action='store_true', help="optional loop mode")
# args = vars(ap.parse_args())
# print("Started with args:",args)
# filename = args['file']
# loopFlag = args['loop']

# CONSTANTS


# VARIABLES


# METHODS 

# MAIN

def main():
    if Carl: runLog.logger.info("Started")
    try:
        egpg = easygopigo3.EasyGoPiGo3(use_mutex=True)
    except:
        strToLog = "Could not instantiate an EasyGoPiGo3"
        print(strToLog)
        if Carl: lifeLog.logger.info(strToLog)
        exit(1)
    if Carl:
        myconfig.setParameters(egpg)
        tp = tiltpan.TiltPan(egpg)
        tp.tiltpan_center()
        tp.off()

    try:
        # Do Somthing in a Loop
        loopSleep = 1 # second
        loopCount = 0
        keepLooping = False
        while keepLooping:
            loopCount += 1
            # do something
            sleep(loopSleep)

        # Do Something Once


    except KeyboardInterrupt: # except the program gets interrupted by Ctrl+C on the keyboard.
       	    if (egpg != None): egpg.stop()           # stop motors
            print("\n*** Ctrl-C detected - Finishing up")
            sleep(1)
    if (egpg != None): egpg.stop()
    if Carl: runLog.logger.info("Finished")
    sleep(1)


if (__name__ == '__main__'):  main()

I’ve played with cigwin, but it is/was HUGE. IMHO, I might as well install Mint in a virtual machine. What I’d like is something that would give me a mini-install of Debian or Fedora - “just the commands, ma’m!”, instead of the whole enchilada.

Something like that is exactly what I was thinking of. I already have a folder called “Projects” in the pi user’s home directory, though you have a point. . .  Maybe making a special in pi’s home directory called “Charlie” which would be the place where things that aren’t going anywhere would reside, and a ./pub folder would be a good idea.

However, you do realize that I’ll have to touch a file there named “Gov’rnor, gimme a pint!” :wink:

1 Like

Yes, but not necessarily. The default install brings in X-Windows, a bunch of editors, and a whole lot more. There are check boxes that allow tailoring what to install, so if you only install the dos command line utilities the package is quite compact.

1 Like

Interesting!

I’ll have to snoop that out.