So I've been playing with the controllers for the PS2 game, Buzz. I've successfully used libusb to poll and read the buttons, and all is merry and bright.
The trouble is, I'd love to use the in-built lights to signal the folks who're using them (specifically to show them who has buzzed first). I know there's lights, I know that the PS2 was able to turn them on and off at will, and I know that someone has managed it with python. So I set out to implement their code with libusb in Ruby.
I've reproduced the SET_CONFIGURATION call they're making but I keep getting this error:
/home/ajfaraday/.rvm/gems/ruby-2.2.1/gems/libusb-0.5.0/lib/libusb/dev_handle.rb:539:in `submit_transfer':
error TRANSFER_STALL (LIBUSB::ERROR_PIPE)
I can't find any material online about what this error is, except that it's a USB pipe error which is being translated to TRANSFER_STALL by libusb.
I also wrote it out in python, with the specific line from the forum above, and I got something that looks like the same error:
usb.core.USBError: [Errno 32] Pipe error
So I'm at a loss to find out what I'm doing wrong. I've managed to make the opposite call (GET_CONFIGURATION) to a successful response (\x00).
Here's my reproduction script (depends on the libusb gem):
require 'libusb'
usb_context = LIBUSB::Context.new
device = usb_context.devices(
idVendor: 0x054c, idProduct: 0x0002
).first
handle = device.open
puts 'get configuration:'
x = handle.control_transfer(
:bmRequestType => "10000000".to_i(2),
:bRequest => 8,
:wValue => 0,
:wIndex => 0,
:dataIn => 1
)
puts x.inspect
puts 'set configuration:'
x = handle.control_transfer(
:bmRequestType => "00000000".to_i(2),
:bRequest => 9,
:wValue => 0,
:wIndex => 0,
:dataOut => "\x00\xFF\xFF\xFF\xFF"
)
puts x.inspect
And here's it's output:
get configuration:
"\x00"
set configuration:
/home/ajfaraday/.rvm/gems/ruby-2.2.1/gems/libusb-0.5.0/lib/libusb/dev_handle.rb:539:in `submit_transfer': error TRANSFER_STALL (LIBUSB::ERROR_PIPE)
from /home/ajfaraday/.rvm/gems/ruby-2.2.1/gems/libusb-0.5.0/lib/libusb/dev_handle.rb:515:in `control_transfer'
from sketches/raw_script.rb:22:in `<main>'
It looks like the pipe error means there's something wrong with the setup or data I'm sending out, but I can't find out anywhere what it is.
I've tried:
putting different amounts of data into the dataOut attribute, too.
detaching the kernel driver first, also re-opening the handle
expressing the dataOut attribute as an array
running it on another (linux) machine
checking the libusb source code (it's converting a USB message, nothing more)
Using different types of message as defined in http://www.usbmadesimple.co.uk/ums_4.htm
I'd be very grateful of any assistance. This really should be possible, and I know it's been done.
Libusb provides two functions named libusb_set_configuration and libusb_get_configuration. You should try to use those instead of rolling your own control transfers to do the same thing. They are documented here:
http://libusb.sourceforge.net/api-1.0/group__dev.html
You can check the source code or documentation of the Ruby libusb binding you are using to figure out how to call them from Ruby.
Also, setting a configuration is a semi-unusual thing to do to a USB device. You should make sure the drivers on your operating system do not already put the device into the correct configuration. Maybe you don't need to set the configuration.
Also, if this controller is an HID, the hidapi library might be a better fit than libusb.
Related
I am creating many games using Lua and LOVE2D, but whenever I implement a new function and want to test it out, or simply want to know a value of a variable in Lua, I either display it on the game screen or just hope that it works.
Now my question is...
IS THERE A WAY TO DISPLAY SOME INFO, such as A VARIABLE VALUE or something else into the terminal or somewhere else? Just like console.log in javascript which displays some content in the javascript console in the browser. So, is there a way to do this is Lua?? using LOVE2D?
I am using a Mac, so I have a terminal and not a command prompt. Is there a way to display some content there? Anywhere else would also be fine, I just need to see if those values are as expected or not.
Use a conf.lua file to enable the console, then you should be able to use a standard print(). You can read the wiki entry here.
Note: You have to run Lua and Love2D via the terminal for this to work. Running Lua and Love2D like this is required for the print statements to show:
/Applications/love.app/Contents/MacOS/love "/Users/myuser/Desktop/love2d-test-proj"
You just need to add a conf.lua file to the same location where your main.lua. Your file may be as simple as this:
function love.conf(t)
t.console = true
end
But feel free to copy the whole configuration file from the above link and edit what you need.
I can't be completely sure about this, because I have no access to Mac, but the console is disabled by default and even on Windows, no prints are shown until you turn it on.
Alternatively You can also display debug info in the game itself like some games do.
What I like to do is add something like debugVariable = {} for logging events that happen in each loop and debugPermanent = {} for events that happen rarely. Possibly add convenience functions for writing to the variables:
function debugAddVariable(str)
table.insert(debugVariable, str)
end
--..and similarly for debugPermanent
Now a function to draw our debug info:
function debugDraw()
love.graphics.push() --remember graphics state
love.graphics.origin() --clear any previous transforms
love.graphics.setColor(--[[select color for debug info]])
love.graphics.setFont(--[[select font for debug info]])
for i, v in ipairs(debugPermanent) do
love.graphics.print(v)
love.graphics.translate(0, --[[fontHeight]])
end
for i, v in ipairs(debugVariable) do
love.graphics.print(v)
love.graphics.translate(0, --[[fontHeight]])
end
debugVariable = {} --clear debugVariable to prepare it for the next loop
love.graphics.pop() --recall graphics state
end
And we just call this draw function at the end of our love.draw() and the texts should appear.
Obviously, this method can be refined further and further almost infinitely, displaying specific variables, and adding graphs for some other variables to clarify the information you want to show, but that's kind of outside of the scope of the question.
Lastly Feel free to check here for debug libraries submitted by users.
When running in parallel I am unable to connect unknowns of subgroups in a ParallelGroup() even though I can connect to the subgroups' params. The code causing the problem (with names changed for clarity) is below. This code is within a group of a larger structure, but is the only place where MPI is being used:
for i in range(0, nTasks):
self.connect('comp_a.output%i' % i, 'parallel_group.sub_group%i.param_a' % i)
self.connect('input_param%i' % i, 'parallel_group.sub_group%i.param_b' % i)
self.connect('parallel_group.sub_group%i.output' % i, 'comp_b.input%i' % i)
The first two connections seem to work fine, but the last one throws an error:
NameError: Source 'parallel_group.sub_group0.output' cannot be connected to target 'comb_b.input0': 'parallel_group.sub_group0.output' does not exist.
Also, if I comment out the offending line, then first line in the loop fails for the second process with the same error message:
NameError: Source 'comp_a.output1' cannot be connected to target 'parallel_group.sub_group1.param_a': 'parallel_group.sub_group1.param_a' does not exist.
All the connections work fine with our serial version of the code. The serial version is the same except that the sub_groups are added directly to the group this code is in rather than being wrapped in parallel_group.
I have tried to look over the tutorials and examples but have not been able to figure what might be wrong. I would really appreciate any suggestions of what to check or what may be wrong. Sorry to not post a complete code sample.
its a little unclear, but it sounds like you've added a new group in the parallel version of the code, named "parallel_group". When you did this, did you promote anything (or everything) from that group? If so, then you shouldn't add the parallel group into the variable name path for the connection.
That seems like the only thing likely to trip you up. I could try to debug a bit more if you can come up with a sample code you can post up here that would show the problem.
I've been looking for this answer in the internet for a while and have found other people asking the same thing, even here. So this post will be a presentation of my case and a response to the "solutions" that I have found.
I am such new in Ruby, but for learning purposes I decided to create a gem, here.
I am trying to implement a keyboard navigation to this program, that will allow the user use short-cuts to select what kind of request he want to see. And in the future, arrow navigations, etc.
My problem: I can't find a consistent way to get the keyboard events from the user's console with Ruby.
Solutions that I have tried:
Highline gem: Seems do not support this feature anymore. Anyway it uses the STDIN, keep reading.
STDIN.getch: I need to run it in a parallel loop, because at the same time that the user can use a short-cut, more data can be created and the program needs to show it. And well, I display formated text in the console, (Rails log). When this loop is running, my text lost the all the format.
Curses: Cool but I need to set position(x,y) to display my text every time? It will get confusing.
Here is where I am trying to do it.
You may note that I am using "stty -raw echo" (turns raw off) before show my text and "stty raw -echo" (turns raw on) after. That keeps my text formated.
But my key listener loop is not working. I mean, It works in sometimes but is not consistent. If a press a key twice it don't work anymore and sometimes it stops alone too.
Let me put one part of the code here:
def run
# Two loops run in parallel using Threads.
# stream_log loops like a normal stream in the file, but it also parser the text.
# break it into requests and store in #requests_queue.
# stream_parsed_log stream inside the #requests_queue and shows it in the screen.
#requests_queue = Queue.new
#all_requests = Array.new
# It's not working yet.
Thread.new { listen_keyboard }
Thread.new { stream_log }
stream_parsed_log
end
def listen_keyboard
# not finished
loop do
char = STDIN.getch
case char
when 'q'
puts "Exiting."
exit
when 'a'
#types_to_show = ['GET', 'POST', 'PUT', 'DELETE', 'ASSET']
requests_to_show = filter_to_show(#all_requests)
command = true
when 'p'
#types_to_show = ['POST']
requests_to_show = filter_to_show(#all_requests)
command = true
end
clear_screen if command
#requests_queue += requests_to_show if command
command = false
end
end
I need a light in my path, what should I do?
That one was my mistake.
It's just a logic error in another part of code that was running in another thread so the ruby don't shows the error by default. I used ruby -d and realized what was wrong. This mistake was messing my keyboard input.
So now it's fixed and I am using STDIN.getch with no problem.
I just turn the raw mode off before show any string. And everything is ok.
You can check here, or in the gem itself.
That's it.
Is it possible to open every link in certain div and collect values of opened fields alltogether in one file or at least terminal output?
I am trying to get list of coordinates from all markers visible on google map.
all_links = b.div(:id, "kmlfolders").links
all_links.each do |link|
b.link.click
b.link(:text, "Norādījumi").click
puts b.text_field(:title, "Galapunkta_adrese").value
end
Are there easier or more effective ways how to automatically collect coordinates from all markers?
Unless there is other data (alt tags? elements invoked via onhover?) in the HTML already that you could pick through, that does seem like the most practical way to iterate through the links, however from what I can see you are not actually making use of the 'link' object inside your loop. You'd need something more like this I think
all_links = b.div(:id, "kmlfolders").links
all_links.each do |thelink|
b.link(:href => thelink.href).click
b.link(:text, "Norādījumi").click
puts b.text_field(:title, "Galapunkta_adrese").value
end
Probably using their API is a lot more effective means to get what you want however, it's why folks make API's after all, and if one is available, then using it is almost always best. Using a test tool as a screen-scraper to gather the info is liable to be a lot harder in the long run than learning how to make some api calls and get the data that way.
for web based api's and Ruby I find the REST-CLIENT gem works great, other folks like HTTP-Party
As I'm not already familiar with Google API, I find it hard for me to dig into API for one particular need. Therefor I made short watir-webdriver script for collecting coordinates of markers on protected google map. Resulting file is used in python script that creates speedcam files for navigation devices.
In this case it's speedcam map maintained and updated by Latvian police, but this script can probably be used with any google map just by replacing url.
# encoding: utf-8
require "rubygems"
require "watir-webdriver"
#b = Watir::Browser.new :ff
#--------------------------------
#b.goto "http://maps.google.com/maps?source=s_q&f=q&hl=lv&geocode=&q=htt%2F%2Fmaps.google.com%2Fmaps%2Fms%3Fmsid%3D207561992958290099079.0004b731f1c645294488e%26msa%3D0%26output%3Dkml&aq=&sll=56.799934,24.5753&sspn=3.85093,8.64624&ie=UTF8&ll=56.799934,24.5753&spn=3.610137,9.887695&z=7&vpsrc=0&oi=map_misc&ct=api_logo"
#b.div(:id, "kmlfolders").wait_until_present
all_markers = #b.div(:id, "kmlfolders").divs(:class, "fdrlt")
#prev_coordinates = 1
puts "#{all_markers.length} speedcam markers detected"
File.open("list_of_coordinates.txt","w") do |outfile|
all_markers.each do |marker|
sleep 1
marker.click
sleep 1
description = #b.div(:id => "iw_kml").text
#b.span(:class, "actbar-text").click
sleep 2
coordinates = #b.text_field(:name, "daddr").value
redo if coordinates == #prev_coordinates
puts coordinates
outfile.puts coordinates
#prev_coordinates = coordinates
end
end
puts "Coordinates saved in file!"
#b.close
Works both on Mac OSX 10.7 and Windows7.
I think this problem is best described in code. I'm sure the solution is close, I just haven't been able to find it. I've been looking over the Qt4 api as well as doing tutorials. Here is my code so far:
require 'Qt4'
class PictureCommentForm < Qt::Widget
def initialize(parent = nil)
super()
#setFixedSize(300, 100)
#comment_text = nil
picture = Qt::Label.new()
image = Qt::Image.new('image.jpeg')
picture.pixmap = image
comment = Qt::LineEdit.new()
layout = Qt::VBoxLayout.new()
layout.addWidget(picture)
layout.addWidget(comment)
setLayout(layout)
connect(comment, SIGNAL('returnPressed()'), self, setCommentText(comment.text) )
end
def setCommentText(text)
#comment_text = text
$qApp.quit()
end
end
app = Qt::Application.new(ARGV)
comment_form = PictureCommentForm.new()
comment_form.show()
app.exec
comment_text = comment_form.comment_text
puts "Comment was:\n #{comment_text}"
EDIT: Thanks for that answer integer. All I want done is a dialog box showing a picture and comment so I can get that data. I do plan on making a full GUI version with qt4, but that's for later.
I don't know Ruby, so bear with me, but I use Qt extensively in Python.
First point is that Qt really, really doesn't want to be used the way you're trying to use it. If you're making some sort of script, then Qt wants you to give it to Qt so it can run your code when it feels like:
We recommend that you connect clean-up
code to the aboutToQuit() signal,
instead of putting it in your
application's main() function because
on some platforms the
QCoreApplication::exec() call may not
return.
Working with Qt you pretty much have to do event-driven programming and give it control of your program flow / main loop.
If you really just want some "utility" that shows some GUI input box and prints whatever the user inputs to console, consider putting the puts directly in whatever function you connected to the text box. Then you can use that program's output in other console scripts.